From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1005) id 5E912393D00B; Wed, 19 May 2021 20:01:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5E912393D00B Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Michael Meissner To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/meissner/heads/work053)] Generate XXSPLTIW on power10. X-Act-Checkin: gcc X-Git-Author: Michael Meissner X-Git-Refname: refs/users/meissner/heads/work053 X-Git-Oldrev: 8fd939bbff9674785621ecae74c83fe1e6630741 X-Git-Newrev: 3f21da04e6957c4783f4219a7d392cceb3f2e435 Message-Id: <20210519200131.5E912393D00B@sourceware.org> Date: Wed, 19 May 2021 20:01:31 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 19 May 2021 20:01:31 -0000 https://gcc.gnu.org/g:3f21da04e6957c4783f4219a7d392cceb3f2e435 commit 3f21da04e6957c4783f4219a7d392cceb3f2e435 Author: Michael Meissner Date: Wed May 19 16:01:08 2021 -0400 Generate XXSPLTIW on power10. This patch adds support to automatically generate the ISA 3.1 XXSPLTIW instruction for V8HImode, V4SImode, and V4SFmode vectors. It does this by adding support for vector constants that can be used, and adding a VEC_DUPLICATE pattern to generate the actual XXSPLTIW instruction. I rewrote the XXSPLTW built-in functions to use VEC_DUPLICATE instead of UNSPEC. This patch also updates the insn counts in the vec-splati-runnable.c test to work with the new option to use XXSPLTIW to load up some vector constants. I added 3 new tests to test loading up V8HI, V4SI, and V4SF vector constants. 1 test needed to turn off power10 code generation so that the expected instructions would be correct. gcc/ 2021-05-19 Michael Meissner * config/rs6000/predicates.md (xxspltiw_operand): New predicate. (easy_vector_constant): If we can use XXSPLTIW, the vector constant is easy. * config/rs6000/rs6000-cpus.def (ISA_3_1_MASKS_SERVER): Add -mxxspltiw support. (POWERPC_MASKS): Add -mxxspltiw support. * config/rs6000/rs6000-protos.h (sign_extend_mode_constant): New declaration. (zero_extend_mode_constant); New declaration. * config/rs6000/rs6000.c (rs6000_option_override_internal): Add -mxxspltiw support. (xxspltib_constant_p): If we can generate XXSPLTIW, don't generate a XXSPLTIB and an extend instruction. (output_vec_const_move): Add support for loading up vector constants with XXSPLTIW. (rs6000_opt_masks): Add -mxxspltiw. (sign_extend_mode_constant): New function. (zero_extend_mode_constant): New function. * config/rs6000/rs6000.opt (-mxxspltiw): New debug switch. * config/rs6000/vsx.md (UNSPEC_XXSPLTIW): Delete. (xxspltiw_v8hi): New insn. (xxspltiw_v4si): Rewrite to generate a vector constant. (xxspltiw_v4sf): Rewrite to generate a vector constant. (xxspltiw_v4si_inst): Delete. (xxspltiw_v4sf_inst): Delete. (xxspltiw_v8hi_dup): New insn. (xxspltiw_v4si_dup): New insn. (xxspltiw_v4sf_dup): New insn. (XXSPLTIW): New mode iterator. (XXSPLTIW splitter): New insn splitter for XXSPLTIW. gcc/testsuite/ 2021-05-19 Michael Meissner * gcc.target/powerpc/pr86731-fwrapv.c: Turn off power10 code generation. * gcc.target/powerpc/vec-splati-runnable.c: Update insn counts. * gcc.target/powerpc/vec-splat-constant-v4sf.c: New test. * gcc.target/powerpc/vec-splat-constant-v4si.c: New test. * gcc.target/powerpc/vec-splat-constant-v8hi.c: New test. Diff: --- gcc/config/rs6000/predicates.md | 29 ++++ gcc/config/rs6000/rs6000-cpus.def | 7 +- gcc/config/rs6000/rs6000-protos.h | 3 + gcc/config/rs6000/rs6000.c | 73 +++++++++- gcc/config/rs6000/rs6000.opt | 4 + gcc/config/rs6000/vsx.md | 151 ++++++++++++++++----- gcc/testsuite/gcc.target/powerpc/pr86731-fwrapv.c | 7 + .../gcc.target/powerpc/vec-splat-constant-v4sf.c | 66 +++++++++ .../gcc.target/powerpc/vec-splat-constant-v4si.c | 51 +++++++ .../gcc.target/powerpc/vec-splat-constant-v8hi.c | 53 ++++++++ .../gcc.target/powerpc/vec-splati-runnable.c | 4 +- 11 files changed, 408 insertions(+), 40 deletions(-) diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index e21bc745f72..bf678f429af 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -640,6 +640,32 @@ return num_insns == 1; }) +;; Return 1 if the operand is a CONST_VECTOR that can be loaded with the +;; XXSPLTIW instruction. Do not return 1 if the constant can be generated with +;; XXSPLTIB or VSPLTIS{H,W} +(define_predicate "xxspltiw_operand" + (match_code "const_vector") +{ + if (!TARGET_XXSPLTIW) + return false; + + if (mode != V8HImode && mode != V4SImode && mode != V4SFmode) + return false; + + rtx element = CONST_VECTOR_ELT (op, 0); + for (size_t i = 1; i < GET_MODE_NUNITS (mode); i++) + if (!rtx_equal_p (element, CONST_VECTOR_ELT (op, i))) + return false; + + if (element == CONST0_RTX (GET_MODE_INNER (mode))) + return false; + + if (CONST_INT_P (element) && EASY_VECTOR_15 (INTVAL (element))) + return false; + + return true; +}) + ;; Return 1 if the operand is a CONST_VECTOR and can be loaded into a ;; vector register without using memory. (define_predicate "easy_vector_constant" @@ -653,6 +679,9 @@ if (zero_constant (op, mode) || all_ones_constant (op, mode)) return true; + if (xxspltiw_operand (op, mode)) + return true; + if (TARGET_P9_VECTOR && xxspltib_constant_p (op, mode, &num_insns, &value)) return true; diff --git a/gcc/config/rs6000/rs6000-cpus.def b/gcc/config/rs6000/rs6000-cpus.def index cbbb42c1b3a..a21a95bc7aa 100644 --- a/gcc/config/rs6000/rs6000-cpus.def +++ b/gcc/config/rs6000/rs6000-cpus.def @@ -85,7 +85,8 @@ | OTHER_POWER10_MASKS \ | OPTION_MASK_P10_FUSION \ | OPTION_MASK_P10_FUSION_LD_CMPI \ - | OPTION_MASK_P10_FUSION_2LOGICAL) + | OPTION_MASK_P10_FUSION_2LOGICAL \ + | OPTION_MASK_XXSPLTIW) /* Flags that need to be turned off if -mno-power9-vector. */ #define OTHER_P9_VECTOR_MASKS (OPTION_MASK_FLOAT128_HW \ @@ -160,8 +161,8 @@ | OPTION_MASK_RECIP_PRECISION \ | OPTION_MASK_SOFT_FLOAT \ | OPTION_MASK_STRICT_ALIGN_OPTIONAL \ - | OPTION_MASK_VSX) - + | OPTION_MASK_VSX \ + | OPTION_MASK_XXSPLTIW) #endif /* This table occasionally claims that a processor does not support a diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index c407034d58c..117724be1ff 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -283,6 +283,9 @@ extern void rs6000_asm_output_dwarf_pcrel (FILE *file, int size, extern void rs6000_asm_output_dwarf_datarel (FILE *file, int size, const char *label); extern long rs6000_const_f32_to_i32 (rtx operand); +extern HOST_WIDE_INT sign_extend_mode_constant (machine_mode, HOST_WIDE_INT); +extern unsigned HOST_WIDE_INT zero_extend_mode_constant (machine_mode, + HOST_WIDE_INT); /* Declare functions in rs6000-c.c */ diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index ef1ebaaee05..1b65e729017 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -4487,6 +4487,12 @@ rs6000_option_override_internal (bool global_init_p) if (!TARGET_PCREL && TARGET_PCREL_OPT) rs6000_isa_flags &= ~OPTION_MASK_PCREL_OPT; + if (TARGET_POWER10 && TARGET_VSX + && (rs6000_isa_flags_explicit & OPTION_MASK_XXSPLTIW) == 0) + rs6000_isa_flags |= OPTION_MASK_XXSPLTIW; + else if (!TARGET_POWER10 || !TARGET_VSX) + rs6000_isa_flags &= ~OPTION_MASK_XXSPLTIW; + if (TARGET_DEBUG_REG || TARGET_DEBUG_TARGET) rs6000_print_isa_options (stderr, 0, "after subtarget", rs6000_isa_flags); @@ -6464,9 +6470,11 @@ xxspltib_constant_p (rtx op, /* 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)) + of an Altivec register. Also if we can generate a XXSPLTIW instruction, + don't emit a XXSPLTIB and an extend instruction. */ + if ((mode == V4SImode || mode == V8HImode) + && !IN_RANGE (value, -1, 0) + && (EASY_VECTOR_15 (value) || TARGET_XXSPLTIW)) return false; /* Return # of instructions and the constant byte for XXSPLTIB. */ @@ -6527,6 +6535,9 @@ output_vec_const_move (rtx *operands) gcc_unreachable (); } + if (xxspltiw_operand (vec, mode)) + return "#"; + if (TARGET_P9_VECTOR && xxspltib_constant_p (vec, mode, &num_insns, &xxspltib_value)) { @@ -24118,6 +24129,7 @@ static struct rs6000_opt_mask const rs6000_opt_masks[] = { "string", 0, false, true }, { "update", OPTION_MASK_NO_UPDATE, true , true }, { "vsx", OPTION_MASK_VSX, false, true }, + { "xxspltiw", OPTION_MASK_XXSPLTIW, false, true }, #ifdef OPTION_MASK_64BIT #if TARGET_AIX_OS { "aix64", OPTION_MASK_64BIT, false, false }, @@ -27980,6 +27992,61 @@ rs6000_output_addr_vec_elt (FILE *file, int value) fprintf (file, "\n"); } +/* Sign extend integer values to a given mode. */ +HOST_WIDE_INT +sign_extend_mode_constant (machine_mode mode, HOST_WIDE_INT value) +{ + HOST_WIDE_INT mask; + + switch (mode) + { + default: + gcc_unreachable (); + + case E_QImode: + mask = HOST_WIDE_INT_C (0x80); + break; + + case E_HImode: + mask = HOST_WIDE_INT_C (0x8000); + break; + + case E_SImode: + mask = HOST_WIDE_INT_C (0x80000000); + break; + } + + return ((value ^ mask) - mask); +} + +/* Zero extend integer values to a given mode. */ +unsigned HOST_WIDE_INT +zero_extend_mode_constant (machine_mode mode, HOST_WIDE_INT value) +{ + unsigned HOST_WIDE_INT uvalue = (unsigned HOST_WIDE_INT) value; + unsigned HOST_WIDE_INT mask; + + switch (mode) + { + default: + gcc_unreachable (); + + case E_QImode: + mask = HOST_WIDE_INT_UC (0xff); + break; + + case E_HImode: + mask = HOST_WIDE_INT_UC (0xffff); + break; + + case E_SImode: + mask = HOST_WIDE_INT_UC (0xffffffff); + break; + } + + return uvalue & mask; +} + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-rs6000.h" diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt index 2685fa71517..5e282d3741c 100644 --- a/gcc/config/rs6000/rs6000.opt +++ b/gcc/config/rs6000/rs6000.opt @@ -627,3 +627,7 @@ Enable instructions that guard against return-oriented programming attacks. mprivileged Target Var(rs6000_privileged) Init(0) Generate code that will run in privileged state. + +mxxspltiw +Target Undocumented Mask(XXSPLTIW) Var(rs6000_isa_flags) +Generate (do not generate) XXSPLTIW instructions. diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index 15a8c0e22d8..a6218d4d8e1 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -386,7 +386,6 @@ UNSPEC_VDIVES UNSPEC_VDIVEU UNSPEC_XXEVAL - UNSPEC_XXSPLTIW UNSPEC_XXSPLTID UNSPEC_XXSPLTI32DX UNSPEC_XXBLEND @@ -6239,36 +6238,6 @@ "vmulld %0,%1,%2" [(set_attr "type" "veccomplex")]) -;; XXSPLTIW built-in function support -(define_insn "xxspltiw_v4si" - [(set (match_operand:V4SI 0 "register_operand" "=wa") - (unspec:V4SI [(match_operand:SI 1 "s32bit_cint_operand" "n")] - UNSPEC_XXSPLTIW))] - "TARGET_POWER10" - "xxspltiw %x0,%1" - [(set_attr "type" "vecsimple") - (set_attr "prefixed" "yes")]) - -(define_expand "xxspltiw_v4sf" - [(set (match_operand:V4SF 0 "register_operand" "=wa") - (unspec:V4SF [(match_operand:SF 1 "const_double_operand" "n")] - UNSPEC_XXSPLTIW))] - "TARGET_POWER10" -{ - long long value = rs6000_const_f32_to_i32 (operands[1]); - emit_insn (gen_xxspltiw_v4sf_inst (operands[0], GEN_INT (value))); - DONE; -}) - -(define_insn "xxspltiw_v4sf_inst" - [(set (match_operand:V4SF 0 "register_operand" "=wa") - (unspec:V4SF [(match_operand:SI 1 "c32bit_cint_operand" "n")] - UNSPEC_XXSPLTIW))] - "TARGET_POWER10" - "xxspltiw %x0,%1" - [(set_attr "type" "vecsimple") - (set_attr "prefixed" "yes")]) - ;; XXSPLTIDP built-in function support (define_expand "xxspltidp_v2df" [(set (match_operand:V2DF 0 "register_operand" ) @@ -6420,3 +6389,123 @@ [(set_attr "type" "vecsimple") (set_attr "prefixed" "yes")]) +;; XXSPLTIW built-in function support. Convert to a vector constant, which +;; will then be optimized to the XXSPLTIW instruction. +(define_expand "xxspltiw_v4si" + [(use (match_operand:V4SI 0 "register_operand")) + (use (match_operand:SI 1 "s32bit_cint_operand"))] + "TARGET_POWER10" +{ + rtx op1 = operands[1]; + rtvec rv = gen_rtvec (4, op1, op1, op1, op1); + rtx vec_constant = gen_rtx_CONST_VECTOR (V4SImode, rv); + emit_move_insn (operands[0], vec_constant); +}) + +(define_expand "xxspltiw_v4sf" + [(use (match_operand:V4SF 0 "register_operand")) + (use (match_operand:SF 1 "const_double_operand"))] + "TARGET_POWER10" +{ + rtx op1 = operands[1]; + rtvec rv = gen_rtvec (4, op1, op1, op1, op1); + rtx vec_constant = gen_rtx_CONST_VECTOR (V4SFmode, rv); + emit_move_insn (operands[0], vec_constant); +}) + +;; XXSPLTIW support. Add support for the XXSPLTIW built-in functions, and to +;; use XXSPLTIW to load up vector V8HImode, V4SImode, and V4SFmode vector +;; constants where all elements are the the same. We special case loading up +;; integer -16..15 and floating point 0.0f, since we can use the shorter +;; XXSPLTIB, VSPLTISH, and VSPLTISW instructions. + +(define_insn "*xxspltiw_v8hi_dup" + [(set (match_operand:V8HI 0 "vsx_register_operand" "=wa,wa,v,wa") + (vec_duplicate:V8HI + (match_operand 1 "const_int_operand" "O,wM,wB,n")))] + "TARGET_XXSPLTIW" +{ + HOST_WIDE_INT value = INTVAL (operands[1]); + unsigned HOST_WIDE_INT uns_value = zero_extend_mode_constant (HImode, value); + HOST_WIDE_INT sign_value = sign_extend_mode_constant (HImode, uns_value); + + if (sign_value == 0) + return "xxspltib %x0,0"; + + if (sign_value == -1) + return "xxspltib %x0,255"; + + int r = reg_or_subregno (operands[0]); + if (ALTIVEC_REGNO_P (r) && EASY_VECTOR_15 (sign_value)) + { + operands[2] = GEN_INT (sign_value); + return "vspltish %0,%1"; + } + + /* The assembler doesn't like negative values. */ + HOST_WIDE_INT new_value = (uns_value << 16) | uns_value; + operands[2] = GEN_INT (zero_extend_mode_constant (SImode, new_value)); + return "xxspltiw %x0,%2"; +} + [(set_attr "type" "vecperm") + (set_attr "prefixed" "*,*,*,yes")]) + +(define_insn "*xxspltiw_v4si_dup" + [(set (match_operand:V4SI 0 "vsx_register_operand" "=wa,wa,v,wa") + (vec_duplicate:V4SI + (match_operand 1 "const_int_operand" "O,wM,wB,n")))] + "TARGET_XXSPLTIW" +{ + HOST_WIDE_INT value = INTVAL (operands[1]); + unsigned HOST_WIDE_INT uns_value = zero_extend_mode_constant (SImode, value); + HOST_WIDE_INT sign_value = sign_extend_mode_constant (SImode, uns_value); + + if (sign_value == 0) + return "xxspltib %x0,0"; + + if (sign_value == -1) + return "xxspltib %x0,255"; + + int r = reg_or_subregno (operands[0]); + if (ALTIVEC_REGNO_P (r) && EASY_VECTOR_15 (sign_value)) + { + operands[2] = GEN_INT (sign_value); + return "vspltisw %0,%2"; + } + + /* The assembler doesn't like negative values. */ + operands[2] = GEN_INT (uns_value); + return "xxspltiw %x0,%2"; +} + [(set_attr "type" "vecperm") + (set_attr "prefixed" "*,*,*,yes")]) + +(define_insn "xxspltiw_v4sf_dup" + [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa,wa") + (vec_duplicate:V4SF + (match_operand:SF 1 "const_double_operand" "O,F")))] + "TARGET_XXSPLTIW" +{ + if (operands[1] == CONST0_RTX (SFmode)) + return "xxspltib %x0,0"; + + /* The assembler doesn't like negative values. */ + long value = rs6000_const_f32_to_i32 (operands[1]); + operands[2] = GEN_INT (zero_extend_mode_constant (SImode, value)); + return "xxspltiw %x0,%2"; +} + [(set_attr "type" "vecsimple") + (set_attr "prefixed" "*,yes")]) + +;; Convert vector constant to vec_duplicate. +(define_mode_iterator XXSPLTIW [V8HI V4SI V4SF]) + +(define_split + [(set (match_operand:XXSPLTIW 0 "vsx_register_operand") + (match_operand:XXSPLTIW 1 "xxspltiw_operand"))] + "TARGET_XXSPLTIW && GET_CODE (operands[1]) == CONST_VECTOR" + [(set (match_dup 0) + (vec_duplicate: (match_dup 2)))] +{ + operands[2] = CONST_VECTOR_ELT (operands[1], 0); +}) diff --git a/gcc/testsuite/gcc.target/powerpc/pr86731-fwrapv.c b/gcc/testsuite/gcc.target/powerpc/pr86731-fwrapv.c index f312550f04d..8a00aaca70d 100644 --- a/gcc/testsuite/gcc.target/powerpc/pr86731-fwrapv.c +++ b/gcc/testsuite/gcc.target/powerpc/pr86731-fwrapv.c @@ -8,6 +8,13 @@ /* { dg-require-effective-target lp64 } */ /* { dg-options "-maltivec -O3 -fwrapv " } */ +/* If the compiler is generating power10 instructions, turn it off. Otherwise, + it will generate a XXSPLTIW instruction instead of LXV/LXVD2X. */ + +#ifdef _ARCH_PWR10 +#pragma GCC target ("cpu=power9") +#endif + #include /* original test as reported. */ vector unsigned int splat(void) diff --git a/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-v4sf.c b/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-v4sf.c new file mode 100644 index 00000000000..06830b02076 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-v4sf.c @@ -0,0 +1,66 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target power10_ok } */ +/* { dg-options "-mdejagnu-cpu=power10 -O2" } */ + +#include + +/* Test whether XXSPLTIW is generated for V4SF vector constants. */ + +vector float +v4sf_const_1 (void) +{ + return (vector float) { 1.0f, 1.0f, 1.0f, 1.0f }; /* XXSPLTIW. */ +} + +vector float +v4sf_const_nan (void) +{ + return (vector float) { __builtin_nanf (""), + __builtin_nanf (""), + __builtin_nanf (""), + __builtin_nanf ("") }; /* XXSPLTIW. */ +} + +vector float +v4sf_const_inf (void) +{ + return (vector float) { __builtin_inff (), + __builtin_inff (), + __builtin_inff (), + __builtin_inff () }; /* XXSPLTIW. */ +} + +vector float +v4sf_const_m0 (void) +{ + return (vector float) { -0.0f, -0.0f, -0.0f, -0.0f }; /* XXSPLTIW. */ +} + +vector float +v4sf_splats_1 (void) +{ + return vec_splats (1.0f); /* XXSPLTIW. */ +} + +vector float +v4sf_splats_nan (void) +{ + return vec_splats (__builtin_nanf ("")); /* XXSPLTIW. */ +} + +vector float +v4sf_splats_inf (void) +{ + return vec_splats (__builtin_inff ()); /* XXSPLTIW. */ +} + +vector float +v8hi_splats_m0 (void) +{ + return vec_splats (-0.0f); /* XXSPLTIW. */ +} + +/* { dg-final { scan-assembler-times {\mxxspltiw\M} 8 } } */ +/* { dg-final { scan-assembler-not {\mxxspltib\M} } } */ +/* { dg-final { scan-assembler-not {\mlxvx?\M} } } */ +/* { dg-final { scan-assembler-not {\mplxv\M} } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-v4si.c b/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-v4si.c new file mode 100644 index 00000000000..02d0c6d66a2 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-v4si.c @@ -0,0 +1,51 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target power10_ok } */ +/* { dg-options "-mdejagnu-cpu=power10 -O2" } */ + +#include + +/* Test whether XXSPLTIW is generated for V4SI vector constants. We make sure + the power9 support (XXSPLTIB/VEXTSB2W) is not done. */ + +vector int +v4si_const_1 (void) +{ + return (vector int) { 1, 1, 1, 1 }; /* VSLTPISW. */ +} + +vector int +v4si_const_126 (void) +{ + return (vector int) { 126, 126, 126, 126 }; /* XXSPLTIW. */ +} + +vector int +v4si_const_1023 (void) +{ + return (vector int) { 1023, 1023, 1023, 1023 }; /* XXSPLTIW. */ +} + +vector int +v4si_splats_1 (void) +{ + return vec_splats (1); /* VSLTPISW. */ +} + +vector int +v4si_splats_126 (void) +{ + return vec_splats (126); /* XXSPLTIW. */ +} + +vector int +v8hi_splats_1023 (void) +{ + return vec_splats (1023); /* XXSPLTIW. */ +} + +/* { dg-final { scan-assembler-times {\mxxspltiw\M} 4 } } */ +/* { dg-final { scan-assembler-times {\mvspltisw\M} 2 } } */ +/* { dg-final { scan-assembler-not {\mxxspltib\M} } } */ +/* { dg-final { scan-assembler-not {\mvextsb2w\M} } } */ +/* { dg-final { scan-assembler-not {\mlxvx?\M} } } */ +/* { dg-final { scan-assembler-not {\mplxv\M} } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-v8hi.c b/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-v8hi.c new file mode 100644 index 00000000000..e6d0fab6d67 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-v8hi.c @@ -0,0 +1,53 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target power10_ok } */ +/* { dg-options "-mdejagnu-cpu=power10 -O2" } */ + +#include + +/* Test whether XXSPLTIW is generated for V8HI vector constants. We make sure + the power9 support (XXSPLTIB/VUPKLSB) is not done. */ + +vector short +v8hi_const_1 (void) +{ + return (vector short) { 1, 1, 1, 1, 1, 1, 1, 1 }; /* VSLTPISH. */ +} + +vector short +v8hi_const_126 (void) +{ + return (vector short) { 126, 126, 126, 126, + 126, 126, 126, 126 }; /* XXSPLTIW. */ +} + +vector short +v8hi_const_1023 (void) +{ + return (vector short) { 1023, 1023, 1023, 1023, + 1023, 1023, 1023, 1023 }; /* XXSPLTIW. */ +} + +vector short +v8hi_splats_1 (void) +{ + return vec_splats ((short)1); /* VSLTPISH. */ +} + +vector short +v8hi_splats_126 (void) +{ + return vec_splats ((short)126); /* XXSPLTIW. */ +} + +vector short +v8hi_splats_1023 (void) +{ + return vec_splats ((short)1023); /* XXSPLTIW. */ +} + +/* { dg-final { scan-assembler-times {\mxxspltiw\M} 4 } } */ +/* { dg-final { scan-assembler-times {\mvspltish\M} 2 } } */ +/* { dg-final { scan-assembler-not {\mxxspltib\M} } } */ +/* { dg-final { scan-assembler-not {\mvupklsb\M} } } */ +/* { dg-final { scan-assembler-not {\mlxvx?\M} } } */ +/* { dg-final { scan-assembler-not {\mplxv\M} } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vec-splati-runnable.c b/gcc/testsuite/gcc.target/powerpc/vec-splati-runnable.c index a135279b1d7..f49ef91422e 100644 --- a/gcc/testsuite/gcc.target/powerpc/vec-splati-runnable.c +++ b/gcc/testsuite/gcc.target/powerpc/vec-splati-runnable.c @@ -149,8 +149,6 @@ main (int argc, char *argv []) return 0; } -/* { dg-final { scan-assembler-times {\mxxspltiw\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mxxspltiw\M} 1 } } */ /* { dg-final { scan-assembler-times {\mxxspltidp\M} 2 } } */ /* { dg-final { scan-assembler-times {\mxxsplti32dx\M} 3 } } */ - -