On Wed, Nov 09, 2011 at 04:44:55PM +0100, Bernd Schmidt wrote:
> On 11/09/11 16:32, Jakub Jelinek wrote:
> > --- gcc/combine.c.jj 2011-11-08 23:35:12.000000000 +0100
> > +++ gcc/combine.c 2011-11-09 10:06:27.207333364 +0100
> > @@ -11397,9 +11397,12 @@ simplify_comparison (enum rtx_code code,
> > later on, and then we wouldn't know whether to sign- or
> > zero-extend. */
> > mode = GET_MODE (XEXP (op0, 0));
> > - if (mode != VOIDmode && GET_MODE_CLASS (mode) == MODE_INT
> > + if (GET_MODE_CLASS (mode) == MODE_INT
> > && ! unsigned_comparison_p
> > - && val_signbit_known_clear_p (mode, const_op)
> > + && HWI_COMPUTABLE_MODE_P (mode)
> > + && ((unsigned HOST_WIDE_INT) const_op
> > + < (((unsigned HOST_WIDE_INT) 1
> > + << (GET_MODE_PRECISION (mode) - 1))))
> > && have_insn_for (COMPARE, mode))
> > {
> > op0 = XEXP (op0, 0);
>
> I guess this is OK, although it would still be nicer to use something
> with a descriptive name rather than bit-fiddling, to avoid this kind of
> confusion. Maybe check whether trunc_int_for_mode doesn't change the
> constant? Or we could make val_signbit_known_clear_p do more extensive
> checking.
Do you think this is more readable?
That matches what the old code did, though I wonder if the c >= 0
test is needed there at all and if simply
&& trunc_int_for_mode (const_op, mode) == const_op
couldn't be used and handle also negative constants - the comparison
is signed and the other operand is sign extended...
2011-11-09 Jakub Jelinek <[email protected]>
PR rtl-optimization/51023
* combine.c (simplify_comparison) <case SIGN_EXTEND>: Don't use
val_signbit_known_clear_p for signed comparison narrowing
optimization. Don't check for non-VOIDmode, use
HWI_COMPUTABLE_MODE_P macro.
<case ZERO_EXTEND>: Don't check for non-VOIDmode.
* gcc.c-torture/execute/pr51023.c: New test.
--- gcc/combine.c.jj 2011-11-08 23:35:12.000000000 +0100
+++ gcc/combine.c 2011-11-09 10:06:27.207333364 +0100
@@ -11397,13 +11397,20 @@ simplify_comparison (enum rtx_code code,
later on, and then we wouldn't know whether to sign- or
zero-extend. */
mode = GET_MODE (XEXP (op0, 0));
- if (mode != VOIDmode && GET_MODE_CLASS (mode) == MODE_INT
+ if (GET_MODE_CLASS (mode) == MODE_INT
&& ! unsigned_comparison_p
- && val_signbit_known_clear_p (mode, const_op)
- && have_insn_for (COMPARE, mode))
+ && HWI_COMPUTABLE_MODE_P (mode))
{
- op0 = XEXP (op0, 0);
- continue;
+ HOST_WIDE_INT c = trunc_int_for_mode (const_op, mode);
+ /* Don't do this if the sign bit of MODE or any
+ higher bit is set in CONST_OP. */
+ if (c == const_op
+ && c >= 0
+ && have_insn_for (COMPARE, mode))
+ {
+ op0 = XEXP (op0, 0);
+ continue;
+ }
}
break;
@@ -11477,7 +11484,7 @@ simplify_comparison (enum rtx_code code,
case ZERO_EXTEND:
mode = GET_MODE (XEXP (op0, 0));
- if (mode != VOIDmode && GET_MODE_CLASS (mode) == MODE_INT
+ if (GET_MODE_CLASS (mode) == MODE_INT
&& (unsigned_comparison_p || equality_comparison_p)
&& HWI_COMPUTABLE_MODE_P (mode)
&& ((unsigned HOST_WIDE_INT) const_op < GET_MODE_MASK (mode))
--- gcc/testsuite/gcc.c-torture/execute/pr51023.c.jj 2011-11-09
10:17:31.133406427 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr51023.c 2011-11-09
10:17:13.000000000 +0100
@@ -0,0 +1,18 @@
+/* PR rtl-optimization/51023 */
+
+extern void abort (void);
+
+short int
+foo (long int x)
+{
+ return x;
+}
+
+int
+main ()
+{
+ long int a = 0x4272AL;
+ if (foo (a) == a)
+ abort ();
+ return 0;
+}
Jakub