Patchwork [i386] : Fix PR target/44481, __builtin_parity() causes ICE in trunc_int_for_mode()

login
register
mail settings
Submitter Uros Bizjak
Date June 11, 2010, 9:53 p.m.
Message ID <1276293228.2505.19.camel@localhost>
Download mbox | patch
Permalink /patch/55373/
State New
Headers show

Comments

Uros Bizjak - June 11, 2010, 9:53 p.m.
Hello!

Apparently, middle end doesn't like parity RTX in CCmode.

Attached patch fixes this by introducing appropriate unspec.  The patch
also removes parityqi2_cmp pattern that was never generated.

2010-06-11  Uros Bizjak  <ubizjak@gmail.com>

	PR target/44481
	* config/i386/i386.md (UNSPEC_PARITY): New unspec.
	(paritydi2_cmp): Use UNSPEC_PARITY unspec insted of parity RTX.
	(partiysi2_cmp): Ditto.
	(*partiyhi2_cmp): Ditto.
	(*parityqi2_cmp): Remove.

testsuite/ChangeLog:

2010-06-11  Uros Bizjak  <ubizjak@gmail.com>

	PR target/44481
	* gcc.target/i386/pr44481.c: New test.

Patch was bootstrapped and regression tested on x86_64-pc-linux-gnu
{,-m32} and was committed to mainline SVN. It will be backported to all
release branches.

Uros.

Patch

Index: testsuite/gcc.target/i386/pr44481.c
===================================================================
--- testsuite/gcc.target/i386/pr44481.c	(revision 0)
+++ testsuite/gcc.target/i386/pr44481.c	(revision 0)
@@ -0,0 +1,14 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+static inline unsigned
+parity (unsigned x)
+{
+  return (unsigned) __builtin_parity (x);
+}
+
+unsigned
+f (unsigned rpoly)
+{
+  return parity (rpoly & 1) ^ parity (rpoly & 6);
+}
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 160627)
+++ config/i386/i386.md	(working copy)
@@ -97,6 +97,7 @@ 
   UNSPEC_SCAS
   UNSPEC_FNSTSW
   UNSPEC_SAHF
+  UNSPEC_PARITY
   UNSPEC_FSTCW
   UNSPEC_ADD_CARRY
   UNSPEC_FLDCW
@@ -12186,7 +12187,8 @@ 
 
 (define_insn_and_split "paritydi2_cmp"
   [(set (reg:CC FLAGS_REG)
-	(parity:CC (match_operand:DI 3 "register_operand" "0")))
+	(unspec:CC [(match_operand:DI 3 "register_operand" "0")]
+		   UNSPEC_PARITY))
    (clobber (match_scratch:DI 0 "=r"))
    (clobber (match_scratch:SI 1 "=&r"))
    (clobber (match_scratch:HI 2 "=Q"))]
@@ -12199,7 +12201,7 @@ 
       (clobber (reg:CC FLAGS_REG))])
    (parallel
      [(set (reg:CC FLAGS_REG)
-	   (parity:CC (match_dup 1)))
+	   (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
       (clobber (match_dup 1))
       (clobber (match_dup 2))])]
 {
@@ -12216,7 +12218,8 @@ 
 
 (define_insn_and_split "paritysi2_cmp"
   [(set (reg:CC FLAGS_REG)
-	(parity:CC (match_operand:SI 2 "register_operand" "0")))
+	(unspec:CC [(match_operand:SI 2 "register_operand" "0")]
+		   UNSPEC_PARITY))
    (clobber (match_scratch:SI 0 "=r"))
    (clobber (match_scratch:HI 1 "=&Q"))]
   "! TARGET_POPCNT"
@@ -12228,7 +12231,7 @@ 
       (clobber (reg:CC FLAGS_REG))])
    (parallel
      [(set (reg:CC FLAGS_REG)
-	   (parity:CC (match_dup 1)))
+	   (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
       (clobber (match_dup 1))])]
 {
   operands[3] = gen_lowpart (HImode, operands[2]);
@@ -12239,20 +12242,13 @@ 
 
 (define_insn "*parityhi2_cmp"
   [(set (reg:CC FLAGS_REG)
-	(parity:CC (match_operand:HI 1 "register_operand" "0")))
+	(unspec:CC [(match_operand:HI 1 "register_operand" "0")]
+		   UNSPEC_PARITY))
    (clobber (match_scratch:HI 0 "=Q"))]
   "! TARGET_POPCNT"
   "xor{b}\t{%h0, %b0|%b0, %h0}"
   [(set_attr "length" "2")
    (set_attr "mode" "HI")])
-
-(define_insn "*parityqi2_cmp"
-  [(set (reg:CC FLAGS_REG)
-	(parity:CC (match_operand:QI 0 "register_operand" "q")))]
-  "! TARGET_POPCNT"
-  "test{b}\t%0, %0"
-  [(set_attr "length" "2")
-   (set_attr "mode" "QI")])
 
 ;; Thread-local storage patterns for ELF.
 ;;