Hi!

SCEV can analyze not just integral/pointer IVs, but (scalar) float ones as
well.  Calling build_int_cst on such types results in ICE, build_zero_cst
works.  Though the loop invariant PHI IVs, if we represent them as using
+0.0 step, aren't correct if honoring signed zeros, as + 0.0 will make
a +0.0 out of -0.0.

Bootstrapped/regtested on {x86_64,i686,powerpc64{,le}}-linux, ok for trunk?

2019-01-22  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/88964
        * gimple-loop-interchange.cc (loop_cand::analyze_induction_var): Use
        build_zero_cst instead of build_int_cst.  Return false for loop
        invariants which honor signed zeros.

        * gfortran.dg/pr88964.f90: New test.

--- gcc/gimple-loop-interchange.cc.jj   2019-01-01 12:37:17.416970701 +0100
+++ gcc/gimple-loop-interchange.cc      2019-01-22 11:34:42.303796570 +0100
@@ -688,11 +688,16 @@ loop_cand::analyze_induction_var (tree v
   /* Var is loop invariant, though it's unlikely to happen.  */
   if (tree_does_not_contain_chrecs (chrec))
     {
+      /* Punt on floating point invariants if honoring signed zeros,
+        representing that as + 0.0 would change the result if init
+        is -0.0.  */
+      if (HONOR_SIGNED_ZEROS (chrec))
+       return false;
       struct induction *iv = XCNEW (struct induction);
       iv->var = var;
       iv->init_val = init;
       iv->init_expr = chrec;
-      iv->step = build_int_cst (TREE_TYPE (chrec), 0);
+      iv->step = build_zero_cst (TREE_TYPE (chrec));
       m_inductions.safe_push (iv);
       return true;
     }
--- gcc/testsuite/gfortran.dg/pr88964.f90.jj    2019-01-22 11:54:46.046154065 
+0100
+++ gcc/testsuite/gfortran.dg/pr88964.f90       2019-01-22 11:54:23.172526590 
+0100
@@ -0,0 +1,57 @@
+! PR tree-optimization/88964
+! { dg-do compile }
+! { dg-options "-O3 -fno-tree-forwprop --param 
sccvn-max-alias-queries-per-access=1" }
+
+MODULE pr88964
+  INTEGER, PARAMETER :: dp=8
+  REAL(KIND=dp) :: p, q, o
+CONTAINS
+  SUBROUTINE foo(a,b,c,f,h)
+    IMPLICIT NONE
+    INTEGER :: a, b, c
+    REAL(KIND=dp) :: f(b*c), h(a*c)
+    CALL bar(h)
+    CALL baz(f)
+    CALL qux(h)
+  END SUBROUTINE foo
+  SUBROUTINE bar(h)
+    IMPLICIT NONE
+    REAL(KIND=dp) :: h(1*1)
+    INTEGER :: r, s, t, u
+    DO u = 1,3
+      DO t = 1,1
+        DO s = 1,3
+          DO r = 1,1
+            h((t-1)*1+r) = h((t-1)*1+r)-p*o
+          END DO
+        END DO
+      END DO
+    END DO
+  END SUBROUTINE bar
+  SUBROUTINE baz(f)
+    IMPLICIT NONE
+    REAL(KIND=dp) :: f(3*1)
+    INTEGER :: s, t, u
+    DO u = 1,4
+      DO t = 1,1
+        DO s = 1,3
+          f((t-1)*3+s) = f((t-1)*3+s) - q
+        END DO
+      END DO
+    END DO
+  END SUBROUTINE baz
+  SUBROUTINE qux(h)
+    IMPLICIT NONE
+    REAL(KIND=dp) :: h(1*1)
+    INTEGER :: r, s, t, u
+    DO u = 1,5
+      DO t = 1,1
+        DO s = 1,3
+          DO r = 1,1
+            h((t-1)*1+r) = h((t-1)*1+r)-p*o
+          END DO
+        END DO
+      END DO
+    END DO
+  END SUBROUTINE qux
+END MODULE pr88964

        Jakub

Reply via email to