OSDN Git Service

PR rtl-optimization/49472
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 4 Jul 2011 21:09:26 +0000 (21:09 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 4 Jul 2011 21:09:26 +0000 (21:09 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@175828 138bc75d-0d04-0410-961f-82ee72b054a4

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

index a3268e9..592ee9c 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.
+
        Backported from mainline
        2011-06-06  Jakub Jelinek  <jakub@redhat.com>
 
index ed6ae2b..eb747ad 100644 (file)
@@ -1,7 +1,7 @@
 /* RTL simplification functions for GNU compiler.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+   2011  Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -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
@@ -2175,12 +2175,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 4fcb69d..f0f983d 100644 (file)
@@ -1,5 +1,8 @@
 2011-07-04  Jakub Jelinek  <jakub@redhat.com>
 
+       PR rtl-optimization/49472
+       * gfortran.dg/pr49472.f90: New test.
+
        Backported from mainline
        2011-06-30  Jakub Jelinek  <jakub@redhat.com>
 
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