re PR rtl-optimization/49472 (Compiler segfault on valid code)
authorJakub Jelinek <jakub@redhat.com>
Mon, 4 Jul 2011 18:53:56 +0000 (20:53 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 4 Jul 2011 18:53:56 +0000 (20:53 +0200)
PR rtl-optimization/49472
* simplify-rtx.c (simplify_unary_operation_1) <case NEG>: When
negating MULT, negate the second operand instead of first.
(simplify_binary_operation_1) <case MULT>: If one operand is
a NEG and the other is MULT, don't attempt to optimize by
negation of the MULT operand if it only moves the NEG operation
around.

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

From-SVN: r175821

gcc/ChangeLog
gcc/simplify-rtx.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/pr49472.f90 [new file with mode: 0644]

index 0823aa84fe02219c4ec6ca25b9a73df28f6fa1cd..509efb8cea0ce04ed27005b74d0d7ca92f523c7a 100644 (file)
@@ -1,5 +1,13 @@
 2011-07-04  Jakub Jelinek  <jakub@redhat.com>
 
+       PR rtl-optimization/49472
+       * simplify-rtx.c (simplify_unary_operation_1) <case NEG>: When
+       negating MULT, negate the second operand instead of first.
+       (simplify_binary_operation_1) <case MULT>: If one operand is
+       a NEG and the other is MULT, don't attempt to optimize by
+       negation of the MULT operand if it only moves the NEG operation
+       around.
+
        PR debug/49602
        * tree-into-ssa.c (rewrite_debug_stmt_uses): Disregard
        get_current_def return value if it can't be trusted to be
index 3c4df973ff5053cabf578b82770da88038a10541..bcd55b27fbc4dd4c3088cdcaeaad44b668d366f1 100644 (file)
@@ -686,13 +686,13 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
          return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1));
        }
 
-      /* (neg (mult A B)) becomes (mult (neg A) B).
+      /* (neg (mult A B)) becomes (mult A (neg B)).
         This works even for floating-point values.  */
       if (GET_CODE (op) == MULT
          && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
        {
-         temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
-         return simplify_gen_binary (MULT, mode, temp, XEXP (op, 1));
+         temp = simplify_gen_unary (NEG, mode, XEXP (op, 1), mode);
+         return simplify_gen_binary (MULT, mode, XEXP (op, 0), temp);
        }
 
       /* NEG commutes with ASHIFT since it is multiplication.  Only do
@@ -2271,12 +2271,34 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
       if (GET_CODE (op0) == NEG)
        {
          rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
+         /* If op1 is a MULT as well and simplify_unary_operation
+            just moved the NEG to the second operand, simplify_gen_binary
+            below could through simplify_associative_operation move
+            the NEG around again and recurse endlessly.  */
+         if (temp
+             && GET_CODE (op1) == MULT
+             && GET_CODE (temp) == MULT
+             && XEXP (op1, 0) == XEXP (temp, 0)
+             && GET_CODE (XEXP (temp, 1)) == NEG
+             && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
+           temp = NULL_RTX;
          if (temp)
            return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
        }
       if (GET_CODE (op1) == NEG)
        {
          rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
+         /* If op0 is a MULT as well and simplify_unary_operation
+            just moved the NEG to the second operand, simplify_gen_binary
+            below could through simplify_associative_operation move
+            the NEG around again and recurse endlessly.  */
+         if (temp
+             && GET_CODE (op0) == MULT
+             && GET_CODE (temp) == MULT
+             && XEXP (op0, 0) == XEXP (temp, 0)
+             && GET_CODE (XEXP (temp, 1)) == NEG
+             && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
+           temp = NULL_RTX;
          if (temp)
            return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
        }
index 5a7d801c377e4564c354f5dd804d34f8ddf7ac86..02c926afe94e235fe2f95b0fb12847180a10b0fa 100644 (file)
@@ -1,5 +1,8 @@
 2011-07-04  Jakub Jelinek  <jakub@redhat.com>
 
+       PR rtl-optimization/49472
+       * gfortran.dg/pr49472.f90: New test.
+
        PR debug/49602
        * gcc.dg/pr49602.c: New test.
 
diff --git a/gcc/testsuite/gfortran.dg/pr49472.f90 b/gcc/testsuite/gfortran.dg/pr49472.f90
new file mode 100644 (file)
index 0000000..1baf82e
--- /dev/null
@@ -0,0 +1,15 @@
+! PR rtl-optimization/49472
+! { dg-do compile }
+! { dg-options "-O -fcompare-debug -ffast-math" }
+subroutine pr49472
+  integer, parameter :: n = 3
+  real(8) :: a, b, c, d, e (n+1)
+  integer :: i
+  do i=2, (n+1)
+    b = 1. / ((i - 1.5d0) * 1.)
+    c = b * a
+    d = -b * c / (1. + b * b) ** 1.5d0
+    e(i) = d
+  end do
+  call dummy (e)
+end subroutine