From ca10595cf475579d19b0bf6fe5399cdf6f9b89f4 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Sun, 22 Jan 2012 14:35:39 +0000 Subject: [PATCH] re PR rtl-optimization/51924 (wrong code with -O -free -fno-rename-registers -ftree-vectorize -funroll-loops) PR rtl-optimization/51924 * ree.c (combine_set_extension): Improve debugging message. (combine_reaching_defs): Likewise. (get_defs): Rename confusingly named variable. (find_and_remove_re): Skip a candidate if the extension expression has been modified. From-SVN: r183390 --- gcc/ChangeLog | 9 +++++++ gcc/ree.c | 26 +++++++++++++-------- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.dg/ext-elim-1.c | 39 +++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/ext-elim-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 325d2fc88a3..71df98e6699 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2012-01-22 Eric Botcazou + + PR rtl-optimization/51924 + * ree.c (combine_set_extension): Improve debugging message. + (combine_reaching_defs): Likewise. + (get_defs): Rename confusingly named variable. + (find_and_remove_re): Skip a candidate if the extension expression has + been modified. + 2012-01-21 Robert Millan Gerald Pfeifer diff --git a/gcc/ree.c b/gcc/ree.c index 48113a966ba..4cab20ed50e 100644 --- a/gcc/ree.c +++ b/gcc/ree.c @@ -346,7 +346,8 @@ combine_set_extension (ext_cand *cand, rtx curr_insn, rtx *orig_set) { if (dump_file) { - fprintf (dump_file, "Merged instruction with extension:\n"); + fprintf (dump_file, + "Tentatively merged extension with definition:\n"); print_rtl_single (dump_file, curr_insn); } return true; @@ -407,21 +408,21 @@ transform_ifelse (ext_cand *cand, rtx def_insn) static struct df_link * get_defs (rtx insn, rtx reg, VEC (rtx,heap) **dest) { - df_ref reg_info, *defs; + df_ref reg_info, *uses; struct df_link *ref_chain, *ref_link; reg_info = NULL; - for (defs = DF_INSN_USES (insn); *defs; defs++) + for (uses = DF_INSN_USES (insn); *uses; uses++) { - reg_info = *defs; + reg_info = *uses; if (GET_CODE (DF_REF_REG (reg_info)) == SUBREG) return NULL; if (REGNO (DF_REF_REG (reg_info)) == REGNO (reg)) break; } - gcc_assert (reg_info != NULL && defs != NULL); + gcc_assert (reg_info != NULL && uses != NULL); ref_chain = DF_REF_CHAIN (reg_info); @@ -686,11 +687,10 @@ combine_reaching_defs (ext_cand *cand, rtx set_pat) purposes. This extension cannot be deleted. */ if (dump_file) { - FOR_EACH_VEC_ELT (rtx, vec, i, def_insn) - { - fprintf (dump_file, "Non-mergeable definitions:\n"); - print_rtl_single (dump_file, def_insn); - } + fprintf (dump_file, + "Merge cancelled, non-mergeable definitions:\n"); + FOR_EACH_VEC_ELT (rtx, vec, i, def_insn) + print_rtl_single (dump_file, def_insn); } } } @@ -843,6 +843,12 @@ find_and_remove_re (void) { num_re_opportunities++; + /* If the candidate insn is itself a definition insn for another + candidate, it may have been modified and the UD chain broken. + FIXME: the handling of successive extensions can be improved. */ + if (!reg_mentioned_p (curr_cand->expr, PATTERN (curr_cand->insn))) + continue; + /* Try to combine the extension with the definition. */ if (dump_file) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f0b4a793ef7..07b1fef7697 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2012-01-22 Eric Botcazou + + * gcc.dg/ext-elim-1.c: New test. + 2012-01-22 Richard Sandiford PR target/51931 diff --git a/gcc/testsuite/gcc.dg/ext-elim-1.c b/gcc/testsuite/gcc.dg/ext-elim-1.c new file mode 100644 index 00000000000..5e899a235f6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ext-elim-1.c @@ -0,0 +1,39 @@ +/* PR rtl-optimization/51924 */ +/* Testcase by Zdenek Sojka */ + +/* { dg-do run } */ +/* { dg-options "-O -free -fno-rename-registers -ftree-vectorize -funroll-loops" } */ + +typedef __UINT64_TYPE__ uint64_t; + +uint64_t __attribute__ ((noinline, noclone)) +bn_sub_words (uint64_t * r, const uint64_t * a, const uint64_t * b, int n) +{ + uint64_t t1, t2; + unsigned c = 0; + + while (n) + { + t1 = a[0]; + t2 = b[0]; + r[0] = (t1 - t2 - c); + if (t1 != t2) + c = (t1 < t2); + a++; + b++; + r++; + n--; + } + return (c); +} + +int +main (void) +{ + uint64_t r[2]; + uint64_t a[2] = { -1, -1 }; + uint64_t b[2] = { 0, 0 }; + if (bn_sub_words (r, a, b, 2) != 0) + __builtin_abort (); + return 0; +}