]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[AArch64] Fix vcond where comparison and result have different types.
authorJames Greenhalgh <james.greenhalgh@arm.com>
Tue, 14 May 2013 14:56:13 +0000 (14:56 +0000)
committerJames Greenhalgh <jgreenhalgh@gcc.gnu.org>
Tue, 14 May 2013 14:56:13 +0000 (14:56 +0000)
gcc/

* config/aarch64/aarch64-simd.md
(aarch64_vcond_internal<mode>): Rename to...
(aarch64_vcond_internal<mode><mode>): ...This, for integer modes.
(aarch64_vcond_internal<VDQF_COND:mode><VDQF:mode>): ...This for
float modes. Clarify all iterator modes.
(vcond<mode><mode>): Use new name for vcond expanders.
(vcond<v_cmp_result><mode>): Likewise.
(vcondu<mode><mode>: Likewise.
* config/aarch64/iterators.md (VDQF_COND): New.

gcc/testsuite/

* gcc.target/aarch64/vect-fcm.x: Add cases testing
FLOAT cmp FLOAT ? INT : INT.
 * gcc.target/aarch64/vect-fcm-eq-d.c: Define IMODE.
 * gcc.target/aarch64/vect-fcm-eq-f.c: Likewise.
 * gcc.target/aarch64/vect-fcm-ge-d.c: Likewise.
 * gcc.target/aarch64/vect-fcm-ge-f.c: Likewise.
 * gcc.target/aarch64/vect-fcm-gt-d.c: Likewise.
 * gcc.target/aarch64/vect-fcm-gt-f.c: Likewise.

From-SVN: r198890

gcc/ChangeLog
gcc/config/aarch64/aarch64-simd.md
gcc/config/aarch64/iterators.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-d.c
gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-f.c
gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-d.c
gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-f.c
gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-d.c
gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-f.c
gcc/testsuite/gcc.target/aarch64/vect-fcm.x

index 76ab15d6eb2917d475e5f253bc27b83ce24f873b..ce75cac360c93471cc8ee6e69188a1f68d92f3f3 100644 (file)
@@ -1,3 +1,15 @@
+2013-05-14  James Greenhalgh  <james.greenhalgh@arm.com>
+
+       * config/aarch64/aarch64-simd.md
+       (aarch64_vcond_internal<mode>): Rename to...
+       (aarch64_vcond_internal<mode><mode>): ...This, for integer modes.
+       (aarch64_vcond_internal<VDQF_COND:mode><VDQF:mode>): ...This for
+       float modes. Clarify all iterator modes.
+       (vcond<mode><mode>): Use new name for vcond expanders.
+       (vcond<v_cmp_result><mode>): Likewise.
+       (vcondu<mode><mode>: Likewise.
+       * config/aarch64/iterators.md (VDQF_COND): New.
+
 2013-05-14  Marc Glisse  <marc.glisse@inria.fr>
 
        PR bootstrap/57266
index b7cc9d3845e5f7768915058ad349a3ad19a5d43b..9069a73c46c9cdc5f75f00c7d0c0d1dc015bae79 100644 (file)
   DONE;
 })
 
-(define_expand "aarch64_vcond_internal<mode>"
+(define_expand "aarch64_vcond_internal<mode><mode>"
   [(set (match_operand:VDQ 0 "register_operand")
        (if_then_else:VDQ
          (match_operator 3 "comparison_operator"
   DONE;
 })
 
-(define_expand "aarch64_vcond_internal<mode>"
-  [(set (match_operand:VDQF 0 "register_operand")
+(define_expand "aarch64_vcond_internal<VDQF_COND:mode><VDQF:mode>"
+  [(set (match_operand:VDQF_COND 0 "register_operand")
        (if_then_else:VDQF
          (match_operator 3 "comparison_operator"
            [(match_operand:VDQF 4 "register_operand")
             (match_operand:VDQF 5 "nonmemory_operand")])
-         (match_operand:VDQF 1 "nonmemory_operand")
-         (match_operand:VDQF 2 "nonmemory_operand")))]
+         (match_operand:VDQF_COND 1 "nonmemory_operand")
+         (match_operand:VDQF_COND 2 "nonmemory_operand")))]
   "TARGET_SIMD"
 {
   int inverse = 0;
   int swap_bsl_operands = 0;
   rtx op1 = operands[1];
   rtx op2 = operands[2];
-  rtx mask = gen_reg_rtx (<V_cmp_result>mode);
-  rtx tmp = gen_reg_rtx (<V_cmp_result>mode);
+  rtx mask = gen_reg_rtx (<VDQF_COND:V_cmp_result>mode);
+  rtx tmp = gen_reg_rtx (<VDQF_COND:V_cmp_result>mode);
 
   rtx (*base_comparison) (rtx, rtx, rtx);
   rtx (*complimentary_comparison) (rtx, rtx, rtx);
       /* Fall through.  */
     default:
       if (!REG_P (operands[5]))
-       operands[5] = force_reg (<MODE>mode, operands[5]);
+       operands[5] = force_reg (<VDQF:MODE>mode, operands[5]);
     }
 
   switch (GET_CODE (operands[3]))
     case UNGE:
     case ORDERED:
     case UNORDERED:
-      base_comparison = gen_aarch64_cmge<mode>;
-      complimentary_comparison = gen_aarch64_cmgt<mode>;
+      base_comparison = gen_aarch64_cmge<VDQF:mode>;
+      complimentary_comparison = gen_aarch64_cmgt<VDQF:mode>;
       break;
     case LE:
     case UNLE:
       /* Fall through.  */
     case GT:
     case UNGT:
-      base_comparison = gen_aarch64_cmgt<mode>;
-      complimentary_comparison = gen_aarch64_cmge<mode>;
+      base_comparison = gen_aarch64_cmgt<VDQF:mode>;
+      complimentary_comparison = gen_aarch64_cmge<VDQF:mode>;
       break;
     case EQ:
     case NE:
     case UNEQ:
-      base_comparison = gen_aarch64_cmeq<mode>;
-      complimentary_comparison = gen_aarch64_cmeq<mode>;
+      base_comparison = gen_aarch64_cmeq<VDQF:mode>;
+      complimentary_comparison = gen_aarch64_cmeq<VDQF:mode>;
       break;
     default:
       gcc_unreachable ();
          switch (GET_CODE (operands[3]))
            {
            case LT:
-             base_comparison = gen_aarch64_cmlt<mode>;
+             base_comparison = gen_aarch64_cmlt<VDQF:mode>;
              break;
            case LE:
-             base_comparison = gen_aarch64_cmle<mode>;
+             base_comparison = gen_aarch64_cmle<VDQF:mode>;
              break;
            default:
              /* Do nothing, other zero form cases already have the correct
         true iff !(a != b && a ORDERED b), swapping the operands to BSL
         will then give us (a == b ||  a UNORDERED b) as intended.  */
 
-      emit_insn (gen_aarch64_cmgt<mode> (mask, operands[4], operands[5]));
-      emit_insn (gen_aarch64_cmgt<mode> (tmp, operands[5], operands[4]));
-      emit_insn (gen_ior<v_cmp_result>3 (mask, mask, tmp));
+      emit_insn (gen_aarch64_cmgt<VDQF:mode> (mask, operands[4], operands[5]));
+      emit_insn (gen_aarch64_cmgt<VDQF:mode> (tmp, operands[5], operands[4]));
+      emit_insn (gen_ior<VDQF_COND:v_cmp_result>3 (mask, mask, tmp));
       swap_bsl_operands = 1;
       break;
     case UNORDERED:
      swap_bsl_operands = 1;
      /* Fall through.  */
     case ORDERED:
-      emit_insn (gen_aarch64_cmgt<mode> (tmp, operands[4], operands[5]));
-      emit_insn (gen_aarch64_cmge<mode> (mask, operands[5], operands[4]));
-      emit_insn (gen_ior<v_cmp_result>3 (mask, mask, tmp));
+      emit_insn (gen_aarch64_cmgt<VDQF:mode> (tmp, operands[4], operands[5]));
+      emit_insn (gen_aarch64_cmge<VDQF:mode> (mask, operands[5], operands[4]));
+      emit_insn (gen_ior<VDQF_COND:v_cmp_result>3 (mask, mask, tmp));
       break;
     default:
       gcc_unreachable ();
     /* If we have (a = (b CMP c) ? -1 : 0);
        Then we can simply move the generated mask.  */
 
-    if (op1 == CONSTM1_RTX (<V_cmp_result>mode)
-       && op2 == CONST0_RTX (<V_cmp_result>mode))
+    if (op1 == CONSTM1_RTX (<VDQF_COND:V_cmp_result>mode)
+       && op2 == CONST0_RTX (<VDQF_COND:V_cmp_result>mode))
       emit_move_insn (operands[0], mask);
     else
       {
        if (!REG_P (op1))
-         op1 = force_reg (<MODE>mode, op1);
+         op1 = force_reg (<VDQF_COND:MODE>mode, op1);
        if (!REG_P (op2))
-         op2 = force_reg (<MODE>mode, op2);
-       emit_insn (gen_aarch64_simd_bsl<mode> (operands[0], mask,
+         op2 = force_reg (<VDQF_COND:MODE>mode, op2);
+       emit_insn (gen_aarch64_simd_bsl<VDQF_COND:mode> (operands[0], mask,
                                               op1, op2));
       }
 
          (match_operand:VALL 2 "nonmemory_operand")))]
   "TARGET_SIMD"
 {
-  emit_insn (gen_aarch64_vcond_internal<mode> (operands[0], operands[1],
+  emit_insn (gen_aarch64_vcond_internal<mode><mode> (operands[0], operands[1],
                                               operands[2], operands[3],
                                               operands[4], operands[5]));
   DONE;
          (match_operand:<V_cmp_result> 2 "nonmemory_operand")))]
   "TARGET_SIMD"
 {
-  emit_insn (gen_aarch64_vcond_internal<v_cmp_result> (
+  emit_insn (gen_aarch64_vcond_internal<v_cmp_result><mode> (
                                                operands[0], operands[1],
                                                operands[2], operands[3],
                                                operands[4], operands[5]));
          (match_operand:VDQ 2 "nonmemory_operand")))]
   "TARGET_SIMD"
 {
-  emit_insn (gen_aarch64_vcond_internal<mode> (operands[0], operands[1],
+  emit_insn (gen_aarch64_vcond_internal<mode><mode> (operands[0], operands[1],
                                               operands[2], operands[3],
                                               operands[4], operands[5]));
   DONE;
index 5945d23436d7cae1192459ec0d4fd39ec9ea1d68..860d4d9a1871dee032d800cf73ee85561e459ec8 100644 (file)
@@ -83,6 +83,9 @@
 ;; Vector Float modes.
 (define_mode_iterator VDQF [V2SF V4SF V2DF])
 
+;; Modes suitable to use as the return type of a vcond expression.
+(define_mode_iterator VDQF_COND [V2SF V2SI V4SF V4SI V2DF V2DI])
+
 ;; All Float modes.
 (define_mode_iterator VALLF [V2SF V4SF V2DF SF DF])
 
index 0507b6000582cb5ae4d993ab773291d1e06218b0..217bbb107aaa637907d9cb0ccd26c3b1a40527bf 100644 (file)
@@ -1,3 +1,14 @@
+2013-05-14  James Greenhalgh  <james.greenhalgh@arm.com>
+
+       * gcc.target/aarch64/vect-fcm.x: Add cases testing
+       FLOAT cmp FLOAT ? INT : INT.
+       * gcc.target/aarch64/vect-fcm-eq-d.c: Define IMODE.
+       * gcc.target/aarch64/vect-fcm-eq-f.c: Likewise.
+       * gcc.target/aarch64/vect-fcm-ge-d.c: Likewise.
+       * gcc.target/aarch64/vect-fcm-ge-f.c: Likewise.
+       * gcc.target/aarch64/vect-fcm-gt-d.c: Likewise.
+       * gcc.target/aarch64/vect-fcm-gt-f.c: Likewise.
+
 2013-05-14  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/53903
index 19ecd63b1d1371beb40d75220dac0e3f53d2d959..6c2e2c8b30e5f7509dfb5bda67b8524d7953d325 100644 (file)
@@ -2,12 +2,13 @@
 /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */
 
 #define FTYPE double
+#define ITYPE long
 #define OP ==
 #define INV_OP !=
 
 #include "vect-fcm.x"
 
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 8 "vect" } } */
 /* { dg-final { scan-assembler "fcmeq\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */
 /* { dg-final { scan-assembler "fcmeq\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, 0" } } */
 /* { dg-final { cleanup-tree-dump "vect" } } */
index 30be5adf529fd9ed96dfc4151e84111bd89b24f3..5a2109c4ac9b7e4c98e7c0ddeaa1013aa077d94a 100644 (file)
@@ -2,12 +2,13 @@
 /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */
 
 #define FTYPE float
+#define ITYPE int
 #define OP ==
 #define INV_OP !=
 
 #include "vect-fcm.x"
 
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 8 "vect" } } */
 /* { dg-final { scan-assembler "fcmeq\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s" } } */
 /* { dg-final { scan-assembler "fcmeq\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, 0" } } */
 /* { dg-final { cleanup-tree-dump "vect" } } */
index b922833be8c97a687f3495f24f8b758d42c12c21..8fad79998e3b704f152e857fef25ca9370414760 100644 (file)
@@ -2,12 +2,13 @@
 /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */
 
 #define FTYPE double
+#define ITYPE long
 #define OP >=
 #define INV_OP <
 
 #include "vect-fcm.x"
 
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 8 "vect" } } */
 /* { dg-final { scan-assembler "fcmge\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */
 /* { dg-final { scan-assembler "fcmge\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, 0" } } */
 /* { dg-final { scan-assembler "fcmlt\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, 0" } } */
index 04d3533ffe3657f22581804b5e412f052447a6b7..7aab9e6b0ad8ee9a0bcf143fcb30b76c18b87a4e 100644 (file)
@@ -2,12 +2,13 @@
 /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */
 
 #define FTYPE float
+#define ITYPE int
 #define OP >=
 #define INV_OP <
 
 #include "vect-fcm.x"
 
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 8 "vect" } } */
 /* { dg-final { scan-assembler "fcmge\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s" } } */
 /* { dg-final { scan-assembler "fcmge\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, 0" } } */
 /* { dg-final { scan-assembler "fcmlt\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, 0" } } */
index 421a04acfb407655b5bd56e5900a2ed6d7f5eba3..d26acaae3c1d17e776ed1496de92494d7690f003 100644 (file)
@@ -2,12 +2,13 @@
 /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */
 
 #define FTYPE double
+#define ITYPE long
 #define OP >
 #define INV_OP <=
 
 #include "vect-fcm.x"
 
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 8 "vect" } } */
 /* { dg-final { scan-assembler "fcmgt\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2d" } } */
 /* { dg-final { scan-assembler "fcmgt\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, 0" } } */
 /* { dg-final { scan-assembler "fcmle\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, 0" } } */
index cdeab14e0ed90f75162deb4900531d39f2631965..2797fd1a1158f26e3db8920ec1a4d6048460e7c5 100644 (file)
@@ -2,12 +2,13 @@
 /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */
 
 #define FTYPE float
+#define ITYPE int
 #define OP >
 #define INV_OP <=
 
 #include "vect-fcm.x"
 
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 8 "vect" } } */
 /* { dg-final { scan-assembler "fcmgt\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s" } } */
 /* { dg-final { scan-assembler "fcmgt\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, 0" } } */
 /* { dg-final { scan-assembler "fcmle\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, 0" } } */
index 803861b02930cf54d979b556c2f2c083b6adf7d6..614f0dec066b17c09dc1cee66a5ee846a6f02e62 100644 (file)
@@ -13,6 +13,8 @@ FTYPE input2[N] =
  2.0, -4.0, 8.0, -16.0,
  -2.125, 4.25, -8.5, 17.0};
 
+/* Float comparisons, float results.  */
+
 void
 foo (FTYPE *in1, FTYPE *in2, FTYPE *output)
 {
@@ -49,11 +51,52 @@ foobarbar (FTYPE *in1, FTYPE *in2, FTYPE *output)
     output[i] = (in1[i] INV_OP 0.0) ? 4.0 : 2.0;
 }
 
+/* Float comparisons, int results.  */
+
+void
+foo_int (FTYPE *in1, FTYPE *in2, ITYPE *output)
+{
+  int i = 0;
+  /* Vectorizable.  */
+  for (i = 0; i < N; i++)
+    output[i] = (in1[i] OP in2[i]) ? 2 : 4;
+}
+
+void
+bar_int (FTYPE *in1, FTYPE *in2, ITYPE *output)
+{
+  int i = 0;
+  /* Vectorizable.  */
+  for (i = 0; i < N; i++)
+    output[i] = (in1[i] INV_OP in2[i]) ? 4 : 2;
+}
+
+void
+foobar_int (FTYPE *in1, FTYPE *in2, ITYPE *output)
+{
+  int i = 0;
+  /* Vectorizable.  */
+  for (i = 0; i < N; i++)
+    output[i] = (in1[i] OP 0.0) ? 4 : 2;
+}
+
+void
+foobarbar_int (FTYPE *in1, FTYPE *in2, ITYPE *output)
+{
+  int i = 0;
+  /* Vectorizable.  */
+  for (i = 0; i < N; i++)
+    output[i] = (in1[i] INV_OP 0.0) ? 4 : 2;
+}
+
 int
 main (int argc, char **argv)
 {
   FTYPE out1[N];
   FTYPE out2[N];
+  ITYPE outi1[N];
+  ITYPE outi2[N];
+
   int i = 0;
   foo (input1, input2, out1);
   bar (input1, input2, out2);
@@ -65,6 +108,17 @@ main (int argc, char **argv)
   for (i = 0; i < N; i++)
     if (out1[i] == out2[i])
       abort ();
+
+  foo_int (input1, input2, outi1);
+  bar_int (input1, input2, outi2);
+  for (i = 0; i < N; i++)
+    if (outi1[i] != outi2[i])
+      abort ();
+  foobar_int (input1, input2, outi1);
+  foobarbar_int (input1, input2, outi2);
+  for (i = 0; i < N; i++)
+    if (outi1[i] == outi2[i])
+      abort ();
   return 0;
 }