From 707f991907e5c97c56a05654fee49f4940158994 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 4 Jul 2011 20:53:56 +0200 Subject: [PATCH] re PR rtl-optimization/49472 (Compiler segfault on valid code) PR rtl-optimization/49472 * simplify-rtx.c (simplify_unary_operation_1) : When negating MULT, negate the second operand instead of first. (simplify_binary_operation_1) : 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 | 8 ++++++++ gcc/simplify-rtx.c | 28 ++++++++++++++++++++++++--- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/gfortran.dg/pr49472.f90 | 15 ++++++++++++++ 4 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr49472.f90 diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0823aa84fe0..509efb8cea0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2011-07-04 Jakub Jelinek + PR rtl-optimization/49472 + * simplify-rtx.c (simplify_unary_operation_1) : When + negating MULT, negate the second operand instead of first. + (simplify_binary_operation_1) : 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 3c4df973ff5..bcd55b27fbc 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 5a7d801c377..02c926afe94 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2011-07-04 Jakub Jelinek + 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 00000000000..1baf82e8b11 --- /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 -- 2.30.2