[PR42249] Fix checking when dest and orig registers are same
Alexander Monakov
amonakov@ispras.ru
Wed Dec 30 16:34:00 GMT 2009
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
More information about the Gcc-patches
mailing list