aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-07-04 20:53:56 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2011-07-04 20:53:56 +0200
commit707f991907e5c97c56a05654fee49f4940158994 (patch)
treeb9c8211932e2c4b13367e217f110ffc882b8f5cf /gcc
parent15923c25df505b21061fda148dcb2b036af4735a (diff)
downloadgcc-707f991907e5c97c56a05654fee49f4940158994.zip
gcc-707f991907e5c97c56a05654fee49f4940158994.tar.gz
gcc-707f991907e5c97c56a05654fee49f4940158994.tar.bz2
re PR rtl-optimization/49472 (Compiler segfault on valid code)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/simplify-rtx.c28
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gfortran.dg/pr49472.f9015
4 files changed, 51 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0823aa8..509efb8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 3c4df97..bcd55b27 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -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));
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5a7d801..02c926a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..1baf82e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr49472.f90
@@ -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