Hi, This is a subsequent patch to refactor the existing float point vector comparison operator supports. The patch to fix PR92132 supplemented vector float point comparison by exposing the names for unordered/ordered/uneq/ltgt and adding ungt/unge/unlt/unle/ ne. As Segher pointed out, some patterns can be refactored together. The main link on this is: https://gcc.gnu.org/ml/gcc-patches/2019-11/msg00452.html
The refactoring mainly follows the below patterns: pattern 1: lt(a,b) = gt(b,a) le(a,b) = ge(b,a) pattern 2: unge(a,b) = ~gt(b,a) unle(a,b) = ~gt(a,b) ne(a,b) = ~eq(a,b) ungt(a,b) = ~ge(b,a) unlt(a,b) = ~ge(a,b) pattern 3: ltgt: gt(a,b) | gt(b,a) ordered: ge(a,b) | ge(b,a) pattern 4: uneq: ~gt(a,b) & ~gt(b,a) unordered: ~ge(a,b) & ~ge(b,a) Naming the code iterators and attributes are really knotty for me :(. Regression testing just launched. BR, Kewen ------------------------------- gcc/ChangeLog 2019-11-11 Kewen Lin <li...@gcc.gnu.org> * config/rs6000/vector.md (vec_fp_cmp1): New code iterator. (vec_fp_cmp2): Likewise. (vec_fp_cmp3): Likewise. (vec_fp_cmp4): Likewise. (vec_fp_cmp1_attr): New code attribute. (vec_fp_cmp2_attr): Likewise. (vec_fp_cmp3_attr): Likewise. (vec_fp_cmp4_attr): Likewise. (vector_<code><mode> for VEC_F and vec_fp_cmp1): New define_and_split. (vector_<code><mode> for VEC_F and vec_fp_cmp2): Likewise. (vector_<code><mode> for VEC_F and vec_fp_cmp3): Likewise. (vector_<code><mode> for VEC_F and vec_fp_cmp4): Likewise. (vector_lt<mode> for VEC_F): Refactor with vec_fp_cmp1. (vector_le<mode> for VEC_F): Likewise. (vector_unge<mode> for VEC_F): Refactor with vec_fp_cmp2. (vector_unle<mode> for VEC_F): Likewise. (vector_ne<mode> for VEC_F): Likewise. (vector_ungt<mode> for VEC_F): Likewise. (vector_unlt<mode> for VEC_F): Likewise. (vector_ltgt<mode> for VEC_F): Refactor with vec_fp_cmp3. (vector_ordered<mode> for VEC_F): Likewise. (vector_uneq<mode> for VEC_F): Refactor with vec_fp_cmp4. (vector_unordered<mode> for VEC_F): Likewise.
diff --git a/gcc/config/rs6000/vector.md b/gcc/config/rs6000/vector.md index b132037..be2d425 100644 --- a/gcc/config/rs6000/vector.md +++ b/gcc/config/rs6000/vector.md @@ -107,6 +107,31 @@ (smin "smin") (smax "smax")]) +;; code iterators and attributes for vector FP comparison operators: + +;; 1. lt and le. +(define_code_iterator vec_fp_cmp1 [lt le]) +(define_code_attr vec_fp_cmp1_attr [(lt "gt") + (le "ge")]) + +; 2. unge, unle, ne, ungt and unlt. +(define_code_iterator vec_fp_cmp2 [unge unle ne ungt unlt]) +(define_code_attr vec_fp_cmp2_attr [(unge "gt") + (unle "gt") + (ne "eq") + (ungt "ge") + (unlt "ge")]) + +;; 3. ltgt and ordered. +(define_code_iterator vec_fp_cmp3 [ltgt ordered]) +(define_code_attr vec_fp_cmp3_attr [(ltgt "gt") + (ordered "ge")]) + +;; 4. uneq and unordered. +(define_code_iterator vec_fp_cmp4 [uneq unordered]) +(define_code_attr vec_fp_cmp4_attr [(uneq "gt") + (unordered "ge")]) + ;; Vector move instructions. Little-endian VSX loads and stores require ;; special handling to circumvent "element endianness." @@ -665,88 +690,6 @@ DONE; }) -; lt(a,b) = gt(b,a) -(define_expand "vector_lt<mode>" - [(set (match_operand:VEC_F 0 "vfloat_operand") - (lt:VEC_F (match_operand:VEC_F 1 "vfloat_operand") - (match_operand:VEC_F 2 "vfloat_operand")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" -{ - emit_insn (gen_vector_gt<mode> (operands[0], operands[2], operands[1])); - DONE; -}) - -; le(a,b) = ge(b,a) -(define_expand "vector_le<mode>" - [(set (match_operand:VEC_F 0 "vfloat_operand") - (le:VEC_F (match_operand:VEC_F 1 "vfloat_operand") - (match_operand:VEC_F 2 "vfloat_operand")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" -{ - emit_insn (gen_vector_ge<mode> (operands[0], operands[2], operands[1])); - DONE; -}) - -; ne(a,b) = ~eq(a,b) -(define_expand "vector_ne<mode>" - [(set (match_operand:VEC_F 0 "vfloat_operand") - (ne:VEC_F (match_operand:VEC_F 1 "vfloat_operand") - (match_operand:VEC_F 2 "vfloat_operand")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" -{ - emit_insn (gen_vector_eq<mode> (operands[0], operands[1], operands[2])); - emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[0])); - DONE; -}) - -; unge(a,b) = ~gt(b,a) -(define_expand "vector_unge<mode>" - [(set (match_operand:VEC_F 0 "vfloat_operand") - (unge:VEC_F (match_operand:VEC_F 1 "vfloat_operand") - (match_operand:VEC_F 2 "vfloat_operand")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" -{ - emit_insn (gen_vector_gt<mode> (operands[0], operands[2], operands[1])); - emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[0])); - DONE; -}) - -; ungt(a,b) = ~ge(b,a) -(define_expand "vector_ungt<mode>" - [(set (match_operand:VEC_F 0 "vfloat_operand") - (ungt:VEC_F (match_operand:VEC_F 1 "vfloat_operand") - (match_operand:VEC_F 2 "vfloat_operand")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" -{ - emit_insn (gen_vector_ge<mode> (operands[0], operands[2], operands[1])); - emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[0])); - DONE; -}) - -; unle(a,b) = ~gt(a,b) -(define_expand "vector_unle<mode>" - [(set (match_operand:VEC_F 0 "vfloat_operand") - (unle:VEC_F (match_operand:VEC_F 1 "vfloat_operand") - (match_operand:VEC_F 2 "vfloat_operand")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" -{ - emit_insn (gen_vector_gt<mode> (operands[0], operands[1], operands[2])); - emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[0])); - DONE; -}) - -; unlt(a,b) = ~ge(a,b) -(define_expand "vector_unlt<mode>" - [(set (match_operand:VEC_F 0 "vfloat_operand") - (unlt:VEC_F (match_operand:VEC_F 1 "vfloat_operand") - (match_operand:VEC_F 2 "vfloat_operand")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" -{ - emit_insn (gen_vector_ge<mode> (operands[0], operands[1], operands[2])); - emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[0])); - DONE; -}) - (define_expand "vector_eq<mode>" [(set (match_operand:VEC_C 0 "vlogical_operand") (eq:VEC_C (match_operand:VEC_C 1 "vlogical_operand") @@ -761,13 +704,6 @@ "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") -(define_expand "vector_ge<mode>" - [(set (match_operand:VEC_F 0 "vlogical_operand") - (ge:VEC_F (match_operand:VEC_F 1 "vlogical_operand") - (match_operand:VEC_F 2 "vlogical_operand")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - ; >= for integer vectors: swap operands and apply not-greater-than (define_expand "vector_nlt<mode>" [(set (match_operand:VEC_I 3 "vlogical_operand") @@ -829,61 +765,74 @@ operands[3] = gen_reg_rtx_and_attrs (operands[0]); }) -(define_insn_and_split "vector_uneq<mode>" +; There are 14 possible vector FP comparison operators, gt and eq of them have +; been expanded above, so just support 12 remaining operators here. + +; 0. For ge: +(define_expand "vector_ge<mode>" + [(set (match_operand:VEC_F 0 "vlogical_operand") + (ge:VEC_F (match_operand:VEC_F 1 "vlogical_operand") + (match_operand:VEC_F 2 "vlogical_operand")))] + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" + "") + +; 1. For lt and le: +; lt(a,b) = gt(b,a) +; le(a,b) = ge(b,a) +(define_insn_and_split "vector_<code><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")))] + (vec_fp_cmp1: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) - (and:VEC_F (not:VEC_F (match_dup 3)) - (not:VEC_F (match_dup 4))))] + [(set (match_dup 0) + (<vec_fp_cmp1_attr>:VEC_F (match_dup 2) + (match_dup 1)))] { - operands[3] = gen_reg_rtx (<MODE>mode); - operands[4] = gen_reg_rtx (<MODE>mode); }) -(define_insn_and_split "vector_ltgt<mode>" +; 2. For unge, unle, ne, ungt and unlt: +; unge(a,b) = ~gt(b,a) +; unle(a,b) = ~gt(a,b) +; ne(a,b) = ~eq(a,b) +; ungt(a,b) = ~ge(b,a) +; unlt(a,b) = ~ge(a,b) +(define_insn_and_split "vector_<code><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")))] + (vec_fp_cmp2: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))) + (<vec_fp_cmp2_attr>:VEC_F (match_dup 1) + (match_dup 2))) (set (match_dup 0) - (ior:VEC_F (match_dup 3) - (match_dup 4)))] + (not:VEC_F (match_dup 3)))] { operands[3] = gen_reg_rtx (<MODE>mode); - operands[4] = gen_reg_rtx (<MODE>mode); + + if (<CODE> == UNGE || <CODE> == UNGT) + std::swap (operands[1], operands[2]); }) -(define_insn_and_split "vector_ordered<mode>" +; 3. For ltgt and ordered: +; ltgt: gt(a,b) | gt(b,a) +; ordered: ge(a,b) | ge(b,a) +(define_insn_and_split "vector_<code><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")))] + (vec_fp_cmp3: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))) + (<vec_fp_cmp3_attr>:VEC_F (match_dup 1) + (match_dup 2))) (set (match_dup 4) - (ge:VEC_F (match_dup 2) - (match_dup 1))) + (<vec_fp_cmp3_attr>:VEC_F (match_dup 2) + (match_dup 1))) (set (match_dup 0) (ior:VEC_F (match_dup 3) (match_dup 4)))] @@ -892,22 +841,25 @@ operands[4] = gen_reg_rtx (<MODE>mode); }) -(define_insn_and_split "vector_unordered<mode>" +; 4. For ltgt and ordered: +; uneq: ~gt(a,b) & ~gt(b,a) +; unordered: ~ge(a,b) & ~ge(b,a) +(define_insn_and_split "vector_<code><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")))] + (vec_fp_cmp4: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))) + (<vec_fp_cmp4_attr>:VEC_F (match_dup 1) + (match_dup 2))) (set (match_dup 4) - (ge:VEC_F (match_dup 2) - (match_dup 1))) + (<vec_fp_cmp4_attr>:VEC_F (match_dup 2) + (match_dup 1))) (set (match_dup 0) - (and:VEC_F (not:VEC_F (match_dup 3)) - (not:VEC_F (match_dup 4))))] + (and:VEC_F (not:VEC_F (match_dup 3)) + (not:VEC_F (match_dup 4))))] { operands[3] = gen_reg_rtx (<MODE>mode); operands[4] = gen_reg_rtx (<MODE>mode);