diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1a526b7ca9e..e53614d339a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2016-06-23 Michael Meissner + Bill Schmidt + + * config/rs6000/predicates.md (splat_input_operand): Rework. + Don't allow constants, since the insns that use this predicate + don't support constants. Constants are handled by other insns + that are created via combine. During and after register + allocation, only allow indexed or indirect addresses, and not + general addresses. Only allow modes supported by the hardware. + * config/rs6000/rs6000.c (xxsplitb_constant_p): Update usage + comment. Move check for using VSPLTIS to a common location, + instead of doing it in two different places. + 2016-06-23 Jocelyn Mayer * config/i386/driver-i386.c (host_detect_local_cpu): Set diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 3d0f48ea712..5fb051af636 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -1056,27 +1056,34 @@ ;; Return 1 if this operand is a valid input for a vsx_splat insn. (define_predicate "splat_input_operand" - (match_code "symbol_ref,const,reg,subreg,mem, - const_double,const_wide_int,const_vector,const_int") + (match_code "reg,subreg,mem") { + machine_mode vmode; + + if (mode == DFmode) + vmode = V2DFmode; + else if (mode == DImode) + vmode = V2DImode; + else if (mode == SImode && TARGET_P9_VECTOR) + vmode = V4SImode; + else if (mode == SFmode && TARGET_P9_VECTOR) + vmode = V4SFmode; + else + return false; + if (MEM_P (op)) { + rtx addr = XEXP (op, 0); + if (! volatile_ok && MEM_VOLATILE_P (op)) return 0; - if (mode == DFmode) - mode = V2DFmode; - else if (mode == DImode) - mode = V2DImode; - else if (mode == SImode && TARGET_P9_VECTOR) - mode = V4SImode; - else if (mode == SFmode && TARGET_P9_VECTOR) - mode = V4SFmode; + + if (reload_in_progress || lra_in_progress || reload_completed) + return indexed_or_indirect_address (addr, vmode); else - gcc_unreachable (); - return memory_address_addr_space_p (mode, XEXP (op, 0), - MEM_ADDR_SPACE (op)); + return memory_address_addr_space_p (vmode, addr, MEM_ADDR_SPACE (op)); } - return input_operand (op, mode); + return gpc_reg_operand (op, mode); }) ;; Return true if OP is a non-immediate operand and not an invalid diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 7e9e908619a..4762c21b7a1 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -6282,14 +6282,7 @@ gen_easy_altivec_constant (rtx op) Return the number of instructions needed (1 or 2) into the address pointed via NUM_INSNS_PTR. - If NOSPLIT_P, only return true for constants that only generate the XXSPLTIB - instruction and can go in any VSX register. If !NOSPLIT_P, only return true - for constants that generate XXSPLTIB and need a sign extend operation, which - restricts us to the Altivec registers. - - Allow either (vec_const [...]) or (vec_duplicate ). If OP is a valid - XXSPLTIB constant, return the constant being set via the CONST_PTR - pointer. */ + Return the constant that is being split via CONSTANT_PTR. */ bool xxspltib_constant_p (rtx op, @@ -6355,13 +6348,6 @@ xxspltib_constant_p (rtx op, if (value != INTVAL (element)) return false; } - - /* See if we could generate vspltisw/vspltish directly instead of - xxspltib + sign extend. Special case 0/-1 to allow getting - any VSX register instead of an Altivec register. */ - if (!IN_RANGE (value, -1, 0) && EASY_VECTOR_15 (value) - && (mode == V4SImode || mode == V8HImode)) - return false; } /* Handle integer constants being loaded into the upper part of the VSX @@ -6389,6 +6375,13 @@ xxspltib_constant_p (rtx op, else return false; + /* See if we could generate vspltisw/vspltish directly instead of xxspltib + + sign extend. Special case 0/-1 to allow getting any VSX register instead + of an Altivec register. */ + if ((mode == V4SImode || mode == V8HImode) && !IN_RANGE (value, -1, 0) + && EASY_VECTOR_15 (value)) + return false; + /* Return # of instructions and the constant byte for XXSPLTIB. */ if (mode == V16QImode) *num_insns_ptr = 1; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3fb01671bb0..6e813cf372c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-06-23 Michael Meissner + Bill Schmidt + + * gcc.target/powerpc/p9-splat-5.c: New test. + 2016-06-23 Uros Bizjak PR tree-optimization/71488 diff --git a/gcc/testsuite/gcc.target/powerpc/p9-splat-5.c b/gcc/testsuite/gcc.target/powerpc/p9-splat-5.c new file mode 100644 index 00000000000..1aac2e81a11 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/p9-splat-5.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-options "-mcpu=power9 -O2" } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-final { scan-assembler "vspltish" } } */ +/* { dg-final { scan-assembler-not "xxspltib" } } */ + +/* Make sure we don't use an inefficient sequence for small integer splat. */ + +#include + +vector short +foo () +{ + return vec_splat_s16 (5); +}