Hi!

This patch fixes a 4.8 ICE (on trunk the bug went latent by GIMPLE
optimization changes).  The problem is we have a REG_EQUAL
(unsigned_float:DF (reg:SI ...)) and cse_process_notes_1 attempts
to replace the reg with CONST_INT that has the top most bit set.
As CONST_INTs are canonicalized by sign extending it, simplify_unary*
ICEs on it because it doesn't know the original mode of the argument
and thus if the e.g. -1 in the CONST_INT is 0xff, 0xffff, 0xffffffff,
0xffffffffffffffffULL.  cse_process_notes_1 already punts similarly
on SIGN_EXTEND/ZERO_EXTEND/SUBREG, this just handles UNSIGNED_FLOAT
similarly, but allows unsigned values that aren't negative when
canonicalized, one doesn't need the mode in that case, if the CONST_INT
was valid for the original mode, then it shouldn't have any bits set
beyond it's precision.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/4.8?

2013-12-31  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/59647
        * cse.c (cse_process_notes_1): Don't substitute negative VOIDmode
        new_rtx into UNSIGNED_FLOAT rtxes.

        * g++.dg/opt/pr59647.C: New test.

--- gcc/cse.c.jj        2013-03-16 08:30:37.000000000 +0100
+++ gcc/cse.c   2013-12-31 15:31:16.469885722 +0100
@@ -6082,6 +6082,18 @@ cse_process_notes_1 (rtx x, rtx object,
        return x;
       }
 
+    case UNSIGNED_FLOAT:
+      {
+       rtx new_rtx = cse_process_notes (XEXP (x, 0), object, changed);
+       /* We don't substitute negative VOIDmode constants into these rtx,
+          since they would impede folding.  */
+       if (GET_MODE (new_rtx) != VOIDmode
+           || (CONST_INT_P (new_rtx) && INTVAL (new_rtx) >= 0)
+           || (CONST_DOUBLE_P (new_rtx) && CONST_DOUBLE_HIGH (new_rtx) >= 0))
+         validate_change (object, &XEXP (x, 0), new_rtx, 0);
+       return x;
+      }
+
     case REG:
       i = REG_QTY (REGNO (x));
 
--- gcc/testsuite/g++.dg/opt/pr59647.C.jj       2013-12-31 15:16:16.259454995 
+0100
+++ gcc/testsuite/g++.dg/opt/pr59647.C  2013-12-31 15:15:51.000000000 +0100
@@ -0,0 +1,32 @@
+// PR rtl-optimization/59647
+// { dg-do compile }
+// { dg-options "-O2 -fno-tree-vrp" }
+// { dg-additional-options "-msse2 -mfpmath=sse" { target { { i?86-*-* 
x86_64-*-* } && ia32 } } }
+
+void f1 (int);
+void f2 ();
+double f3 (int);
+
+struct A
+{
+  int f4 () const
+  {
+    if (a == 0)
+      return 1;
+    return 0;
+  }
+  unsigned f5 ()
+  {
+    if (!f4 ())
+      f2 ();
+    return a;
+  }
+  int a;
+};
+
+void
+f6 (A *x)
+{
+  unsigned b = x->f5 ();
+  f1 (b - 1 - f3 (x->f5 () - 1U));
+}

        Jakub

Reply via email to