Hi all, In this PR we may end up shifting a negative value left in simplify_comparison. The statement is: const_op <<= INTVAL (XEXP (op0, 1));
This patch guards the block of that statement by const_op >= 0. I _think_ that's a correct thing to do for that trasnformation: "If we have (compare (xshiftrt FOO N) (const_int C)) and the low order N bits of FOO are known to be zero, we can do this by comparing FOO with C shifted left N bits so long as no overflow occurs." The constant C here is const_op. Bootstrapped and tested on arm-none-linux-gnueabihf, aarch64-none-linux-gnu. Ok for trunk? Thanks, Kyrill 2016-05-13 Kyrylo Tkachov <kyrylo.tkac...@arm.com> PR middle-end/71074 * combine.c (simplify_comparison): Avoid left shift of negative const_op in LSHIFTRT case. 2016-05-13 Kyrylo Tkachov <kyrylo.tkac...@arm.com> PR middle-end/71074 * gcc.c-torture/compile/pr71074.c: New test.
diff --git a/gcc/combine.c b/gcc/combine.c index 2a7a9e6e2b597246392ede22552af1bdd7e1a794..7a21d593777ef267942e0ee80e024b147907652f 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -12321,6 +12321,7 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1) optimization and for > or <= by setting all the low order N bits in the comparison constant. */ if (CONST_INT_P (XEXP (op0, 1)) + && const_op >= 0 && INTVAL (XEXP (op0, 1)) > 0 && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT && mode_width <= HOST_BITS_PER_WIDE_INT diff --git a/gcc/testsuite/gcc.c-torture/compile/pr71074.c b/gcc/testsuite/gcc.c-torture/compile/pr71074.c new file mode 100644 index 0000000000000000000000000000000000000000..9ad6cbe7c231069c86d3ade22784f338f331b657 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr71074.c @@ -0,0 +1,13 @@ +int bar (void); + +void +foo (unsigned long long a, int b) +{ + int i; + + for (a = -12; a >= 10; a = bar ()) + break; + + if (i == bar () || bar () >= a) + bar (); +}