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 <ja...@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. --- 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; +} Jakub