aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/ree.c26
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/ext-elim-1.c39
4 files changed, 68 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 325d2fc..71df98e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2012-01-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ 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 <rmh@gnu.org>
Gerald Pfeifer <gerald@pfeifer.com>
diff --git a/gcc/ree.c b/gcc/ree.c
index 48113a9..4cab20e 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 f0b4a79..07b1fef 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2012-01-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.dg/ext-elim-1.c: New test.
+
2012-01-22 Richard Sandiford <rdsandiford@googlemail.com>
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 0000000..5e899a2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ext-elim-1.c
@@ -0,0 +1,39 @@
+/* PR rtl-optimization/51924 */
+/* Testcase by Zdenek Sojka <zsojka@seznam.cz> */
+
+/* { 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;
+}