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);

Reply via email to