GCC Maintainers: I have addressed Segher's concerns regarding the range checking of the argument. The following is the updated patch.
The regression testing for the patch was done on GCC mainline on powerpc64le-unknown-linux-gnu (Power 8 LE) with no regressions. Additional hand testing was done on the following test cases to verify the range checking was working. vec_splat_u8 (0xfffffffe); vec_splat_u8 (0x7e); vec_splat_u8 (0xfe); vec_splat_u16 (0xfffffffe); vec_splat_u16 (0x7ffe); vec_splat_u16 (0xfffe); vec_splat_u16 (-2); vec_splat_u32 (0xfffffffe); vec_splat_u32 (0xeffffffe); vec_splat_s32 (16); vec_splat_s32 (15); vec_splat_s32 (-16); vec_splat_s32 (-17); vec_splat_s8 (16); vec_splat_s8 (15); vec_splat_s8 (1); vec_splat_s8 (-1); vec_splat_s8 (-16); vec_splat_s8 (-17); Please let me know if the patch looks OK for the GCC 7 branch. Carl Love -------------------------------------------------- gcc/ChangeLog: 2018-04-17 Carl Love <c...@us.ibm.com> PR target/83402 * config/rs6000/rs6000-c.c (rs6000_gimple_fold_builtin): Add size check for arg0. --- gcc/config/rs6000/rs6000.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index a0c9b5c..6b8039d 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -16574,10 +16574,23 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi) case ALTIVEC_BUILTIN_VSPLTISH: case ALTIVEC_BUILTIN_VSPLTISW: { + int size; + + if (fn_code == ALTIVEC_BUILTIN_VSPLTISB) + size = 8; + else if (fn_code == ALTIVEC_BUILTIN_VSPLTISH) + size = 16; + else + size = 32; + arg0 = gimple_call_arg (stmt, 0); lhs = gimple_call_lhs (stmt); - /* Only fold the vec_splat_*() if arg0 is constant. */ - if (TREE_CODE (arg0) != INTEGER_CST) + + /* Only fold the vec_splat_*() if the lower bits of arg 0 is a + 5-bit signed constant in range -16 to +15. */ + if (TREE_CODE (arg0) != INTEGER_CST + || !IN_RANGE (sext_hwi(TREE_INT_CST_LOW (arg0), size), + -16, 15)) return false; gimple_seq stmts = NULL; location_t loc = gimple_location (stmt); -- 2.7.4