From: dpatel Date: Mon, 18 Apr 2005 15:50:53 +0000 (+0000) Subject: * config/rs6000/atlivec.md (mulv4si3): New pattern. X-Git-Tag: upstream/4.9.2~62005 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5210db796309cfab53080cd417dc5d876e8d73a9;p=platform%2Fupstream%2Flinaro-gcc.git * config/rs6000/atlivec.md (mulv4si3): New pattern. * gcc.dg/vect/vect-11.c: Require effective target vect_int_mult. * gcc.dg/vect/vect-11a.c: New. * gcc.dg/vect/vect-none.c: Update. * lib/target-supports.exp (check_effective_target_vect_int_mult): New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@98323 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f1e108d..924cf26 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2005-04-18 Devang Patel + + * config/rs6000/atlivec.md (mulv4si3): New pattern. + 2005-04-18 James A. Morrison PR tree-optimization/20922 diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md index 7eb4611..6f11d7c 100644 --- a/gcc/config/rs6000/altivec.md +++ b/gcc/config/rs6000/altivec.md @@ -477,6 +477,65 @@ DONE; }") +;; 32 bit integer multiplication +;; A_high = Operand_0 & 0xFFFF0000 >> 16 +;; A_low = Operand_0 & 0xFFFF +;; B_high = Operand_1 & 0xFFFF0000 >> 16 +;; B_low = Operand_1 & 0xFFFF +;; result = A_low * B_low + (A_high * B_low + B_high * A_low) << 16 + +;; (define_insn "mulv4si3" +;; [(set (match_operand:V4SI 0 "register_operand" "=v") +;; (mult:V4SI (match_operand:V4SI 1 "register_operand" "v") +;; (match_operand:V4SI 2 "register_operand" "v")))] +(define_expand "mulv4si3" + [(use (match_operand:V4SI 0 "register_operand" "")) + (use (match_operand:V4SI 1 "register_operand" "")) + (use (match_operand:V4SI 2 "register_operand" ""))] + "TARGET_ALTIVEC" + " + { + rtx zero; + rtx swap; + rtx small_swap; + rtx sixteen; + rtx one; + rtx two; + rtx low_product; + rtx high_product; + + zero = gen_reg_rtx (V4SImode); + emit_insn (gen_altivec_vspltisw (zero, const0_rtx)); + + sixteen = gen_reg_rtx (V4SImode); + emit_insn (gen_altivec_vspltisw (sixteen, gen_rtx_CONST_INT (V4SImode, -16))); + + swap = gen_reg_rtx (V4SImode); + emit_insn (gen_altivec_vrlw (swap, operands[2], sixteen)); + + one = gen_reg_rtx (V8HImode); + convert_move (one, operands[1], 0); + + two = gen_reg_rtx (V8HImode); + convert_move (two, operands[2], 0); + + small_swap = gen_reg_rtx (V8HImode); + convert_move (small_swap, swap, 0); + + low_product = gen_reg_rtx (V4SImode); + emit_insn (gen_altivec_vmulouh (low_product, one, two)); + + high_product = gen_reg_rtx (V4SImode); + emit_insn (gen_altivec_vmsumuhm (high_product, one, small_swap, zero)); + + emit_insn (gen_altivec_vslw (high_product, high_product, sixteen)); + + emit_insn (gen_addv4si3 (operands[0], high_product, low_product)); + + DONE; + }") + + ;; Fused multiply subtract (define_insn "altivec_vnmsubfp" [(set (match_operand:V4SF 0 "register_operand" "=v") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 81e1aa7..d469720 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2005-04-18 Devang Patel + + * gcc.dg/vect/vect-11.c: Require effective target vect_int_mult. + * gcc.dg/vect/vect-11a.c: New. + * gcc.dg/vect/vect-none.c: Update. + * lib/target-supports.exp (check_effective_target_vect_int_mult): New. + 2005-04-18 James A. Morrison PR tree-optimization/20922 diff --git a/gcc/testsuite/gcc.dg/vect/vect-11.c b/gcc/testsuite/gcc.dg/vect/vect-11.c index 2e07233..0633b6c 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-11.c +++ b/gcc/testsuite/gcc.dg/vect/vect-11.c @@ -1,4 +1,5 @@ /* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_int_mult } */ #include #include "tree-vect.h" @@ -35,5 +36,5 @@ int main (void) return main1 (); } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */ +/* { 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-11a.c b/gcc/testsuite/gcc.dg/vect/vect-11a.c new file mode 100644 index 0000000..c77d6c9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-11a.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_int_mult } */ + +#include +#include "tree-vect.h" + +extern void abort (void); +void u () +{ + unsigned int A[4] = {0x08000000,0xffffffff,0xff0000ff,0xf0000001}; + unsigned int B[4] = {0x08000000,0x08000001,0xff0000ff,0xf0000001}; + unsigned int Answer[4] = {0,0xf7ffffff,0x0200fe01,0xe0000001}; + unsigned int C[4]; + int i, j; + + for (i=0; i<4; i++) + C[i] = A[i] * B[i]; + for (i=0; i<4; i++) + if (C[i] != Answer[i]) + abort (); +} +void s() +{ + signed int A[4] = {0x08000000,0xffffffff,0xff0000ff,0xf0000001}; + signed int B[4] = {0x08000000,0x08000001,0xff0000ff,0xf0000001}; + signed int Answer[4] = {0,0xf7ffffff,0x0200fe01, 0xe0000001}; + signed int C[4]; + int i, j; + + for (i=0; i<4; i++) + C[i] = A[i] * B[i]; + for (i=0; i<4; i++) + if (C[i] != Answer[i]) + abort (); +} + +int main1 () +{ + u(); + s(); + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-none.c b/gcc/testsuite/gcc.dg/vect/vect-none.c index 924c421..e36f487 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-none.c +++ b/gcc/testsuite/gcc.dg/vect/vect-none.c @@ -107,6 +107,7 @@ foo (int n) /* Test 3 - no target support for integer mult. */ + /* This loop is vectorized on platforms that support vect_int_mult. */ for (i = 0; i < N; i++) { ia[i] = ib[i] * ic[i]; @@ -133,6 +134,7 @@ foo (int n) /* Test 6 - condition in loop. */ + /* This loop is vectorized on platformst that support vect_condition. */ for (i = 0; i < N; i++){ a[i] = (b[i] > 0 ? b[i] : 0); } @@ -181,6 +183,9 @@ foo (int n) } /* { dg-final { scan-tree-dump-times "vectorized " 3 "vect"} } */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"} } */ -/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 2 "vect"} } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" { xfail powerpc*-*-* i?86-*-* x86_64-*-* } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target powerpc*-*-* } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 2 "vect" { target powerpc*-*-* } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target i?86-*-* x86_64-*-* ia64-*-* } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 2 "vect" { target i?86-*-* x86_64-*-* ia64-*-* } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 784c435..18d0e9d 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -856,6 +856,23 @@ proc check_effective_target_vect_condition { } { return $et_vect_cond_saved } +# Return 1 if the target supports vector int multiplication, 0 otherwise. + +proc check_effective_target_vect_int_mult { } { + global et_vect_int_mult_saved + + if [info exists et_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*-*-*] } { + set et_vect_int_mult_saved 1 + } + } + + verbose "check_effective_target_vect_int_mult: returning $et_vect_int_mult_saved" 2 + return $et_vect_int_mult_saved +} # Return 1 if the target matches the effective target 'arg', 0 otherwise. # This can be used with any check_* proc that takes no argument and