re PR target/35540 (Segmentation fault with __builtin_parity() and -O1)
authorUros Bizjak <uros@gcc.gnu.org>
Tue, 11 Mar 2008 19:18:48 +0000 (20:18 +0100)
committerUros Bizjak <uros@gcc.gnu.org>
Tue, 11 Mar 2008 19:18:48 +0000 (20:18 +0100)
        PR target/35540
        * config/i386/i386.md (paritysi2, paritydi2): Use register_operand
        constraint for operand 1.
        (paritysi2_cmp): Use register_operand constraint for operand 2.
        Use earlyclobber modifier for operand 1.  Remove support for
        memory operands.
        (paritydi2_cmp): Use register_operand constraint for operand 3.
        Use earlyclobber modifier for operand 1.  Remove support for
        memory operands.

testsuite/ChangeLog:

        PR target/35540
        * gcc.target/i386/pr35540.c: New test.

From-SVN: r133118

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr35540.c [new file with mode: 0644]

index c3fb00aabe64e5809b90500fab81e23a2af3c199..ccd9abee4ce8bc0fd6de08618337c92895d20742 100644 (file)
@@ -1,5 +1,17 @@
+2008-03-11  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/35540
+       * config/i386/i386.md (paritysi2, paritydi2): Use register_operand
+       constraint for operand 1.
+       (paritysi2_cmp): Use register_operand constraint for operand 2.
+       Use earlyclobber modifier for operand 1.  Remove support for
+       memory operands.
+       (paritydi2_cmp): Use register_operand constraint for operand 3.
+       Use earlyclobber modifier for operand 1.  Remove support for
+       memory operands.
+
 2008-03-11  Paul Brook  <paul@codesourcery.com>
-       Vladimir Prus  <vladimir@codesourcery.com>
+           Vladimir Prus  <vladimir@codesourcery.com>
 
        * config/arm/arm.c (use_return_insn): Check TARGET_APCS_FRAME.
        (arm_compute_save_reg0_reg12_mask): Always
index eb942d60d9cc97a82de9eaecf7be2aa44955fe03..17e974d544a6f242ab616012bf2df1caed2c1f7d 100644 (file)
 
 (define_expand "paritydi2"
   [(set (match_operand:DI 0 "register_operand" "")
-       (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
+       (parity:DI (match_operand:DI 1 "register_operand" "")))]
   "! TARGET_POPCNT"
 {
   rtx scratch = gen_reg_rtx (QImode);
 
 (define_insn_and_split "paritydi2_cmp"
   [(set (reg:CC FLAGS_REG)
-       (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
-   (clobber (match_scratch:DI 0 "=r,X"))
-   (clobber (match_scratch:SI 1 "=r,r"))
-   (clobber (match_scratch:HI 2 "=Q,Q"))]
+       (parity:CC (match_operand:DI 3 "register_operand" "0")))
+   (clobber (match_scratch:DI 0 "=r"))
+   (clobber (match_scratch:SI 1 "=&r"))
+   (clobber (match_scratch:HI 2 "=Q"))]
   "! TARGET_POPCNT"
   "#"
   "&& reload_completed"
 {
   operands[4] = gen_lowpart (SImode, operands[3]);
 
-  if (MEM_P (operands[3]))
-    emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
-  else if (! TARGET_64BIT)
-    operands[1] = gen_highpart (SImode, operands[3]);
-  else
+  if (TARGET_64BIT)
     {
       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
     }
+  else
+    operands[1] = gen_highpart (SImode, operands[3]);
 })
 
 (define_expand "paritysi2"
   [(set (match_operand:SI 0 "register_operand" "")
-       (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
+       (parity:SI (match_operand:SI 1 "register_operand" "")))]
   "! TARGET_POPCNT"
 {
   rtx scratch = gen_reg_rtx (QImode);
 
 (define_insn_and_split "paritysi2_cmp"
   [(set (reg:CC FLAGS_REG)
-       (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
-   (clobber (match_scratch:SI 0 "=r,X"))
-   (clobber (match_scratch:HI 1 "=Q,Q"))]
+       (parity:CC (match_operand:SI 2 "register_operand" "0")))
+   (clobber (match_scratch:SI 0 "=r"))
+   (clobber (match_scratch:HI 1 "=&Q"))]
   "! TARGET_POPCNT"
   "#"
   "&& reload_completed"
 {
   operands[3] = gen_lowpart (HImode, operands[2]);
 
-  if (MEM_P (operands[2]))
-    emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
-  else
-    {
-      emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
-      emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
-    }
+  emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
+  emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
 })
 
 (define_insn "*parityhi2_cmp"
index f6bf6834c3f83a4f8ff5b26d6ee7d0f254ec0643..1fd06c444a9932fe6daced973533b74034784c6d 100644 (file)
@@ -1,3 +1,8 @@
+2008-03-11  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/35540
+       * gcc.target/i386/pr35540.c: New test.
+
 2008-03-11  Uros Bizjak  <ubizjak@gmail.com>
 
        * g++.dg/inherit/override-attribs.C: Require ilp32 x86 target.
diff --git a/gcc/testsuite/gcc.target/i386/pr35540.c b/gcc/testsuite/gcc.target/i386/pr35540.c
new file mode 100644 (file)
index 0000000..00af637
--- /dev/null
@@ -0,0 +1,45 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+extern void abort (void);
+
+int __attribute__ ((noinline))
+test (unsigned int *a, int b)
+{
+  return b ? 1 : __builtin_parity (*a);
+}
+
+int __attribute__ ((noinline))
+testl (unsigned long *a, int b)
+{
+  return b ? 1 : __builtin_parityl (*a);
+}
+
+int __attribute__ ((noinline))
+testll (unsigned long long *a, int b)
+{
+  return b ? 1 : __builtin_parityll (*a);
+}
+
+int
+main ()
+{
+  unsigned int a = 0;
+  unsigned long al;
+  unsigned long long all;
+
+  a = 0x12345670;
+  if (test (&a, 0))
+    abort ();
+
+  al = 0x12345670ul;
+  if (testl (&al, 0))
+    abort();
+
+#if 1
+  all = 0x12345678abcdef0ull;
+  if (testll (&all, 0))
+    abort ();
+#endif
+  return 0;
+}