Hi, Add handling for early expansion of vector divide built-ins Bootstrapped and tested on powerpc64le-unknown-linux-gnu, and powerpc-unknown-linux, (p7,p8le,p8be) with no regressions.
OK for trunk? Thanks, -Will [gcc] 2017-05-10 Will Schmidt <will_schm...@vnet.ibm.com> * config/rs6000/rs6000.c (rs6000_gimple_fold_builtin): Add handling for early expansion of vector divide builtins. (builtin_function_type): Add VSX_BUILTIN_UDIV_V2DI to the list of builtins identified as having unsigned arguments. [gcc/testsuite] 2017-05-10 Will Schmidt <will_schm...@vnet.ibm.com> * gcc.target/powerpc/fold-vec-div-float.c: New. * gcc.target/powerpc/fold-vec-div-floatdouble.c: New. * gcc.target/powerpc/fold-vec-div-longlong.c: New. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 90f9f6a..a200072 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -16902,6 +16902,30 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi) gsi_replace (gsi, g, true); return true; } + /* Flavors of vec_div (Integer). */ + case VSX_BUILTIN_DIV_V2DI: + case VSX_BUILTIN_UDIV_V2DI: + { + arg0 = gimple_call_arg (stmt, 0); + arg1 = gimple_call_arg (stmt, 1); + lhs = gimple_call_lhs (stmt); + gimple *g = gimple_build_assign (lhs, TRUNC_DIV_EXPR, arg0, arg1); + gimple_set_location (g, gimple_location (stmt)); + gsi_replace (gsi, g, true); + return true; + } + /* Flavors of vec_div (Float). */ + case VSX_BUILTIN_XVDIVSP: + case VSX_BUILTIN_XVDIVDP: + { + arg0 = gimple_call_arg (stmt, 0); + arg1 = gimple_call_arg (stmt, 1); + lhs = gimple_call_lhs (stmt); + gimple *g = gimple_build_assign (lhs, RDIV_EXPR, arg0, arg1); + gimple_set_location (g, gimple_location (stmt)); + gsi_replace (gsi, g, true); + return true; + } /* Flavors of vec_and. */ case ALTIVEC_BUILTIN_VAND: { @@ -18667,6 +18691,7 @@ builtin_function_type (machine_mode mode_ret, machine_mode mode_arg0, case MISC_BUILTIN_DIVWEUO: case MISC_BUILTIN_DIVDEU: case MISC_BUILTIN_DIVDEUO: + case VSX_BUILTIN_UDIV_V2DI: h.uns_p[0] = 1; h.uns_p[1] = 1; h.uns_p[2] = 1; diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-div-float.c b/gcc/testsuite/gcc.target/powerpc/fold-vec-div-float.c new file mode 100644 index 0000000..8e8f645 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-div-float.c @@ -0,0 +1,16 @@ +/* Verify that overloaded built-ins for vec_div with float + inputs produce the right results with -maltivec. */ + +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec" } */ + +#include <altivec.h> + +vector float +test1 (vector float x, vector float y) +{ + return vec_div (x, y); +} + +/* { dg-final { scan-assembler-times {\mxvdivsp\M} 1 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-div-floatdouble.c b/gcc/testsuite/gcc.target/powerpc/fold-vec-div-floatdouble.c new file mode 100644 index 0000000..0559013 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-div-floatdouble.c @@ -0,0 +1,16 @@ +/* Verify that overloaded built-ins for vec_div with float and + double inputs for VSX produce the right results with -mvsx. */ + +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-maltivec" } */ + +#include <altivec.h> + +vector double +test2 (vector double x, vector double y) +{ + return vec_div (x, y); +} + +/* { dg-final { scan-assembler-times {\mxvdivdp\M} 1 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-div-longlong.c b/gcc/testsuite/gcc.target/powerpc/fold-vec-div-longlong.c new file mode 100644 index 0000000..c37c648 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-div-longlong.c @@ -0,0 +1,22 @@ +/* Verify that overloaded built-ins for vec_div with long long + inputs produce the right results. */ + +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_p8vector_ok } */ +/* { dg-options "-maltivec -mpower8-vector -O3" } */ + +#include <altivec.h> + +vector signed long long +test3 (vector signed long long x, vector signed long long y) +{ + return vec_div (x, y); +} + +vector unsigned long long +test6 (vector unsigned long long x, vector unsigned long long y) +{ + return vec_div (x, y); +} +/* { dg-final { scan-assembler-times {\mdivd\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mdivdu\M} 2 } } */