aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRevital Eres <eres@il.ibm.com>2007-10-31 17:04:42 +0000
committerRevital Eres <revitale@gcc.gnu.org>2007-10-31 17:04:42 +0000
commite2e95f45a8324f5aeacdc191217359f747fc2c26 (patch)
treeffcd2f0cd6e20a0379266c1ddc17953d9734dcc9 /gcc
parent1e4c40729a2606b0b3cd7993d9f6faac7ca1506b (diff)
downloadgcc-e2e95f45a8324f5aeacdc191217359f747fc2c26.zip
gcc-e2e95f45a8324f5aeacdc191217359f747fc2c26.tar.gz
gcc-e2e95f45a8324f5aeacdc191217359f747fc2c26.tar.bz2
Enable auto-vectorization for PowerPC 750CL paired-single instructions
From-SVN: r129803
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/config/rs6000/750cl.h3
-rw-r--r--gcc/config/rs6000/paired.md148
-rw-r--r--gcc/config/rs6000/rs6000-c.c2
-rw-r--r--gcc/config/rs6000/rs6000-protos.h6
-rw-r--r--gcc/config/rs6000/rs6000.c97
-rw-r--r--gcc/testsuite/ChangeLog27
-rw-r--r--gcc/testsuite/gcc.dg/vect/tree-vect.h5
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-ifcvt-11.c33
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-ifcvt-12.c32
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-ifcvt-13.c33
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-ifcvt-14.c33
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-ifcvt-15.c33
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-ifcvt-16.c33
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-ifcvt-17.c33
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect.exp9
-rw-r--r--gcc/testsuite/lib/target-supports.exp83
17 files changed, 614 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e781bd4..75cc8da 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,19 @@
+2007-10-31 Revital Eres <eres@il.ibm.com>
+
+ * config/rs6000/paired.md (sminv2sf3, smaxv2sf3, reduc_smax_v2sf,
+ reduc_smin_v2sf vec_interleave_highv2sf, vec_interleave_lowv2sf,
+ vec_extract_evenv2sf, vec_extract_oddv2sf, reduc_splus_v2sf,
+ movmisalignv2sf, vcondv2sf): New.
+ (UNSPEC_INTERHI_V2SF, UNSPEC_INTERLO_V2SF, UNSPEC_EXTEVEN_V2SF,
+ UNSPEC_EXTODD_V2SF): Define new constants.
+ * config/rs6000/rs6000-protos.h (paired_expand_vector_move,
+ paired_emit_vector_cond_expr): New.
+ * config/rs6000/rs6000-c.c (__PAIRED__): Add new builtin_define.
+ * config/rs6000/rs6000.c (paired_expand_vector_move,
+ paired_emit_vector_cond_expr, paired_emit_vector_compare):
+ New functions.
+ * config/rs6000/750cl.h (ASM_CPU_SPEC): Pass down -m750cl option.
+
2007-10-31 Sebastian Pop <sebastian.pop@amd.com>
PR tree-optimization/32377
diff --git a/gcc/config/rs6000/750cl.h b/gcc/config/rs6000/750cl.h
index d01761b..b88a194 100644
--- a/gcc/config/rs6000/750cl.h
+++ b/gcc/config/rs6000/750cl.h
@@ -21,3 +21,6 @@
#undef TARGET_PAIRED_FLOAT
#define TARGET_PAIRED_FLOAT rs6000_paired_float
+#undef ASM_CPU_SPEC
+#define ASM_CPU_SPEC "-m750cl"
+
diff --git a/gcc/config/rs6000/paired.md b/gcc/config/rs6000/paired.md
index 67eee23..4e41359 100644
--- a/gcc/config/rs6000/paired.md
+++ b/gcc/config/rs6000/paired.md
@@ -21,6 +21,12 @@
;; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
;; MA 02110-1301, USA.
+(define_constants
+[(UNSPEC_INTERHI_V2SF 330)
+ (UNSPEC_INTERLO_V2SF 331)
+ (UNSPEC_EXTEVEN_V2SF 332)
+ (UNSPEC_EXTODD_V2SF 333)
+])
(define_insn "negv2sf2"
[(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
@@ -370,3 +376,145 @@
"ps_merge00 %0, %1, %2"
[(set_attr "type" "fp")])
+(define_expand "sminv2sf3"
+ [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
+ (smin:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
+ (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
+ "TARGET_PAIRED_FLOAT"
+{
+ rtx tmp = gen_reg_rtx (V2SFmode);
+
+ emit_insn (gen_subv2sf3 (tmp, operands[1], operands[2]));
+ emit_insn (gen_selv2sf4 (operands[0], tmp, operands[2], operands[1], CONST0_RTX (SFmode)));
+ DONE;
+})
+
+(define_expand "smaxv2sf3"
+ [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
+ (smax:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")
+ (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
+ "TARGET_PAIRED_FLOAT"
+{
+ rtx tmp = gen_reg_rtx (V2SFmode);
+
+ emit_insn (gen_subv2sf3 (tmp, operands[1], operands[2]));
+ emit_insn (gen_selv2sf4 (operands[0], tmp, operands[1], operands[2], CONST0_RTX (SFmode)));
+ DONE;
+})
+
+(define_expand "reduc_smax_v2sf"
+ [(match_operand:V2SF 0 "gpc_reg_operand" "=f")
+ (match_operand:V2SF 1 "gpc_reg_operand" "f")]
+ "TARGET_PAIRED_FLOAT"
+{
+ rtx tmp_swap = gen_reg_rtx (V2SFmode);
+ rtx tmp = gen_reg_rtx (V2SFmode);
+
+ emit_insn (gen_paired_merge10 (tmp_swap, operands[1], operands[1]));
+ emit_insn (gen_subv2sf3 (tmp, operands[1], tmp_swap));
+ emit_insn (gen_selv2sf4 (operands[0], tmp, operands[1], tmp_swap, CONST0_RTX (SFmode)));
+
+ DONE;
+})
+
+(define_expand "reduc_smin_v2sf"
+ [(match_operand:V2SF 0 "gpc_reg_operand" "=f")
+ (match_operand:V2SF 1 "gpc_reg_operand" "f")]
+ "TARGET_PAIRED_FLOAT"
+{
+ rtx tmp_swap = gen_reg_rtx (V2SFmode);
+ rtx tmp = gen_reg_rtx (V2SFmode);
+
+ emit_insn (gen_paired_merge10 (tmp_swap, operands[1], operands[1]));
+ emit_insn (gen_subv2sf3 (tmp, operands[1], tmp_swap));
+ emit_insn (gen_selv2sf4 (operands[0], tmp, tmp_swap, operands[1], CONST0_RTX (SFmode)));
+
+ DONE;
+})
+
+(define_expand "vec_interleave_highv2sf"
+ [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
+ (unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "f")
+ (match_operand:V2SF 2 "gpc_reg_operand" "f")]
+ UNSPEC_INTERHI_V2SF))]
+ "TARGET_PAIRED_FLOAT"
+ "
+{
+ emit_insn (gen_paired_merge00 (operands[0], operands[1], operands[2]));
+ DONE;
+}")
+
+(define_expand "vec_interleave_lowv2sf"
+ [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
+ (unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "f")
+ (match_operand:V2SF 2 "gpc_reg_operand" "f")]
+ UNSPEC_INTERLO_V2SF))]
+ "TARGET_PAIRED_FLOAT"
+ "
+{
+ emit_insn (gen_paired_merge11 (operands[0], operands[1], operands[2]));
+ DONE;
+}")
+
+(define_expand "vec_extract_evenv2sf"
+ [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
+ (unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "f")
+ (match_operand:V2SF 2 "gpc_reg_operand" "f")]
+ UNSPEC_EXTEVEN_V2SF))]
+ "TARGET_PAIRED_FLOAT"
+ "
+{
+ emit_insn (gen_paired_merge00 (operands[0], operands[1], operands[2]));
+ DONE;
+}")
+
+(define_expand "vec_extract_oddv2sf"
+ [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
+ (unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "f")
+ (match_operand:V2SF 2 "gpc_reg_operand" "f")]
+ UNSPEC_EXTODD_V2SF))]
+ "TARGET_PAIRED_FLOAT"
+ "
+{
+ emit_insn (gen_paired_merge11 (operands[0], operands[1], operands[2]));
+ DONE;
+}")
+
+
+(define_expand "reduc_splus_v2sf"
+ [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
+ (match_operand:V2SF 1 "gpc_reg_operand" "f"))]
+ "TARGET_PAIRED_FLOAT"
+ "
+{
+ emit_insn (gen_paired_sum1 (operands[0], operands[1], operands[1], operands[1]));
+ DONE;
+}")
+
+(define_expand "movmisalignv2sf"
+ [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
+ (match_operand:V2SF 1 "gpc_reg_operand" "f"))]
+ "TARGET_PAIRED_FLOAT"
+{
+ paired_expand_vector_move (operands);
+ DONE;
+})
+
+(define_expand "vcondv2sf"
+ [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
+ (if_then_else:V2SF
+ (match_operator 3 "gpc_reg_operand"
+ [(match_operand:V2SF 4 "gpc_reg_operand" "f")
+ (match_operand:V2SF 5 "gpc_reg_operand" "f")])
+ (match_operand:V2SF 1 "gpc_reg_operand" "f")
+ (match_operand:V2SF 2 "gpc_reg_operand" "f")))]
+ "TARGET_PAIRED_FLOAT && flag_unsafe_math_optimizations"
+ "
+{
+ if (paired_emit_vector_cond_expr (operands[0], operands[1], operands[2],
+ operands[3], operands[4], operands[5]))
+ DONE;
+ else
+ FAIL;
+}")
+
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index f2a5061..336ecee 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -123,6 +123,8 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfile)
}
if (TARGET_SPE)
builtin_define ("__SPE__");
+ if (TARGET_PAIRED_FLOAT)
+ builtin_define ("__PAIRED__");
if (TARGET_SOFT_FLOAT)
builtin_define ("_SOFT_FLOAT");
if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 8c9eb06..56bb376 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -65,6 +65,12 @@ extern int mems_ok_for_quad_peep (rtx, rtx);
extern bool gpr_or_gpr_p (rtx, rtx);
extern enum reg_class rs6000_secondary_reload_class (enum reg_class,
enum machine_mode, rtx);
+
+extern int paired_emit_vector_cond_expr (rtx, rtx, rtx,
+ rtx, rtx, rtx);
+extern void paired_expand_vector_move (rtx operands[]);
+
+
extern int ccr_bit (rtx, int);
extern int extract_MB (rtx);
extern int extract_ME (rtx);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index cbbb8a8..3dc6c15 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -2773,6 +2773,103 @@ paired_expand_vector_init (rtx target, rtx vals)
emit_move_insn (target, new);
}
+void
+paired_expand_vector_move (rtx operands[])
+{
+ rtx op0 = operands[0], op1 = operands[1];
+
+ emit_move_insn (op0, op1);
+}
+
+/* Emit vector compare for code RCODE. DEST is destination, OP1 and
+ OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
+ operands for the relation operation COND. This is a recursive
+ function. */
+
+static void
+paired_emit_vector_compare (enum rtx_code rcode,
+ rtx dest, rtx op0, rtx op1,
+ rtx cc_op0, rtx cc_op1)
+{
+ rtx tmp = gen_reg_rtx (V2SFmode);
+ rtx tmp1, max, min, equal_zero;
+
+ gcc_assert (TARGET_PAIRED_FLOAT);
+ gcc_assert (GET_MODE (op0) == GET_MODE (op1));
+
+ switch (rcode)
+ {
+ case LT:
+ case LTU:
+ paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
+ return;
+ case GE:
+ case GEU:
+ emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
+ emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
+ return;
+ case LE:
+ case LEU:
+ paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
+ return;
+ case GT:
+ paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
+ return;
+ case EQ:
+ tmp1 = gen_reg_rtx (V2SFmode);
+ max = gen_reg_rtx (V2SFmode);
+ min = gen_reg_rtx (V2SFmode);
+ equal_zero = gen_reg_rtx (V2SFmode);
+
+ emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
+ emit_insn (gen_selv2sf4
+ (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
+ emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
+ emit_insn (gen_selv2sf4
+ (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
+ emit_insn (gen_subv2sf3 (tmp1, min, max));
+ emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
+ return;
+ case NE:
+ paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
+ return;
+ case UNLE:
+ paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
+ return;
+ case UNLT:
+ paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
+ return;
+ case UNGE:
+ paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
+ return;
+ case UNGT:
+ paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
+ return;
+ default:
+ gcc_unreachable ();
+ }
+
+ return;
+}
+
+/* Emit vector conditional expression.
+ DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
+ CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
+
+int
+paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
+ rtx cond, rtx cc_op0, rtx cc_op1)
+{
+ enum rtx_code rcode = GET_CODE (cond);
+
+ if (!TARGET_PAIRED_FLOAT)
+ return 0;
+
+ paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
+
+ return 1;
+}
+
/* Initialize vector TARGET to VALS. */
void
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9ff71b5..d8f691a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,30 @@
+2007-10-31 Revital Eres <eres@il.ibm.com>
+
+ * gcc.dg/vect/vect.exp: Add support for powerpc-*paired
+ target.
+ * gcc.dg/vect/tree-vect.h (check_vect): Add
+ powerpc-*paired test.
+ * lib/target-supports.exp (check_750cl_hw_available):
+ New.
+ (check_effective_target_vect_int,
+ check_effective_target_vect_intfloat_cvt,
+ check_effective_target_powerpc_altivec_ok,
+ check_effective_target_vect_long,
+ check_effective_target_vect_sdot_hi,
+ check_effective_target_vect_udot_hi,
+ check_effective_target_vect_pack_trunc,
+ check_effective_target_vect_unpack,
+ check_effective_target_vect_shift,
+ check_effective_target_vect_int_mult): Disable for powerpc-*paired
+ target.
+ * gcc.dg/vect/vect-ifcvt-11.c: New.
+ * gcc.dg/vect/vect-ifcvt-12.c: Likewise.
+ * gcc.dg/vect/vect-ifcvt-13.c: Likewise.
+ * gcc.dg/vect/vect-ifcvt-14.c: Likewise.
+ * gcc.dg/vect/vect-ifcvt-15.c: Likewise.
+ * gcc.dg/vect/vect-ifcvt-16.c: Likewise.
+ * gcc.dg/vect/vect-ifcvt-17.c: Likewise.
+
2007-10-31 Dominique d'Humieres <dominiq@lps.ens.fr>
Tobias Burnus <burnus@net-b.de>
diff --git a/gcc/testsuite/gcc.dg/vect/tree-vect.h b/gcc/testsuite/gcc.dg/vect/tree-vect.h
index 76e7ff4..e080a6d 100644
--- a/gcc/testsuite/gcc.dg/vect/tree-vect.h
+++ b/gcc/testsuite/gcc.dg/vect/tree-vect.h
@@ -13,7 +13,10 @@ sig_ill_handler (int sig)
void check_vect (void)
{
signal(SIGILL, sig_ill_handler);
-#if defined(__ppc__) || defined(__ppc64__) || defined(__powerpc__) || defined(powerpc)
+#if defined(__PAIRED__)
+ /* 750CL paired-single instruction, 'ps_mul %v0,%v0,%v0'. */
+ asm volatile (".long 0x10000032");
+#elif defined(__ppc__) || defined(__ppc64__) || defined(__powerpc__) || defined(powerpc)
/* Altivec instruction, 'vor %v0,%v0,%v0'. */
asm volatile (".long 0x10000484");
#elif defined(__i386__) || defined(__x86_64__)
diff --git a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-11.c b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-11.c
new file mode 100644
index 0000000..560b5bc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-11.c
@@ -0,0 +1,33 @@
+/* { dg-require-effective-target vect_condition } */
+/* { dg-require-effective-target vect_float } */
+
+#include <stdarg.h>
+#include <signal.h>
+#include "tree-vect.h"
+
+#define N 16
+#define MAX 42
+
+extern void abort(void);
+
+int main ()
+{
+ float A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11};
+ float B[N] = {0,0,42,42,42,0,0,0,0,0,42,42,42,42,42,0};
+ int i, j;
+
+ check_vect ();
+
+ for (i = 0; i < 16; i++)
+ A[i] = ( A[i] >= MAX ? MAX : 0);
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ if (A[i] != B[i])
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-12.c b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-12.c
new file mode 100644
index 0000000..5f132b8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-12.c
@@ -0,0 +1,32 @@
+/* { dg-require-effective-target vect_condition } */
+/* { dg-require-effective-target vect_float } */
+
+#include <stdarg.h>
+#include <signal.h>
+#include "tree-vect.h"
+
+#define N 16
+#define MAX 42
+
+extern void abort(void);
+
+int main ()
+{
+ float A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11};
+ float B[N] = {0,0,0,42,42,0,0,0,0,0,42,42,42,42,42,0};
+ int i, j;
+
+ check_vect ();
+ for (i = 0; i < 16; i++)
+ A[i] = ( A[i] > MAX ? MAX : 0);
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ if (A[i] != B[i])
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-13.c b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-13.c
new file mode 100644
index 0000000..a5a5936
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-13.c
@@ -0,0 +1,33 @@
+/* { dg-require-effective-target vect_condition } */
+/* { dg-require-effective-target vect_float } */
+
+#include <stdarg.h>
+#include <signal.h>
+#include "tree-vect.h"
+
+#define N 16
+#define MAX 42
+
+extern void abort(void);
+
+int main ()
+{
+ float A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11};
+ float B[N] = {42,42,42,0,0,42,42,42,42,42,0,0,0,0,0,42};
+ int i, j;
+
+ check_vect ();
+
+ for (i = 0; i < 16; i++)
+ A[i] = ( A[i] <= MAX ? MAX : 0);
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ if (A[i] != B[i])
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-14.c b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-14.c
new file mode 100644
index 0000000..a5a5936
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-14.c
@@ -0,0 +1,33 @@
+/* { dg-require-effective-target vect_condition } */
+/* { dg-require-effective-target vect_float } */
+
+#include <stdarg.h>
+#include <signal.h>
+#include "tree-vect.h"
+
+#define N 16
+#define MAX 42
+
+extern void abort(void);
+
+int main ()
+{
+ float A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11};
+ float B[N] = {42,42,42,0,0,42,42,42,42,42,0,0,0,0,0,42};
+ int i, j;
+
+ check_vect ();
+
+ for (i = 0; i < 16; i++)
+ A[i] = ( A[i] <= MAX ? MAX : 0);
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ if (A[i] != B[i])
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-15.c b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-15.c
new file mode 100644
index 0000000..67d7ebe
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-15.c
@@ -0,0 +1,33 @@
+/* { dg-require-effective-target vect_condition } */
+/* { dg-require-effective-target vect_float } */
+
+#include <stdarg.h>
+#include <signal.h>
+#include "tree-vect.h"
+
+#define N 16
+#define MAX 42
+
+extern void abort(void);
+
+int main ()
+{
+ float A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11};
+ float B[N] = {42,42,0,0,0,42,42,42,42,42,0,0,0,0,0,42};
+ int i, j;
+
+ check_vect ();
+
+ for (i = 0; i < 16; i++)
+ A[i] = ( A[i] < MAX ? MAX : 0);
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ if (A[i] != B[i])
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-16.c b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-16.c
new file mode 100644
index 0000000..de7da97e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-16.c
@@ -0,0 +1,33 @@
+/* { dg-require-effective-target vect_condition } */
+/* { dg-require-effective-target vect_float } */
+
+#include <stdarg.h>
+#include <signal.h>
+#include "tree-vect.h"
+
+#define N 16
+#define MAX 42
+
+extern void abort(void);
+
+int main ()
+{
+ float A[N] = {36,39,42,45,43,32,21,42,23,34,45,56,67,42,89,11};
+ float B[N] = {42,42,0,42,42,42,42,0,42,42,42,42,42,0,42,42};
+ int i, j;
+
+ check_vect ();
+
+ for (i = 0; i < 16; i++)
+ A[i] = ( A[i] != MAX ? MAX : 0);
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ if (A[i] != B[i])
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-17.c b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-17.c
new file mode 100644
index 0000000..0a497b5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-17.c
@@ -0,0 +1,33 @@
+/* { dg-require-effective-target vect_condition } */
+/* { dg-require-effective-target vect_float } */
+
+#include <stdarg.h>
+#include <signal.h>
+#include "tree-vect.h"
+
+#define N 16
+#define MAX 42
+
+extern void abort(void);
+
+int main ()
+{
+ float A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,42,78,89,11};
+ float B[N] = {42,42,0,42,42,42,42,42,42,42,42,42,0,42,42,42};
+ int i, j;
+
+ check_vect ();
+
+ for (i = 0; i < 16; i++)
+ A[i] = ( A[i] == MAX ? 0 : MAX);
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ if (A[i] != B[i])
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect.exp b/gcc/testsuite/gcc.dg/vect/vect.exp
index ad76833..40cb29f 100644
--- a/gcc/testsuite/gcc.dg/vect/vect.exp
+++ b/gcc/testsuite/gcc.dg/vect/vect.exp
@@ -36,7 +36,14 @@ set save-dg-do-what-default ${dg-do-what-default}
# Skip these tests for targets that do not support generating vector
# code. Set additional target-dependent vector flags, which can be
# overridden by using dg-options in individual tests.
-if [istarget "powerpc*-*-*"] {
+if [istarget "powerpc-*paired*"] {
+ lappend DEFAULT_VECTCFLAGS "-mpaired"
+ if [check_750cl_hw_available] {
+ set dg-do-what-default run
+ } else {
+ set dg-do-what-default compile
+ }
+} elseif [istarget "powerpc*-*-*"] {
# Skip targets not supporting -maltivec.
if ![is-effective-target powerpc_altivec_ok] {
return
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 5fe2059..f4c3e6a 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -906,6 +906,63 @@ proc check_effective_target_static_libgfortran { } {
return $et_static_libgfortran_saved
}
+# Return 1 if the target supports executing 750CL paired-single instructions, 0
+# otherwise. Cache the result.
+
+proc check_750cl_hw_available { } {
+ global 750cl_hw_available_saved
+ global tool
+
+ if [info exists 750cl_hw_available_saved] {
+ verbose "check_hw_available returning saved $750cl_hw_available_saved" 2
+ } else {
+ set 750cl_hw_available_saved 0
+
+ # If this is not the right target then we can quit.
+ if { ![istarget powerpc-*paired*] } {
+ verbose "check_hw_available returning 0" 2
+ return $750cl_hw_available_saved
+ }
+
+ # Set up, compile, and execute a test program containing paired-single
+ # instructions. Include the current process ID in the file
+ # names to prevent conflicts with invocations for multiple
+ # testsuites.
+ set src 750cl[pid].c
+ set exe 750cl[pid].x
+
+ set f [open $src "w"]
+ puts $f "int main() {"
+ puts $f "#ifdef __MACH__"
+ puts $f " asm volatile (\"ps_mul v0,v0,v0\");"
+ puts $f "#else"
+ puts $f " asm volatile (\"ps_mul 0,0,0\");"
+ puts $f "#endif"
+ puts $f " return 0; }"
+ close $f
+
+ verbose "check_750cl_hw_available compiling testfile $src" 2
+ set lines [${tool}_target_compile $src $exe executable "-mpaired"]
+ file delete $src
+
+ if [string match "" $lines] then {
+ # No error message, compilation succeeded.
+ set result [${tool}_load "./$exe" "" ""]
+ set status [lindex $result 0]
+ remote_file build delete $exe
+ verbose "check_750cl_hw_available testfile status is <$status>" 2
+
+ if { $status == "pass" } then {
+ set 750_hw_available_saved 1
+ }
+ } else {
+ verbose "check_750_hw_availalble testfile compilation failed" 2
+ }
+ }
+ return $750cl_hw_available_saved
+}
+
+
# Return 1 if the target supports executing AltiVec instructions, 0
# otherwise. Cache the result.
@@ -1451,7 +1508,8 @@ proc check_effective_target_vect_int { } {
} else {
set et_vect_int_saved 0
if { [istarget i?86-*-*]
- || [istarget powerpc*-*-*]
+ || ([istarget powerpc*-*-*]
+ && ![istarget powerpc-*-linux*paired*])
|| [istarget spu-*-*]
|| [istarget x86_64-*-*]
|| [istarget sparc*-*-*]
@@ -1476,7 +1534,8 @@ proc check_effective_target_vect_intfloat_cvt { } {
} else {
set et_vect_intfloat_cvt_saved 0
if { [istarget i?86-*-*]
- || [istarget powerpc*-*-*]
+ || ([istarget powerpc*-*-*]
+ && ![istarget powerpc-*-linux*paired*])
|| [istarget x86_64-*-*] } {
set et_vect_intfloat_cvt_saved 1
}
@@ -1618,7 +1677,8 @@ proc check_effective_target_powerpc_fprs { } {
# Return 1 if this is a PowerPC target supporting -maltivec.
proc check_effective_target_powerpc_altivec_ok { } {
- if { [istarget powerpc*-*-*]
+ if { ([istarget powerpc*-*-*]
+ && ![istarget powerpc-*-linux*paired*])
|| [istarget rs6000-*-*] } {
# AltiVec is not supported on AIX before 5.3.
if { [istarget powerpc*-*-aix4*]
@@ -1720,7 +1780,8 @@ proc check_effective_target_vect_shift { } {
verbose "check_effective_target_vect_shift: using cached result" 2
} else {
set et_vect_shift_saved 0
- if { [istarget powerpc*-*-*]
+ if { ([istarget powerpc*-*-*]
+ && ![istarget powerpc-*-linux*paired*])
|| [istarget ia64-*-*]
|| [istarget i?86-*-*]
|| [istarget x86_64-*-*] } {
@@ -1738,7 +1799,9 @@ proc check_effective_target_vect_shift { } {
proc check_effective_target_vect_long { } {
if { [istarget i?86-*-*]
- || ([istarget powerpc*-*-*] && [check_effective_target_ilp32])
+ || (([istarget powerpc*-*-*]
+ && ![istarget powerpc-*-linux*paired*])
+ && [check_effective_target_ilp32])
|| [istarget x86_64-*-*]
|| ([istarget sparc*-*-*] && [check_effective_target_ilp32]) } {
set answer 1
@@ -2033,7 +2096,7 @@ proc check_effective_target_vect_sdot_hi { } {
verbose "check_effective_target_vect_sdot_hi: using cached result" 2
} else {
set et_vect_sdot_hi_saved 0
- if { [istarget powerpc*-*-*]
+ if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
|| [istarget i?86-*-*]
|| [istarget x86_64-*-*] } {
set et_vect_sdot_hi_saved 1
@@ -2055,7 +2118,7 @@ proc check_effective_target_vect_udot_hi { } {
verbose "check_effective_target_vect_udot_hi: using cached result" 2
} else {
set et_vect_udot_hi_saved 0
- if { [istarget powerpc*-*-*] } {
+ if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) } {
set et_vect_udot_hi_saved 1
}
}
@@ -2077,7 +2140,7 @@ proc check_effective_target_vect_pack_trunc { } {
verbose "check_effective_target_vect_pack_trunc: using cached result" 2
} else {
set et_vect_pack_trunc_saved 0
- if { [istarget powerpc*-*-*]
+ if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
|| [istarget i?86-*-*]
|| [istarget x86_64-*-*] } {
set et_vect_pack_trunc_saved 1
@@ -2099,7 +2162,7 @@ proc check_effective_target_vect_unpack { } {
verbose "check_effective_target_vect_unpack: using cached result" 2
} else {
set et_vect_unpack_saved 0
- if { [istarget powerpc*-*-*]
+ if { ([istarget powerpc*-*-*] && ![istarget powerpc-*paired*])
|| [istarget i?86-*-*]
|| [istarget x86_64-*-*] } {
set et_vect_unpack_saved 1
@@ -2329,7 +2392,7 @@ proc check_effective_target_vect_int_mult { } {
verbose "check_effective_target_vect_int_mult: using cached result" 2
} else {
set et_vect_int_mult_saved 0
- if { [istarget powerpc*-*-*]
+ if { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*])
|| [istarget spu-*-*]
|| [istarget i?86-*-*]
|| [istarget x86_64-*-*] } {