From: Segher Boessenkool Date: Tue, 18 Aug 2015 14:27:50 +0000 (+0200) Subject: re PR rtl-optimization/67028 (combine bug. Different assumptions about subreg in... X-Git-Tag: releases/gcc-4.9.4~643 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=360200529e482f757da09bc645b3748460b60977;p=thirdparty%2Fgcc.git re PR rtl-optimization/67028 (combine bug. Different assumptions about subreg in different places.) PR rtl-optimization/67028 * combine.c (simplify_comparison): Fix comment. Rearrange code. Add test to see if a const_int fits in the new mode. gcc/testsuite/ PR rtl-optimization/67028 * gcc.dg/pr67028.c: New testcase. From-SVN: r226971 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5959f9dab298..4fc0435cb80d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2015-08-18 Segher Boessenkool + + Backport from mainline: + 2015-08-08 Segher Boessenkool + + PR rtl-optimization/67028 + * combine.c (simplify_comparison): Fix comment. Rearrange code. + Add test to see if a const_int fits in the new mode. + 2015-08-16 Uros Bizjak Backport from mainline: diff --git a/gcc/combine.c b/gcc/combine.c index adea2c161b62..a22aba7d48e4 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -11655,14 +11655,15 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1) continue; } - /* If this is (and:M1 (subreg:M2 X 0) (const_int C1)) where C1 + /* If this is (and:M1 (subreg:M1 X:M2 0) (const_int C1)) where C1 fits in both M1 and M2 and the SUBREG is either paradoxical or represents the low part, permute the SUBREG and the AND and try again. */ - if (GET_CODE (XEXP (op0, 0)) == SUBREG) + if (GET_CODE (XEXP (op0, 0)) == SUBREG + && CONST_INT_P (XEXP (op0, 1))) { - unsigned HOST_WIDE_INT c1; tmode = GET_MODE (SUBREG_REG (XEXP (op0, 0))); + unsigned HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1)); /* Require an integral mode, to avoid creating something like (AND:SF ...). */ if (SCALAR_INT_MODE_P (tmode) @@ -11672,18 +11673,22 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1) have a defined value due to the AND operation. However, if we commute the AND inside the SUBREG then they no longer have defined values and the meaning of - the code has been changed. */ + the code has been changed. + Also C1 should not change value in the smaller mode, + see PR67028 (a positive C1 can become negative in the + smaller mode, so that the AND does no longer mask the + upper bits). */ && (0 #ifdef WORD_REGISTER_OPERATIONS || (mode_width > GET_MODE_PRECISION (tmode) - && mode_width <= BITS_PER_WORD) + && mode_width <= BITS_PER_WORD + && trunc_int_for_mode (c1, tmode) == (HOST_WIDE_INT) c1) #endif || (mode_width <= GET_MODE_PRECISION (tmode) && subreg_lowpart_p (XEXP (op0, 0)))) - && CONST_INT_P (XEXP (op0, 1)) && mode_width <= HOST_BITS_PER_WIDE_INT && HWI_COMPUTABLE_MODE_P (tmode) - && ((c1 = INTVAL (XEXP (op0, 1))) & ~mask) == 0 + && (c1 & ~mask) == 0 && (c1 & ~GET_MODE_MASK (tmode)) == 0 && c1 != mask && c1 != GET_MODE_MASK (tmode)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d90d3d7ea99d..177791878437 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2015-08-18 Segher Boessenkool + + Backport from mainline: + 2015-08-08 Segher Boessenkool + + PR rtl-optimization/67028 + * gcc.dg/pr67028.c: New testcase. + 2015-08-16 Uros Bizjak Backport from mainline: diff --git a/gcc/testsuite/gcc.dg/pr67028.c b/gcc/testsuite/gcc.dg/pr67028.c new file mode 100644 index 000000000000..b42fb8110ebb --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr67028.c @@ -0,0 +1,21 @@ +/* { dg-do run } */ +/* { dg-options "-O3" } */ + +short c = 0; + +int __attribute__ ((noinline)) f(void) +{ + int d = 5; + signed char e = (c != 1) * -2; + int a = (unsigned short)e > d; + + return a; +} + +int main(void) +{ + if (!f()) + __builtin_abort(); + + return 0; +}