This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PR42249] Fix checking when dest and orig registers are same


This patch (also failing on 4.4 branch) is the repost of 
http://gcc.gnu.org/ml/gcc-patches/2008-09/msg01930.html, which was not 
applied at the time.  Quoting from that message: "The problem was that 
when the chosen destination register for an expression is the same as 
the existing register, we short-circuit the checks for validity of all 
insns that originated this expression with the chosen register.  
Obviously, not all of the original insns will have the same register 
as the expression -- some of them can have different registers, 
and the check should still be made."

OK for trunk?

2008-09-29 Andrey Belevantsev <abel@ispras.ru>

	PR rtl-optimization/42249
	* sel-sched.c (try_replace_dest_reg): When chosen register
	and original register is the same, do not bail out early, but
	still check all original insns for validity of replacing destination
	register.  Set EXPR_TARGET_AVAILABLE to 1 before leaving function
	in this case.

	* gcc.dg/pr42249.c: New.
---
 gcc/sel-sched.c                |   19 ++++++++-----------
 gcc/testsuite/gcc.dg/pr42249.c |   37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 11 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr42249.c

diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c
index e5ebc57..27c0f21 100644
--- a/gcc/sel-sched.c
+++ b/gcc/sel-sched.c
@@ -1642,14 +1642,6 @@ collect_unavailable_regs_from_bnds (expr_t expr, blist_t bnds, regset used_regs,
 static bool
 try_replace_dest_reg (ilist_t orig_insns, rtx best_reg, expr_t expr)
 {
-  if (expr_dest_regno (expr) == REGNO (best_reg))
-    {
-      EXPR_TARGET_AVAILABLE (expr) = 1;
-      return true;
-    }
-
-  gcc_assert (orig_insns);
-
   /* Try whether we'll be able to generate the insn
      'dest := best_reg' at the place of the original operation.  */
   for (; orig_insns; orig_insns = ILIST_NEXT (orig_insns))
@@ -1658,14 +1650,19 @@ try_replace_dest_reg (ilist_t orig_insns, rtx best_reg, expr_t expr)
 
       gcc_assert (EXPR_SEPARABLE_P (INSN_EXPR (orig_insn)));
 
-      if (!replace_src_with_reg_ok_p (orig_insn, best_reg)
-	  || !replace_dest_with_reg_ok_p (orig_insn, best_reg))
+      if (REGNO (best_reg) != REGNO (INSN_LHS (orig_insn))
+	  && (! replace_src_with_reg_ok_p (orig_insn, best_reg)
+	      || ! replace_dest_with_reg_ok_p (orig_insn, best_reg)))
 	return false;
     }
 
   /* Make sure that EXPR has the right destination
      register.  */
-  replace_dest_with_reg_in_expr (expr, best_reg);
+  if (expr_dest_regno (expr) != REGNO (best_reg))
+    replace_dest_with_reg_in_expr (expr, best_reg);
+  else
+    EXPR_TARGET_AVAILABLE (expr) = 1;
+
   return true;
 }
 
diff --git a/gcc/testsuite/gcc.dg/pr42249.c b/gcc/testsuite/gcc.dg/pr42249.c
new file mode 100644
index 0000000..2170874
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr42249.c
@@ -0,0 +1,37 @@
+/* { dg-do compile { target powerpc*-*-* ia64-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -fselective-scheduling -fsel-sched-pipelining" } */
+
+typedef struct TypHeader
+{
+  unsigned long size;
+  struct TypHeader **ptr;
+} *TypHandle;
+
+extern TypHandle NewBag (unsigned int type, unsigned long size);
+typedef unsigned long TypPoint32;
+
+TypHandle
+QuoPP (TypHandle hdL, TypHandle hdR)
+{
+  TypHandle hdC;
+  unsigned long degC;
+  TypPoint32 *ptC;
+  unsigned long degL;
+  TypPoint32 *ptL;
+  unsigned long degR;
+  TypPoint32 *ptR;
+  unsigned long p;
+
+  degL = ((hdL)->size) / sizeof (TypPoint32);
+  degR = ((hdR)->size) / sizeof (TypPoint32);
+  degC = degL < degR ? degR : degL;
+  hdC = NewBag (9, (unsigned long) (degC * sizeof (TypPoint32)));
+  ptC = (TypPoint32 *) ((TypHandle *) ((hdC)->ptr));
+
+  for (p = 0; p < degC; p++)
+    ptC[(((p) < (degR)) ? (ptR)[(p)] : (p))] =
+      ((((((p) < (degL)) ? (ptL)[(p)] : (p))) <
+        (degR)) ? (ptR)[((((p) < (degL)) ? (ptL)[(p)] : (p)))]
+       : ((((p) < (degL)) ? (ptL)[(p)] : (p))));
+}
+
-- 
1.6.4.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]