diff mbox

Fix rs6000 vector select RTL patterns (PR target/49621)

Message ID 20110708124010.GW2687@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek July 8, 2011, 12:40 p.m. UTC
Hi!

As mentioned in the PR, IMNSHO the rs6000 vector_select_* patterns
are invalid RTL, they compare a vector register in some vector mode
to const0_rtx instead of corresponding vector zero constant.

The "Comparison Operations" section of RTL docs says:
"The mode of the comparison is determined by the operands; they
must both be valid for a common machine mode."

Having one vector mode and one VOIDmode confuses simplify-rtx.c enough
to create simplifications which lead to ICEs.

The following patch fixes that by using CONST0_RTX (mode) instead
in the patterns.

Bootstrapped/regtested on powerpc64-linux --with-cpu=default32 and
powerpc64-linux, ok for trunk/4.6?

2011-07-08  Jakub Jelinek  <jakub@redhat.com>

	PR target/49621
	* config/rs6000/rs6000.c (rs6000_emit_vector_cond_expr): Use
	CONST0_RTX (dest_mode) instead of const0_rtx as second operand
	of NE.
	* config/rs6000/vector.md (vector_select_<mode>,
	vector_select_<mode>_uns): Change second operand of NE to
	CONST0_RTX (<MODE>mode) instead of const0_rtx.
	* config/rs6000/altivec.md (*altivec_vsel<mode>,
	*altivec_vsel<mode>_uns): Expect second operand of NE to be
	zero_constant of the corresponding vector mode.
	* config/rs6000/vsx.md (*vsx_xxsel<mode>, *vsx_xxsel<mode>_uns):
	Likewise.

	* gcc.target/powerpc/altivec-34.c: New test.


	Jakub

Comments

David Edelsohn July 8, 2011, 2:47 p.m. UTC | #1
On Fri, Jul 8, 2011 at 8:40 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> As mentioned in the PR, IMNSHO the rs6000 vector_select_* patterns
> are invalid RTL, they compare a vector register in some vector mode
> to const0_rtx instead of corresponding vector zero constant.
>
> The "Comparison Operations" section of RTL docs says:
> "The mode of the comparison is determined by the operands; they
> must both be valid for a common machine mode."
>
> Having one vector mode and one VOIDmode confuses simplify-rtx.c enough
> to create simplifications which lead to ICEs.
>
> The following patch fixes that by using CONST0_RTX (mode) instead
> in the patterns.
>
> Bootstrapped/regtested on powerpc64-linux --with-cpu=default32 and
> powerpc64-linux, ok for trunk/4.6?
>
> 2011-07-08  Jakub Jelinek  <jakub@redhat.com>
>
>        PR target/49621
>        * config/rs6000/rs6000.c (rs6000_emit_vector_cond_expr): Use
>        CONST0_RTX (dest_mode) instead of const0_rtx as second operand
>        of NE.
>        * config/rs6000/vector.md (vector_select_<mode>,
>        vector_select_<mode>_uns): Change second operand of NE to
>        CONST0_RTX (<MODE>mode) instead of const0_rtx.
>        * config/rs6000/altivec.md (*altivec_vsel<mode>,
>        *altivec_vsel<mode>_uns): Expect second operand of NE to be
>        zero_constant of the corresponding vector mode.
>        * config/rs6000/vsx.md (*vsx_xxsel<mode>, *vsx_xxsel<mode>_uns):
>        Likewise.
>
>        * gcc.target/powerpc/altivec-34.c: New test.

Okay.

I remember Geoff fixing something similar for FP a while ago.  Sorry I
missed this when this series of patches was merged.

Thanks, David
diff mbox

Patch

--- gcc/config/rs6000/rs6000.c.jj	2011-07-07 13:25:49.000000000 +0200
+++ gcc/config/rs6000/rs6000.c	2011-07-08 09:28:30.000000000 +0200
@@ -16888,7 +16888,7 @@  rs6000_emit_vector_cond_expr (rtx dest, 
       op_false = tmp;
     }
 
-  cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
+  cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, CONST0_RTX (dest_mode));
   emit_insn (gen_rtx_SET (VOIDmode,
 			  dest,
 			  gen_rtx_IF_THEN_ELSE (dest_mode,
--- gcc/config/rs6000/vector.md.jj	2011-05-02 18:39:25.000000000 +0200
+++ gcc/config/rs6000/vector.md	2011-07-07 13:50:37.000000000 +0200
@@ -465,21 +465,21 @@  (define_expand "vector_select_<mode>"
   [(set (match_operand:VEC_L 0 "vlogical_operand" "")
 	(if_then_else:VEC_L
 	 (ne:CC (match_operand:VEC_L 3 "vlogical_operand" "")
-		(const_int 0))
+		(match_dup 4))
 	 (match_operand:VEC_L 2 "vlogical_operand" "")
 	 (match_operand:VEC_L 1 "vlogical_operand" "")))]
   "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
-  "")
+  "operands[4] = CONST0_RTX (<MODE>mode);")
 
 (define_expand "vector_select_<mode>_uns"
   [(set (match_operand:VEC_L 0 "vlogical_operand" "")
 	(if_then_else:VEC_L
 	 (ne:CCUNS (match_operand:VEC_L 3 "vlogical_operand" "")
-		   (const_int 0))
+		   (match_dup 4))
 	 (match_operand:VEC_L 2 "vlogical_operand" "")
 	 (match_operand:VEC_L 1 "vlogical_operand" "")))]
   "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
-  "")
+  "operands[4] = CONST0_RTX (<MODE>mode);")
 
 ;; Expansions that compare vectors producing a vector result and a predicate,
 ;; setting CR6 to indicate a combined status
--- gcc/config/rs6000/altivec.md.jj	2011-04-01 23:09:21.000000000 +0200
+++ gcc/config/rs6000/altivec.md	2011-07-07 13:50:37.000000000 +0200
@@ -487,7 +487,7 @@  (define_insn "*altivec_vsel<mode>"
   [(set (match_operand:VM 0 "altivec_register_operand" "=v")
 	(if_then_else:VM
 	 (ne:CC (match_operand:VM 1 "altivec_register_operand" "v")
-		(const_int 0))
+		(match_operand:VM 4 "zero_constant" ""))
 	 (match_operand:VM 2 "altivec_register_operand" "v")
 	 (match_operand:VM 3 "altivec_register_operand" "v")))]
   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
@@ -498,7 +498,7 @@  (define_insn "*altivec_vsel<mode>_uns"
   [(set (match_operand:VM 0 "altivec_register_operand" "=v")
 	(if_then_else:VM
 	 (ne:CCUNS (match_operand:VM 1 "altivec_register_operand" "v")
-		   (const_int 0))
+		   (match_operand:VM 4 "zero_constant" ""))
 	 (match_operand:VM 2 "altivec_register_operand" "v")
 	 (match_operand:VM 3 "altivec_register_operand" "v")))]
   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
--- gcc/config/rs6000/vsx.md.jj	2011-05-02 18:39:25.000000000 +0200
+++ gcc/config/rs6000/vsx.md	2011-07-07 13:50:37.000000000 +0200
@@ -674,7 +674,7 @@  (define_insn "*vsx_xxsel<mode>"
   [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa")
 	(if_then_else:VSX_L
 	 (ne:CC (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,wa")
-		(const_int 0))
+		(match_operand:VSX_L 4 "zero_constant" ""))
 	 (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,wa")
 	 (match_operand:VSX_L 3 "vsx_register_operand" "<VSr>,wa")))]
   "VECTOR_MEM_VSX_P (<MODE>mode)"
@@ -685,7 +685,7 @@  (define_insn "*vsx_xxsel<mode>_uns"
   [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa")
 	(if_then_else:VSX_L
 	 (ne:CCUNS (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,wa")
-		   (const_int 0))
+		   (match_operand:VSX_L 4 "zero_constant" ""))
 	 (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,wa")
 	 (match_operand:VSX_L 3 "vsx_register_operand" "<VSr>,wa")))]
   "VECTOR_MEM_VSX_P (<MODE>mode)"
--- gcc/testsuite/gcc.target/powerpc/altivec-34.c.jj	2011-07-07 13:58:04.000000000 +0200
+++ gcc/testsuite/gcc.target/powerpc/altivec-34.c	2011-07-07 13:57:03.000000000 +0200
@@ -0,0 +1,24 @@ 
+/* PR target/49621 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -maltivec" } */
+
+#include <altivec.h>
+
+int
+foo (void)
+{
+  vector unsigned a, b, c;
+  unsigned k = 1;
+
+  a = (vector unsigned) { 0, 0, 0, 1 };
+  b = c = (vector unsigned) { 0, 0, 0, 0 };
+
+  a = vec_add (a, vec_splats (k));
+  b = vec_add (b, a);
+  c = vec_sel (c, a, b);
+
+  if (vec_any_eq (b, c))
+    return 1;
+
+  return 0;
+}