On power7 systems, the backend was not prepared to handle vector comparisons with UNEQ, LTGT, ORDERED, and UNORDERED tests, since there is no single comparison instruction for these cases. This patch adds support for doing vector conditional move involving these operations. I have bootstrapped the compiler with these patches, and there were no regressions. The test gcc.c-torture/execute/ieee/pr50340.c now passes if you build the compiler using --with-cpu=power7 as a default (or define ADDITIONAL_TORTURE_OPTIONS in the site.exp file to add -mcpu=power7). Is this ok to install in 4.8?
In addition, I would like to backport this fix to the current older branches. Can I check it into the 4.7 branch or should this patch wait until after the 4.7 release for 4.7.1? 2012-03-05 Michael Meissner <meiss...@linux.vnet.ibm.com> PR target/50310 * config/rs6000/vector.md (vector_uneq<mode>): Add support for UNEQ, LTGT, ORDERED, and UNORDERED IEEE vector comparisons. (vector_ltgt<mode>): Likewise. (vector_ordered<mode>): Likewise. (vector_unordered<mode>): Likewise. * config/rs6000/rs6000.c (rs6000_emit_vector_compare_inner): Likewise. -- Michael Meissner, IBM 5 Technology Place Drive, M/S 2757, Westford, MA 01886-3141, USA meiss...@linux.vnet.ibm.com fax +1 (978) 399-6899
Index: gcc/config/rs6000/vector.md =================================================================== --- gcc/config/rs6000/vector.md (revision 184959) +++ gcc/config/rs6000/vector.md (working copy) @@ -516,6 +516,94 @@ (define_expand "vector_geu<mode>" "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" "") +(define_insn_and_split "*vector_uneq<mode>" + [(set (match_operand:VEC_F 0 "vfloat_operand" "") + (uneq:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") + (match_operand:VEC_F 2 "vfloat_operand" "")))] + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" + "#" + "" + [(set (match_dup 3) + (gt:VEC_F (match_dup 1) + (match_dup 2))) + (set (match_dup 4) + (gt:VEC_F (match_dup 2) + (match_dup 1))) + (set (match_dup 0) + (not:VEC_F (ior:VEC_F (match_dup 3) + (match_dup 4))))] + " +{ + operands[3] = gen_reg_rtx (<MODE>mode); + operands[4] = gen_reg_rtx (<MODE>mode); +}") + +(define_insn_and_split "*vector_ltgt<mode>" + [(set (match_operand:VEC_F 0 "vfloat_operand" "") + (ltgt:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") + (match_operand:VEC_F 2 "vfloat_operand" "")))] + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" + "#" + "" + [(set (match_dup 3) + (gt:VEC_F (match_dup 1) + (match_dup 2))) + (set (match_dup 4) + (gt:VEC_F (match_dup 2) + (match_dup 1))) + (set (match_dup 0) + (ior:VEC_F (match_dup 3) + (match_dup 4)))] + " +{ + operands[3] = gen_reg_rtx (<MODE>mode); + operands[4] = gen_reg_rtx (<MODE>mode); +}") + +(define_insn_and_split "*vector_ordered<mode>" + [(set (match_operand:VEC_F 0 "vfloat_operand" "") + (ordered:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") + (match_operand:VEC_F 2 "vfloat_operand" "")))] + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" + "#" + "" + [(set (match_dup 3) + (ge:VEC_F (match_dup 1) + (match_dup 2))) + (set (match_dup 4) + (ge:VEC_F (match_dup 2) + (match_dup 1))) + (set (match_dup 0) + (ior:VEC_F (match_dup 3) + (match_dup 4)))] + " +{ + operands[3] = gen_reg_rtx (<MODE>mode); + operands[4] = gen_reg_rtx (<MODE>mode); +}") + +(define_insn_and_split "*vector_unordered<mode>" + [(set (match_operand:VEC_F 0 "vfloat_operand" "") + (unordered:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") + (match_operand:VEC_F 2 "vfloat_operand" "")))] + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" + "#" + "" + [(set (match_dup 3) + (ge:VEC_F (match_dup 1) + (match_dup 2))) + (set (match_dup 4) + (ge:VEC_F (match_dup 2) + (match_dup 1))) + (set (match_dup 0) + (not:VEC_F (ior:VEC_F (match_dup 3) + (match_dup 4))))] + " +{ + operands[3] = gen_reg_rtx (<MODE>mode); + operands[4] = gen_reg_rtx (<MODE>mode); +}") + ;; Note the arguments for __builtin_altivec_vsel are op2, op1, mask ;; which is in the reverse order that we want (define_expand "vector_select_<mode>" Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 184959) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -16126,6 +16126,10 @@ rs6000_emit_vector_compare_inner (enum r case EQ: case GT: case GTU: + case ORDERED: + case UNORDERED: + case UNEQ: + case LTGT: mask = gen_reg_rtx (mode); emit_insn (gen_rtx_SET (VOIDmode, mask,