From fc21784dec6ab2642059b2a988af355a08cbba1a Mon Sep 17 00:00:00 2001 From: James Greenhalgh Date: Tue, 14 May 2013 14:56:13 +0000 Subject: [PATCH] [AArch64] Fix vcond where comparison and result have different types. gcc/ * config/aarch64/aarch64-simd.md (aarch64_vcond_internal): Rename to... (aarch64_vcond_internal): ...This, for integer modes. (aarch64_vcond_internal): ...This for float modes. Clarify all iterator modes. (vcond): Use new name for vcond expanders. (vcond): Likewise. (vcondu: 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 | 12 +++++ gcc/config/aarch64/aarch64-simd.md | 60 ++++++++++++------------ gcc/config/aarch64/iterators.md | 3 ++ gcc/testsuite/ChangeLog | 11 +++++ gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-d.c | 3 +- gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-f.c | 3 +- gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-d.c | 3 +- gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-f.c | 3 +- gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-d.c | 3 +- gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-f.c | 3 +- gcc/testsuite/gcc.target/aarch64/vect-fcm.x | 54 +++++++++++++++++++++ 11 files changed, 122 insertions(+), 36 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 76ab15d6eb2..ce75cac360c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2013-05-14 James Greenhalgh + + * config/aarch64/aarch64-simd.md + (aarch64_vcond_internal): Rename to... + (aarch64_vcond_internal): ...This, for integer modes. + (aarch64_vcond_internal): ...This for + float modes. Clarify all iterator modes. + (vcond): Use new name for vcond expanders. + (vcond): Likewise. + (vcondu: Likewise. + * config/aarch64/iterators.md (VDQF_COND): New. + 2013-05-14 Marc Glisse PR bootstrap/57266 diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index b7cc9d3845e..9069a73c46c 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -1711,7 +1711,7 @@ DONE; }) -(define_expand "aarch64_vcond_internal" +(define_expand "aarch64_vcond_internal" [(set (match_operand:VDQ 0 "register_operand") (if_then_else:VDQ (match_operator 3 "comparison_operator" @@ -1806,14 +1806,14 @@ DONE; }) -(define_expand "aarch64_vcond_internal" - [(set (match_operand:VDQF 0 "register_operand") +(define_expand "aarch64_vcond_internal" + [(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; @@ -1821,8 +1821,8 @@ int swap_bsl_operands = 0; rtx op1 = operands[1]; rtx op2 = operands[2]; - rtx mask = gen_reg_rtx (mode); - rtx tmp = gen_reg_rtx (mode); + rtx mask = gen_reg_rtx (mode); + rtx tmp = gen_reg_rtx (mode); rtx (*base_comparison) (rtx, rtx, rtx); rtx (*complimentary_comparison) (rtx, rtx, rtx); @@ -1842,7 +1842,7 @@ /* Fall through. */ default: if (!REG_P (operands[5])) - operands[5] = force_reg (mode, operands[5]); + operands[5] = force_reg (mode, operands[5]); } switch (GET_CODE (operands[3])) @@ -1855,8 +1855,8 @@ case UNGE: case ORDERED: case UNORDERED: - base_comparison = gen_aarch64_cmge; - complimentary_comparison = gen_aarch64_cmgt; + base_comparison = gen_aarch64_cmge; + complimentary_comparison = gen_aarch64_cmgt; break; case LE: case UNLE: @@ -1864,14 +1864,14 @@ /* Fall through. */ case GT: case UNGT: - base_comparison = gen_aarch64_cmgt; - complimentary_comparison = gen_aarch64_cmge; + base_comparison = gen_aarch64_cmgt; + complimentary_comparison = gen_aarch64_cmge; break; case EQ: case NE: case UNEQ: - base_comparison = gen_aarch64_cmeq; - complimentary_comparison = gen_aarch64_cmeq; + base_comparison = gen_aarch64_cmeq; + complimentary_comparison = gen_aarch64_cmeq; break; default: gcc_unreachable (); @@ -1899,10 +1899,10 @@ switch (GET_CODE (operands[3])) { case LT: - base_comparison = gen_aarch64_cmlt; + base_comparison = gen_aarch64_cmlt; break; case LE: - base_comparison = gen_aarch64_cmle; + base_comparison = gen_aarch64_cmle; break; default: /* Do nothing, other zero form cases already have the correct @@ -1945,9 +1945,9 @@ 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 (mask, operands[4], operands[5])); - emit_insn (gen_aarch64_cmgt (tmp, operands[5], operands[4])); - emit_insn (gen_ior3 (mask, mask, tmp)); + emit_insn (gen_aarch64_cmgt (mask, operands[4], operands[5])); + emit_insn (gen_aarch64_cmgt (tmp, operands[5], operands[4])); + emit_insn (gen_ior3 (mask, mask, tmp)); swap_bsl_operands = 1; break; case UNORDERED: @@ -1956,9 +1956,9 @@ swap_bsl_operands = 1; /* Fall through. */ case ORDERED: - emit_insn (gen_aarch64_cmgt (tmp, operands[4], operands[5])); - emit_insn (gen_aarch64_cmge (mask, operands[5], operands[4])); - emit_insn (gen_ior3 (mask, mask, tmp)); + emit_insn (gen_aarch64_cmgt (tmp, operands[4], operands[5])); + emit_insn (gen_aarch64_cmge (mask, operands[5], operands[4])); + emit_insn (gen_ior3 (mask, mask, tmp)); break; default: gcc_unreachable (); @@ -1973,16 +1973,16 @@ /* If we have (a = (b CMP c) ? -1 : 0); Then we can simply move the generated mask. */ - if (op1 == CONSTM1_RTX (mode) - && op2 == CONST0_RTX (mode)) + if (op1 == CONSTM1_RTX (mode) + && op2 == CONST0_RTX (mode)) emit_move_insn (operands[0], mask); else { if (!REG_P (op1)) - op1 = force_reg (mode, op1); + op1 = force_reg (mode, op1); if (!REG_P (op2)) - op2 = force_reg (mode, op2); - emit_insn (gen_aarch64_simd_bsl (operands[0], mask, + op2 = force_reg (mode, op2); + emit_insn (gen_aarch64_simd_bsl (operands[0], mask, op1, op2)); } @@ -1999,7 +1999,7 @@ (match_operand:VALL 2 "nonmemory_operand")))] "TARGET_SIMD" { - emit_insn (gen_aarch64_vcond_internal (operands[0], operands[1], + emit_insn (gen_aarch64_vcond_internal (operands[0], operands[1], operands[2], operands[3], operands[4], operands[5])); DONE; @@ -2015,7 +2015,7 @@ (match_operand: 2 "nonmemory_operand")))] "TARGET_SIMD" { - emit_insn (gen_aarch64_vcond_internal ( + emit_insn (gen_aarch64_vcond_internal ( operands[0], operands[1], operands[2], operands[3], operands[4], operands[5])); @@ -2032,7 +2032,7 @@ (match_operand:VDQ 2 "nonmemory_operand")))] "TARGET_SIMD" { - emit_insn (gen_aarch64_vcond_internal (operands[0], operands[1], + emit_insn (gen_aarch64_vcond_internal (operands[0], operands[1], operands[2], operands[3], operands[4], operands[5])); DONE; diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index 5945d23436d..860d4d9a187 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -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]) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0507b600058..217bbb107aa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2013-05-14 James Greenhalgh + + * 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 PR c++/53903 diff --git a/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-d.c b/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-d.c index 19ecd63b1d1..6c2e2c8b30e 100644 --- a/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-d.c +++ b/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-d.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-f.c b/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-f.c index 30be5adf529..5a2109c4ac9 100644 --- a/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-f.c +++ b/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-f.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-d.c b/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-d.c index b922833be8c..8fad79998e3 100644 --- a/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-d.c +++ b/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-d.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-f.c b/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-f.c index 04d3533ffe3..7aab9e6b0ad 100644 --- a/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-f.c +++ b/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-f.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-d.c b/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-d.c index 421a04acfb4..d26acaae3c1 100644 --- a/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-d.c +++ b/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-d.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-f.c b/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-f.c index cdeab14e0ed..2797fd1a115 100644 --- a/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-f.c +++ b/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-f.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/vect-fcm.x b/gcc/testsuite/gcc.target/aarch64/vect-fcm.x index 803861b0293..614f0dec066 100644 --- a/gcc/testsuite/gcc.target/aarch64/vect-fcm.x +++ b/gcc/testsuite/gcc.target/aarch64/vect-fcm.x @@ -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; } -- 2.11.4.GIT