OSDN Git Service

Enable auto-vectorization for PowerPC 750CL paired-single instructions
authorrevitale <revitale@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 31 Oct 2007 17:04:42 +0000 (17:04 +0000)
committerrevitale <revitale@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 31 Oct 2007 17:04:42 +0000 (17:04 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@129803 138bc75d-0d04-0410-961f-82ee72b054a4

17 files changed:
gcc/ChangeLog
gcc/config/rs6000/750cl.h
gcc/config/rs6000/paired.md
gcc/config/rs6000/rs6000-c.c
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/tree-vect.h
gcc/testsuite/gcc.dg/vect/vect-ifcvt-11.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-ifcvt-12.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-ifcvt-13.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-ifcvt-14.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-ifcvt-15.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-ifcvt-16.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-ifcvt-17.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect.exp
gcc/testsuite/lib/target-supports.exp

index e781bd4..75cc8da 100644 (file)
@@ -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
index d01761b..b88a194 100644 (file)
@@ -21,3 +21,6 @@
 #undef TARGET_PAIRED_FLOAT
 #define TARGET_PAIRED_FLOAT rs6000_paired_float
 
+#undef ASM_CPU_SPEC 
+#define ASM_CPU_SPEC "-m750cl"
+
index 67eee23..4e41359 100644 (file)
 ;; 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")
   "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;
+}")
+
index f2a5061..336ecee 100644 (file)
@@ -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)))
index 8c9eb06..56bb376 100644 (file)
@@ -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);
index cbbb8a8..3dc6c15 100644 (file)
@@ -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
index 9ff71b5..d8f691a 100644 (file)
@@ -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>
 
index 76e7ff4..e080a6d 100644 (file)
@@ -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 (file)
index 0000000..560b5bc
--- /dev/null
@@ -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 (file)
index 0000000..5f132b8
--- /dev/null
@@ -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 (file)
index 0000000..a5a5936
--- /dev/null
@@ -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 (file)
index 0000000..a5a5936
--- /dev/null
@@ -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 (file)
index 0000000..67d7ebe
--- /dev/null
@@ -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 (file)
index 0000000..de7da97
--- /dev/null
@@ -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 (file)
index 0000000..0a497b5
--- /dev/null
@@ -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" } } */
index ad76833..40cb29f 100644 (file)
@@ -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
index 5fe2059..f4c3e6a 100644 (file)
@@ -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-*-*] } {