aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Greenhalgh <james.greenhalgh@arm.com>2013-01-18 16:59:49 +0000
committerJames Greenhalgh <james.greenhalgh@arm.com>2013-01-18 16:59:49 +0000
commitabc67da6a9ba940dd268a2044f7cf4799b846c4d (patch)
tree4b34a6693ee9deab4aa0bd91a1bd07ba108fe51d
parent08724a9e3848fe4c2e1aea0cfe30c5f081610218 (diff)
[AArch64-4.7] Backport: Add support for floating-point vcond.
gcc/ * config/aarch64/aarch64-simd.md (aarch64_simd_bsl<mode>_internal): Add floating-point modes. (aarch64_simd_bsl): Likewise. (aarch64_vcond_internal<mode>): Likewise. (vcond<mode><mode>): Likewise. (aarch64_cm<cmp><mode>): Fix constraints, add new modes. * config/aarch64/iterators.md (V_cmp_result): Add V2DF. gcc/testsuite/ * gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-d.c: New. * gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-f.c: Likewise. * gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-d.c: Likewise. * gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-f.c: Likewise. * gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-d.c: Likewise. * gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-f.c: Likewise. * gcc/testsuite/gcc.target/aarch64/vect-fcm.x: Likewise. * gcc/testsuite/lib/target-supports.exp (check_effective_target_vect_cond): Enable for AArch64. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/ARM/aarch64-4.7-branch@195298 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.aarch6413
-rw-r--r--gcc/config/aarch64/aarch64-simd.md103
-rw-r--r--gcc/testsuite/ChangeLog.aarch6415
-rw-r--r--gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-d.c14
-rw-r--r--gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-f.c14
-rw-r--r--gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-d.c14
-rw-r--r--gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-f.c14
-rw-r--r--gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-d.c14
-rw-r--r--gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-f.c14
-rw-r--r--gcc/testsuite/gcc.target/aarch64/vect-fcm.x56
-rw-r--r--gcc/testsuite/lib/target-supports.exp3
11 files changed, 255 insertions, 19 deletions
diff --git a/gcc/ChangeLog.aarch64 b/gcc/ChangeLog.aarch64
index afd9bf0a183..3a022502a1f 100644
--- a/gcc/ChangeLog.aarch64
+++ b/gcc/ChangeLog.aarch64
@@ -1,3 +1,16 @@
+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
+ (aarch64_simd_bsl<mode>_internal): Add floating-point modes.
+ (aarch64_simd_bsl): Likewise.
+ (aarch64_vcond_internal<mode>): Likewise.
+ (vcond<mode><mode>): Likewise.
+ (aarch64_cm<cmp><mode>): Fix constraints, add new modes.
+ * config/aarch64/iterators.md (V_cmp_result): Add V2DF.
+
2013-01-18 Tejas Belagod <tejas.belagod@arm.com>
* config/aarch64/arm_neon.h: Map scalar types to standard types.
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index b053b974ae6..b8a6b928614 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -1463,7 +1463,7 @@
(set_attr "simd_mode" "V2SI")]
)
-;; vbsl_* intrinsics may compile to any of vbsl/vbif/vbit depending on register
+;; vbsl_* intrinsics may compile to any of bsl/bif/bit depending on register
;; allocation. For an intrinsic of form:
;; vD = bsl_* (vS, vN, vM)
;; We can use any of:
@@ -1472,11 +1472,12 @@
;; bif vD, vM, vS (if D = N, so 0-bits in vS choose bits from vM, else vN)
(define_insn "aarch64_simd_bsl<mode>_internal"
- [(set (match_operand:VDQ 0 "register_operand" "=w,w,w")
- (unspec:VDQ [(match_operand:VDQ 1 "register_operand" " 0,w,w")
- (match_operand:VDQ 2 "register_operand" " w,w,0")
- (match_operand:VDQ 3 "register_operand" " w,0,w")]
- UNSPEC_BSL))]
+ [(set (match_operand:VALL 0 "register_operand" "=w,w,w")
+ (unspec:VALL
+ [(match_operand:<V_cmp_result> 1 "register_operand" " 0,w,w")
+ (match_operand:VALL 2 "register_operand" " w,w,0")
+ (match_operand:VALL 3 "register_operand" " w,0,w")]
+ UNSPEC_BSL))]
"TARGET_SIMD"
"@
bsl\\t%0.<Vbtype>, %2.<Vbtype>, %3.<Vbtype>
@@ -1485,15 +1486,15 @@
)
(define_expand "aarch64_simd_bsl<mode>"
- [(set (match_operand:VDQ 0 "register_operand")
- (unspec:VDQ [(match_operand:<V_cmp_result> 1 "register_operand")
- (match_operand:VDQ 2 "register_operand")
- (match_operand:VDQ 3 "register_operand")]
- UNSPEC_BSL))]
+ [(set (match_operand:VALL 0 "register_operand")
+ (unspec:VALL [(match_operand:<V_cmp_result> 1 "register_operand")
+ (match_operand:VALL 2 "register_operand")
+ (match_operand:VALL 3 "register_operand")]
+ UNSPEC_BSL))]
"TARGET_SIMD"
{
/* We can't alias operands together if they have different modes. */
- operands[1] = gen_lowpart (<MODE>mode, operands[1]);
+ operands[1] = gen_lowpart (<V_cmp_result>mode, operands[1]);
})
(define_expand "aarch64_vcond_internal<mode>"
@@ -1574,14 +1575,64 @@
DONE;
})
+(define_expand "aarch64_vcond_internal<mode>"
+ [(set (match_operand:VDQF 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 "register_operand")
+ (match_operand:VDQF 2 "register_operand")))]
+ "TARGET_SIMD"
+{
+ int inverse = 0;
+ rtx mask = 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]);
+
+ switch (GET_CODE (operands[3]))
+ {
+ case LT:
+ inverse = 1;
+ /* Fall through. */
+ case GE:
+ emit_insn (gen_aarch64_cmge<mode> (mask, operands[4], operands[5]));
+ break;
+ case LE:
+ inverse = 1;
+ /* Fall through. */
+ case GT:
+ emit_insn (gen_aarch64_cmgt<mode> (mask, operands[4], operands[5]));
+ break;
+ case NE:
+ inverse = 1;
+ /* Fall through. */
+ case EQ:
+ emit_insn (gen_aarch64_cmeq<mode> (mask, operands[4], operands[5]));
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ if (inverse)
+ emit_insn (gen_aarch64_simd_bsl<mode> (operands[0], mask, operands[2],
+ operands[1]));
+ else
+ emit_insn (gen_aarch64_simd_bsl<mode> (operands[0], mask, operands[1],
+ operands[2]));
+ DONE;
+})
+
(define_expand "vcond<mode><mode>"
- [(set (match_operand:VDQ 0 "register_operand")
- (if_then_else:VDQ
+ [(set (match_operand:VALL 0 "register_operand")
+ (if_then_else:VALL
(match_operator 3 "comparison_operator"
- [(match_operand:VDQ 4 "register_operand")
- (match_operand:VDQ 5 "nonmemory_operand")])
- (match_operand:VDQ 1 "register_operand")
- (match_operand:VDQ 2 "register_operand")))]
+ [(match_operand:VALL 4 "register_operand")
+ (match_operand:VALL 5 "nonmemory_operand")])
+ (match_operand:VALL 1 "register_operand")
+ (match_operand:VALL 2 "register_operand")))]
"TARGET_SIMD"
{
emit_insn (gen_aarch64_vcond_internal<mode> (operands[0], operands[1],
@@ -2866,6 +2917,22 @@
(set_attr "simd_mode" "<MODE>")]
)
+;; fcm(eq|ge|le|lt|gt)
+
+(define_insn "aarch64_cm<cmp><mode>"
+ [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w,w")
+ (unspec:<V_cmp_result>
+ [(match_operand:VDQF 1 "register_operand" "w,w")
+ (match_operand:VDQF 2 "aarch64_simd_reg_or_zero" "w,Dz")]
+ VCMP_S))]
+ "TARGET_SIMD"
+ "@
+ fcm<cmp>\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>
+ fcm<cmp>\t%<v>0<Vmtype>, %<v>1<Vmtype>, 0"
+ [(set_attr "simd_type" "simd_fcmp")
+ (set_attr "simd_mode" "<MODE>")]
+)
+
;; addp
(define_insn "aarch64_addp<mode>"
diff --git a/gcc/testsuite/ChangeLog.aarch64 b/gcc/testsuite/ChangeLog.aarch64
index 2044a9440cd..fd9ee7514a5 100644
--- a/gcc/testsuite/ChangeLog.aarch64
+++ b/gcc/testsuite/ChangeLog.aarch64
@@ -1,3 +1,18 @@
+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.
+ * gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-f.c: Likewise.
+ * gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-d.c: Likewise.
+ * gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-f.c: Likewise.
+ * gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-d.c: Likewise.
+ * gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-f.c: Likewise.
+ * gcc/testsuite/gcc.target/aarch64/vect-fcm.x: Likewise.
+ * gcc/testsuite/lib/target-supports.exp
+ (check_effective_target_vect_cond): Enable for AArch64.
+
2013-01-14 Tejas Belagod <tejas.belagod@arm.com>
* gcc.target/aarch64/aarch64/vect-ld1r-compile-fp.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
new file mode 100644
index 00000000000..a177d28fedb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-d.c
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */
+
+#define FTYPE double
+#define OP ==
+#define INV_OP !=
+
+#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 { 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
new file mode 100644
index 00000000000..01f388075d3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/vect-fcm-eq-f.c
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */
+
+#define FTYPE float
+#define OP ==
+#define INV_OP !=
+
+#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 { 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
new file mode 100644
index 00000000000..6027593a8d4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-d.c
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */
+
+#define FTYPE double
+#define OP >=
+#define INV_OP <
+
+#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 { 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
new file mode 100644
index 00000000000..0337d70359c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/vect-fcm-ge-f.c
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */
+
+#define FTYPE float
+#define OP >=
+#define INV_OP <
+
+#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 { 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
new file mode 100644
index 00000000000..b812a39196d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-d.c
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */
+
+#define FTYPE double
+#define OP >
+#define INV_OP <=
+
+#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 { 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
new file mode 100644
index 00000000000..5e012a4f4c9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/vect-fcm-gt-f.c
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-all -fno-unroll-loops --save-temps -fno-inline" } */
+
+#define FTYPE float
+#define OP >
+#define INV_OP <=
+
+#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 { cleanup-tree-dump "vect" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/vect-fcm.x b/gcc/testsuite/gcc.target/aarch64/vect-fcm.x
new file mode 100644
index 00000000000..7e51bef0ce2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/vect-fcm.x
@@ -0,0 +1,56 @@
+#include <stdlib.h>
+#define N 16
+
+FTYPE input1[N] =
+{2.0, 4.0, 8.0, 16.0,
+ 2.125, 4.25, 8.5, 17.0,
+ -2.0, -4.0, -8.0, -16.0,
+ -2.125, -4.25, -8.5, -17.0};
+
+FTYPE input2[N] =
+{-2.0, 4.0, -8.0, 16.0,
+ 2.125, -4.25, 8.5, -17.0,
+ 2.0, -4.0, 8.0, -16.0,
+ -2.125, 4.25, -8.5, 17.0};
+
+void
+foo (FTYPE *in1, FTYPE *in2, FTYPE *output)
+{
+ int i = 0;
+ /* Vectorizable. */
+ for (i = 0; i < N; i++)
+ output[i] = (in1[i] OP in2[i]) ? 2.0 : 4.0;
+}
+
+void
+bar (FTYPE *in1, FTYPE *in2, FTYPE *output)
+{
+ int i = 0;
+ /* Vectorizable. */
+ for (i = 0; i < N; i++)
+ output[i] = (in1[i] INV_OP in2[i]) ? 4.0 : 2.0;
+}
+
+void
+foobar (FTYPE *in1, FTYPE *in2, FTYPE *output)
+{
+ int i = 0;
+ /* Vectorizable. */
+ for (i = 0; i < N; i++)
+ output[i] = (in1[i] OP 0.0) ? 4.0 : 2.0;
+}
+
+int
+main (int argc, char **argv)
+{
+ FTYPE out1[N];
+ FTYPE out2[N];
+ int i = 0;
+ foo (input1, input2, out1);
+ bar (input1, input2, out2);
+ for (i = 0; i < N; i++)
+ if (out1[i] != out2[i])
+ abort ();
+ return 0;
+}
+
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 66a70899acc..b9337661b57 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -3490,7 +3490,8 @@ proc check_effective_target_vect_condition { } {
verbose "check_effective_target_vect_cond: using cached result" 2
} else {
set et_vect_cond_saved 0
- if { [istarget powerpc*-*-*]
+ if { [istarget aarch64*-*-*]
+ || [istarget powerpc*-*-*]
|| [istarget ia64-*-*]
|| [istarget i?86-*-*]
|| [istarget spu-*-*]