In straight-line strength reduction, a candidate expression of the form
"(type1)x + (type2)x", where type1 and type2 are compatible, results in
two interpretations of the candidate with different result types.
Because the types are compatible, the first interpretation can appear to
be a legal basis for the second, resulting in an invalid replacement.
The obvious solution is to keep a statement from serving as its own
basis.

Bootstrapped and tested on powerpc64-unknown-linux-gnu with no new
regressions, committed as obvious.

Thanks,
Bill
-- 
Bill Schmidt, Ph.D.
IBM Advance Toolchain for PowerLinux
IBM Linux Technology Center
wschm...@linux.vnet.ibm.com
wschm...@us.ibm.com



gcc:

2012-10-22  Bill Schmidt  <wschm...@linux.vnet.ibm.com>

        PR tree-optimization/55008
        * gimple-ssa-strength-reduction.c (find_basis_for_candidate): Don't
        allow a candidate to be a basis for itself under another interpretation.

gcc/testsuite:

2012-10-22  Bill Schmidt  <wschm...@linux.vnet.ibm.com>

        PR tree-optimization/55008
        * gcc.dg/tree-ssa/pr55008.c: New test.



Index: gcc/testsuite/gcc.dg/tree-ssa/pr55008.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/pr55008.c     (revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/pr55008.c     (revision 0)
@@ -0,0 +1,17 @@
+/* This used to fail to compile; see PR55008.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -w" } */
+
+typedef unsigned long long T;
+
+void f(void)
+{
+    int a, *p;
+
+    T b = 6309343725;
+
+    if(*p ? (b = 1) : 0)
+        if(b - (a = b /= 0) ? : (a + b))
+            while(1);
+}
+
Index: gcc/gimple-ssa-strength-reduction.c
===================================================================
--- gcc/gimple-ssa-strength-reduction.c (revision 192691)
+++ gcc/gimple-ssa-strength-reduction.c (working copy)
@@ -366,6 +366,7 @@ find_basis_for_candidate (slsr_cand_t c)
       slsr_cand_t one_basis = chain->cand;
 
       if (one_basis->kind != c->kind
+         || one_basis->cand_stmt == c->cand_stmt
          || !operand_equal_p (one_basis->stride, c->stride, 0)
          || !types_compatible_p (one_basis->cand_type, c->cand_type)
          || !dominated_by_p (CDI_DOMINATORS,


Reply via email to