diff options
author | revitale <revitale@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-10-31 17:04:42 +0000 |
---|---|---|
committer | revitale <revitale@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-10-31 17:04:42 +0000 |
commit | a39ea4df3097965e689783caa9098d496b837c9f (patch) | |
tree | ffcd2f0cd6e20a0379266c1ddc17953d9734dcc9 | |
parent | ed69e50620a42f9b5a5dc320e7ae3091a2f378cd (diff) | |
download | gcc-a39ea4df3097965e689783caa9098d496b837c9f.tar.gz |
Enable auto-vectorization for PowerPC 750CL paired-single instructions
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@129803 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/config/rs6000/750cl.h | 3 | ||||
-rw-r--r-- | gcc/config/rs6000/paired.md | 148 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000-c.c | 2 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000-protos.h | 6 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 97 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 27 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/tree-vect.h | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-ifcvt-11.c | 33 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-ifcvt-12.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-ifcvt-13.c | 33 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-ifcvt-14.c | 33 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-ifcvt-15.c | 33 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-ifcvt-16.c | 33 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-ifcvt-17.c | 33 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect.exp | 9 | ||||
-rw-r--r-- | gcc/testsuite/lib/target-supports.exp | 83 |
17 files changed, 614 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e781bd4b094..75cc8da6d0f 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 d01761b2ae2..b88a1942685 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 67eee233c5e..4e41359d014 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 f2a5061abc4..336eceef7b2 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 8c9eb0696c1..56bb376a77d 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 cbbb8a84a81..3dc6c15ad56 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 9ff71b51f2c..d8f691af424 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 76e7ff4557d..e080a6d35a4 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 00000000000..560b5bc73df --- /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 00000000000..5f132b8ba81 --- /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 00000000000..a5a59366bdc --- /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 00000000000..a5a59366bdc --- /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 00000000000..67d7ebe60c6 --- /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 00000000000..de7da97efa3 --- /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 00000000000..0a497b524bd --- /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 ad7683381fc..40cb29f5a6f 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 5fe2059dc1e..f4c3e6aea30 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-*-*] } { |