From 1aeec6dc1f26657cc32ed107b3de255566fcca41 Mon Sep 17 00:00:00 2001 From: Segher Boessenkool Date: Sat, 8 Aug 2015 03:51:27 +0200 Subject: [PATCH] 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: r226731 --- gcc/ChangeLog | 6 ++++++ gcc/combine.c | 19 ++++++++++++------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/pr67028.c | 21 +++++++++++++++++++++ 4 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr67028.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 00070d94dfa..c85c8e3adbe 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +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-07 DJ Delorie * config/rx/rx.c (rx_mode_dependent_address_p): Remove unneeded asserts. diff --git a/gcc/combine.c b/gcc/combine.c index 4a92f55c8a0..8f98cbb6bdf 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -12057,14 +12057,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) @@ -12074,16 +12075,20 @@ 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). */ && ((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) || (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 8aba7c0351d..38b6f9ee49b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-08-08 Segher Boessenkool + + PR rtl-optimization/67028 + * gcc.dg/pr67028.c: New testcase. + 2015-08-07 H.J. Lu PR rtl-optimization/67029 diff --git a/gcc/testsuite/gcc.dg/pr67028.c b/gcc/testsuite/gcc.dg/pr67028.c new file mode 100644 index 00000000000..b42fb8110eb --- /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; +} -- 2.30.2