]> gcc.gnu.org Git - gcc.git/commitdiff
re PR target/20322 (Miscompilation of libcpp/expr.c at -O2+)
authorJakub Jelinek <jakub@redhat.com>
Thu, 10 Mar 2005 21:26:12 +0000 (22:26 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 10 Mar 2005 21:26:12 +0000 (22:26 +0100)
PR target/20322
* combine.c (try_combine): If recog_for_combine added CLOBBERs
to NEWI2PAT, fail to combine if they are used by NEWPAT.

* gcc.dg/20050307-1.c: New test.

From-SVN: r96260

gcc/ChangeLog
gcc/combine.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/20050307-1.c [new file with mode: 0644]

index 03b1ef519aa0fcd24fbacb9fea8589a766764c15..ff1e60be2948665c92ced73bcff4b5ccf9527aaa 100644 (file)
@@ -1,3 +1,9 @@
+2005-03-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/20322
+       * combine.c (try_combine): If recog_for_combine added CLOBBERs
+       to NEWI2PAT, fail to combine if they are used by NEWPAT.
+
 2005-03-10  Aldy Hernandez  <aldyh@redhat.com>
 
         * doc/invoke.texi: Add 8540 to list of cpus in rs6000 cpu section.
index 0fc1f5f4283fb6e39748db0a2d6118d272b61e70..ae20c51caaf56eb2c9dec44cada6f13149accd69 100644 (file)
@@ -2417,6 +2417,20 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
          SUBST (*split, newdest);
          i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
 
+         /* recog_for_combine might have added CLOBBERs to newi2pat.
+            Make sure NEWPAT does not depend on the clobbered regs.  */
+         if (GET_CODE (newi2pat) == PARALLEL)
+           for (i = XVECLEN (newi2pat, 0) - 1; i >= 0; i--)
+             if (GET_CODE (XVECEXP (newi2pat, 0, i)) == CLOBBER)
+               {
+                 rtx reg = XEXP (XVECEXP (newi2pat, 0, i), 0);
+                 if (reg_overlap_mentioned_p (reg, newpat))
+                   {
+                     undo_all ();
+                     return 0;
+                   }
+               }
+
          /* If the split point was a MULT and we didn't have one before,
             don't use one now.  */
          if (i2_code_number >= 0 && ! (split_code == MULT && ! have_mult))
index 8454c08cc60db248b839db05f98219311f4ca26d..082f18a33e6d7b515fddd935acce43d64dc55d44 100644 (file)
@@ -1,3 +1,8 @@
+2005-03-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/20322
+       * gcc.dg/20050307-1.c: New test.
+
 2005-03-10  Nathan Sidwell  <nathan@codesourcery.com>
 
        PR c++/20375
diff --git a/gcc/testsuite/gcc.dg/20050307-1.c b/gcc/testsuite/gcc.dg/20050307-1.c
new file mode 100644 (file)
index 0000000..0e8dac6
--- /dev/null
@@ -0,0 +1,52 @@
+/* PR target/20322 */
+
+extern void abort (void);
+
+typedef unsigned long T;
+typedef struct
+{
+  T a, b;
+  unsigned char c, d;
+} S;
+
+#define M (sizeof (T) * 4)
+
+S __attribute__((noinline))
+foo (T x, T y)
+{
+  S e;
+  T f[2], g;
+
+  e.b = (x & (~(T) 0 >> M)) * (y & (~(T) 0 >> M));
+  e.a = (x >> M) * (y >> M);
+
+  f[0] = (x & (~(T) 0 >> M)) * (y >> M);
+  f[1] = (x >> M) * (y & (~(T) 0 >> M));
+
+  g = e.b;
+  e.b += (f[0] & (~(T) 0 >> M)) << M;
+  if (e.b < g)
+    e.a++;
+
+  g = e.b;
+  e.b += (f[1] & (~(T) 0 >> M)) << M;
+  if (e.b < g)
+    e.a++;
+
+  e.a += (f[0] >> M);
+  e.a += (f[1] >> M);
+  e.c = 1;
+  e.d = 0;
+
+  return e;
+}
+
+int
+main (void)
+{
+  T x = 1UL << (M * 2 - 1);
+  S y = foo (1, x);
+  if (y.a || y.b != x || y.c != 1 || y.d)
+    abort ();
+  return 0;
+}
This page took 0.133612 seconds and 5 git commands to generate.