diff options
author | jgreenhalgh <jgreenhalgh@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-01-18 17:03:30 +0000 |
---|---|---|
committer | jgreenhalgh <jgreenhalgh@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-01-18 17:03:30 +0000 |
commit | ea8020d9d4f9dd5b4add7c7836d87bee6863daba (patch) | |
tree | 8e920074704ec0c89464a4795483ef2c5919239b | |
parent | 7a4a9196a3508cb93ae3c9dfe8dd999ad656e5bc (diff) |
[AArch64-4.7] Backport: Fix unordered comparisons to floating-point vcond.
gcc/
* config/aarch64/aarch64-simd.md
(aarch64_vcond_internal<mode>): Handle unordered cases.
* config/aarch64/iterators.md (v_cmp_result): New.
gcc/testsuite/
* gcc.target/aarch64/vect-fcm-gt-f.c: Change expected output.
* gcc.target/aarch64/vect-fcm-gt-d.c: Likewise.
* gcc.target/aarch64/vect-fcm-ge-f.c: Likewise.
* gcc.target/aarch64/vect-fcm-ge-d.c: Likewise.
* gcc.target/aarch64/vect-fcm-eq-f.c: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/ARM/aarch64-4.7-branch@195300 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog.aarch64 | 9 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64-simd.md | 109 | ||||
-rw-r--r-- | gcc/config/aarch64/iterators.md | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog.aarch64 | 11 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-d.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-f.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-d.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-f.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-d.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-f.c | 4 |
10 files changed, 140 insertions, 21 deletions
diff --git a/gcc/ChangeLog.aarch64 b/gcc/ChangeLog.aarch64 index 3a022502a1f..e546a96deea 100644 --- a/gcc/ChangeLog.aarch64 +++ b/gcc/ChangeLog.aarch64 @@ -1,6 +1,15 @@ 2013-01-18 James Greenhalgh <james.greenhalgh@arm.com> Backport from mainline. + 2013-01-18 James Greenhalgh <james.greenhalgh@arm.com> + + * config/aarch64/aarch64-simd.md + (aarch64_vcond_internal<mode>): Handle unordered cases. + * config/aarch64/iterators.md (v_cmp_result): New. + +2013-01-18 James Greenhalgh <james.greenhalgh@arm.com> + + Backport from mainline. 2013-01-08 James Greenhalgh <james.greenhalgh@arm.com> * config/aarch64/aarch64-simd.md diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index b8a6b928614..bd6aeb145d6 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -1586,37 +1586,128 @@ "TARGET_SIMD" { int inverse = 0; + int swap_bsl_operands = 0; rtx mask = gen_reg_rtx (<V_cmp_result>mode); + rtx tmp = gen_reg_rtx (<V_cmp_result>mode); - if (!REG_P (operands[5]) - && (operands[5] != CONST0_RTX (<MODE>mode))) - operands[5] = force_reg (<MODE>mode, operands[5]); + rtx (*base_comparison) (rtx, rtx, rtx); + rtx (*complimentary_comparison) (rtx, rtx, rtx); + + switch (GET_CODE (operands[3])) + { + case GE: + case LE: + case EQ: + if (!REG_P (operands[5]) + && (operands[5] != CONST0_RTX (<MODE>mode))) + operands[5] = force_reg (<MODE>mode, operands[5]); + break; + default: + if (!REG_P (operands[5])) + operands[5] = force_reg (<MODE>mode, operands[5]); + } switch (GET_CODE (operands[3])) { case LT: + case UNLT: inverse = 1; /* Fall through. */ case GE: - emit_insn (gen_aarch64_cmge<mode> (mask, operands[4], operands[5])); + case UNGE: + case ORDERED: + case UNORDERED: + base_comparison = gen_aarch64_cmge<mode>; + complimentary_comparison = gen_aarch64_cmgt<mode>; break; case LE: + case UNLE: inverse = 1; /* Fall through. */ case GT: - emit_insn (gen_aarch64_cmgt<mode> (mask, operands[4], operands[5])); + case UNGT: + base_comparison = gen_aarch64_cmgt<mode>; + complimentary_comparison = gen_aarch64_cmge<mode>; break; + case EQ: case NE: - inverse = 1; - /* Fall through. */ + case UNEQ: + base_comparison = gen_aarch64_cmeq<mode>; + complimentary_comparison = gen_aarch64_cmeq<mode>; + break; + default: + gcc_unreachable (); + } + + switch (GET_CODE (operands[3])) + { + case LT: + case LE: + case GT: + case GE: case EQ: - emit_insn (gen_aarch64_cmeq<mode> (mask, operands[4], operands[5])); + /* The easy case. Here we emit one of FCMGE, FCMGT or FCMEQ. + As a LT b <=> b GE a && a LE b <=> b GT a. Our transformations are: + a GE b -> a GE b + a GT b -> a GT b + a LE b -> b GE a + a LT b -> b GT a + a EQ b -> a EQ b */ + + if (!inverse) + emit_insn (base_comparison (mask, operands[4], operands[5])); + else + emit_insn (complimentary_comparison (mask, operands[5], operands[4])); + break; + case UNLT: + case UNLE: + case UNGT: + case UNGE: + case NE: + /* FCM returns false for lanes which are unordered, so if we use + the inverse of the comparison we actually want to emit, then + swap the operands to BSL, we will end up with the correct result. + Note that a NE NaN and NaN NE b are true for all a, b. + + Our transformations are: + a GE b -> !(b GT a) + a GT b -> !(b GE a) + a LE b -> !(a GT b) + a LT b -> !(a GE b) + a NE b -> !(a EQ b) */ + + if (inverse) + emit_insn (base_comparison (mask, operands[4], operands[5])); + else + emit_insn (complimentary_comparison (mask, operands[5], operands[4])); + + swap_bsl_operands = 1; + break; + case UNEQ: + /* We check (a > b || b > a). combining these comparisons give us + 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)); + swap_bsl_operands = 1; + break; + case UNORDERED: + /* Operands are ORDERED iff (a > b || b >= a). + Swapping the operands to BSL will give the UNORDERED case. */ + 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)); break; default: gcc_unreachable (); } - if (inverse) + if (swap_bsl_operands) emit_insn (gen_aarch64_simd_bsl<mode> (operands[0], mask, operands[2], operands[1])); else diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index d99abd7569f..96ec437a37f 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -430,6 +430,14 @@ (V2SF "V2SI") (V4SF "V4SI") (V2DF "V2DI")]) +;; Lower case mode of results of comparison operations. +(define_mode_attr v_cmp_result [(V8QI "v8qi") (V16QI "v16qi") + (V4HI "v4hi") (V8HI "v8hi") + (V2SI "v2si") (V4SI "v4si") + (DI "di") (V2DI "v2di") + (V2SF "v2si") (V4SF "v4si") + (V2DF "v2di")]) + ;; Vm for lane instructions is restricted to FP_LO_REGS. (define_mode_attr vwx [(V4HI "x") (V8HI "x") (HI "x") (V2SI "w") (V4SI "w") (SI "w")]) diff --git a/gcc/testsuite/ChangeLog.aarch64 b/gcc/testsuite/ChangeLog.aarch64 index fd9ee7514a5..ecef675c11c 100644 --- a/gcc/testsuite/ChangeLog.aarch64 +++ b/gcc/testsuite/ChangeLog.aarch64 @@ -1,6 +1,17 @@ 2013-01-18 James Greenhalgh <james.greenhalgh@arm.com> Backport from mainline. + 2013-01-18 James Greenhalgh <james.greenhalgh@arm.com> + + * gcc.target/aarch64/vect-fcm-gt-f.c: Change expected output. + * gcc.target/aarch64/vect-fcm-gt-d.c: Likewise. + * gcc.target/aarch64/vect-fcm-ge-f.c: Likewise. + * gcc.target/aarch64/vect-fcm-ge-d.c: Likewise. + * gcc.target/aarch64/vect-fcm-eq-f.c: Likewise. + +2013-01-18 James Greenhalgh <james.greenhalgh@arm.com> + + Backport from mainline. 2013-01-08 James Greenhalgh <james.greenhalgh@arm.com> * gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-d.c: New. 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 a177d28fedb..b6fb5ae8798 100644 --- a/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-d.c +++ b/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-d.c @@ -8,7 +8,7 @@ #include "vect-fcm.x" /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" } } */ -/* { dg-final { scan-assembler-times "fcmeq\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2d" 2 } } */ -/* { dg-final { scan-assembler-times "fcmeq\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, 0" 1 } } */ +/* { 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" } } */ /* { dg-final { cleanup-saved-temps } } */ 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 01f388075d3..283d34fb80a 100644 --- a/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-f.c +++ b/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-f.c @@ -8,7 +8,7 @@ #include "vect-fcm.x" /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" } } */ -/* { dg-final { scan-assembler-times "fcmeq\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s" 2 } } */ -/* { dg-final { scan-assembler-times "fcmeq\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, 0" 1 } } */ +/* { 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" } } */ /* { dg-final { cleanup-saved-temps } } */ 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 6027593a8d4..868e1f8e60d 100644 --- a/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-d.c +++ b/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-d.c @@ -8,7 +8,7 @@ #include "vect-fcm.x" /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" } } */ -/* { dg-final { scan-assembler-times "fcmge\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2d" 2 } } */ -/* { dg-final { scan-assembler-times "fcmge\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, 0" 1 } } */ +/* { 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 { cleanup-tree-dump "vect" } } */ /* { dg-final { cleanup-saved-temps } } */ 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 0337d70359c..e3258f3641e 100644 --- a/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-f.c +++ b/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-f.c @@ -8,7 +8,7 @@ #include "vect-fcm.x" /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" } } */ -/* { dg-final { scan-assembler-times "fcmge\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s" 2 } } */ -/* { dg-final { scan-assembler-times "fcmge\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, 0" 1 } } */ +/* { 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 { cleanup-tree-dump "vect" } } */ /* { dg-final { cleanup-saved-temps } } */ 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 b812a39196d..ed8b4521591 100644 --- a/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-d.c +++ b/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-d.c @@ -8,7 +8,7 @@ #include "vect-fcm.x" /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" } } */ -/* { dg-final { scan-assembler-times "fcmgt\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2d" 2 } } */ -/* { dg-final { scan-assembler-times "fcmgt\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, 0" 1 } } */ +/* { 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 { cleanup-tree-dump "vect" } } */ /* { dg-final { cleanup-saved-temps } } */ 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 5e012a4f4c9..e90a87581d3 100644 --- a/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-f.c +++ b/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-f.c @@ -8,7 +8,7 @@ #include "vect-fcm.x" /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" } } */ -/* { dg-final { scan-assembler-times "fcmgt\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s" 2 } } */ -/* { dg-final { scan-assembler-times "fcmgt\\tv\[0-9\]+\.\[24\]s, v\[0-9\]+\.\[24\]s, 0" 1 } } */ +/* { 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 { cleanup-tree-dump "vect" } } */ /* { dg-final { cleanup-saved-temps } } */ |