re PR target/20196 (Miscompilation of mem_init in 32-bit ppc linux kernel)
authorJakub Jelinek <jakub@redhat.com>
Thu, 24 Feb 2005 21:23:14 +0000 (22:23 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 24 Feb 2005 21:23:14 +0000 (22:23 +0100)
PR target/20196
* config/rs6000/rs6000.md (LTU, GTU sCC splitters): Add earlyclobber,
allow splitting only if operands 0 and 3 don't overlap.

* gcc.c-torture/execute/20050224-1.c: New test.

From-SVN: r95513

gcc/ChangeLog
gcc/config/rs6000/rs6000.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20050224-1.c [new file with mode: 0644]

index 3e2bcb494740de00a7ac5d10ac36674e7a91653a..9ce1ada473bfaaac7ff82c2e62b71ac8e24bf385 100644 (file)
@@ -1,3 +1,9 @@
+2005-02-24  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/20196
+       * config/rs6000/rs6000.md (LTU, GTU sCC splitters): Add earlyclobber,
+       allow splitting only if operands 0 and 3 don't overlap.
+
 2005-02-24  Richard Henderson  <rth@redhat.com>
 
        PR middle-end/19953
index 3fdb165dd41ceacb7ff6dfd30662db58a82f8ec2..7fd210d9d1d5c3aabdbcbf87b4389254ea1b84ad 100644 (file)
   "")
 
 (define_insn_and_split ""
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
        (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
                         (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
                 (match_operand:SI 3 "reg_or_short_operand" "rI,rI")))]
   "TARGET_32BIT"
   "#"
-  "TARGET_32BIT"
+  "&& !reg_overlap_mentioned_p (operands[0], operands[3])"
   [(set (match_dup 0) (neg:SI (ltu:SI (match_dup 1) (match_dup 2))))
    (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 0)))]
   "")
 
 (define_insn_and_split ""
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
        (plus:DI (ltu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
                         (match_operand:DI 2 "reg_or_neg_short_operand" "r,P"))
                 (match_operand:DI 3 "reg_or_short_operand" "rI,rI")))]
   "TARGET_64BIT"
   "#"
-  "TARGET_64BIT"
+  "&& !reg_overlap_mentioned_p (operands[0], operands[3])"
   [(set (match_dup 0) (neg:DI (ltu:DI (match_dup 1) (match_dup 2))))
    (set (match_dup 0) (minus:DI (match_dup 3) (match_dup 0)))]
   "")
   "")
 
 (define_insn_and_split ""
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
         (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
                          (match_operand:SI 2 "reg_or_short_operand" "rI"))
                  (match_operand:SI 3 "reg_or_short_operand" "rI")))]
   "TARGET_32BIT"
   "#"
-  "TARGET_32BIT"
+  "&& !reg_overlap_mentioned_p (operands[0], operands[3])"
   [(set (match_dup 0) (neg:SI (gtu:SI (match_dup 1) (match_dup 2))))
    (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 0)))]
   "")
 
 (define_insn_and_split ""
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
         (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r")
                          (match_operand:DI 2 "reg_or_short_operand" "rI"))
                  (match_operand:DI 3 "reg_or_short_operand" "rI")))]
   "TARGET_64BIT"
   "#"
-  "TARGET_64BIT"
+  "&& !reg_overlap_mentioned_p (operands[0], operands[3])"
   [(set (match_dup 0) (neg:DI (gtu:DI (match_dup 1) (match_dup 2))))
    (set (match_dup 0) (minus:DI (match_dup 3) (match_dup 0)))]
   "")
index 1b1a9c43164debcad4a3d9772c9bd5ba254be964..192a460cdac452bff2f66cd7839f636e7f44ba41 100644 (file)
@@ -1,5 +1,8 @@
 2005-02-24  Jakub Jelinek  <jakub@redhat.com>
 
+       PR target/20196
+       * gcc.c-torture/execute/20050224-1.c: New test.
+
        PR c++/20175
        * g++.dg/warn/Wbraces2.C: New test.
 
diff --git a/gcc/testsuite/gcc.c-torture/execute/20050224-1.c b/gcc/testsuite/gcc.c-torture/execute/20050224-1.c
new file mode 100644 (file)
index 0000000..6812003
--- /dev/null
@@ -0,0 +1,33 @@
+/* Origin: Mikael Pettersson <mikpe@csd.uu.se> and the Linux kernel.  */
+
+extern void abort (void);
+unsigned long a = 0xc0000000, b = 0xd0000000;
+unsigned long c = 0xc01bb958, d = 0xc0264000;
+unsigned long e = 0xc0288000, f = 0xc02d4378;
+
+void
+foo (int x, int y, int z)
+{
+  if (x != 245 || y != 36 || z != 444)
+    abort ();
+}
+
+int
+main (void)
+{
+  unsigned long g;
+  int h = 0, i = 0, j = 0;
+
+  if (sizeof (unsigned long) < 4)
+    return 0;
+
+  for (g = a; g < b; g += 0x1000)
+    if (g < c)
+      h++;
+    else if (g >= d && g < e)
+      j++;
+    else if (g < f)
+      i++;
+  foo (i, j, h);
+  return 0;
+}