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  <ja...@redhat.com>

        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

Reply via email to