https://gcc.gnu.org/g:5cc5c90f5a2d0130277991b843bec930c66fbade
commit 5cc5c90f5a2d0130277991b843bec930c66fbade Author: Michael Meissner <meiss...@linux.ibm.com> Date: Thu Mar 27 21:14:13 2025 -0400 Add potential p-future XVRLD and XVRLDI instructions. 2025-03-27 Michael Meissner <meiss...@linux.ibm.com> gcc/ * config/rs6000/altivec.md (altivec_vrl<VI_char>): Add support for a possible XVRLD instruction in the future. (altivec_vrl<VI_char>_immediate): New insns. * config/rs6000/predicates.md (vector_shift_immediate): New predicate. * config/rs6000/rs6000.h (TARGET_XVRLW): New macro. * config/rs6000/rs6000.md (isa attribute): Add xvrlw. (enabled attribute): Add support for xvrlw. gcc/testsuite/ * gcc.target/powerpc/vector-rotate-left.c: New test. * lib/target-supports.exp (check_effective_target_powerpc_future_ok): Add support to test -mcpu=future. Diff: --- gcc/config/rs6000/altivec.md | 35 +++++++++++++++++++--- gcc/config/rs6000/predicates.md | 26 ++++++++++++++++ gcc/config/rs6000/rs6000.h | 3 ++ gcc/config/rs6000/rs6000.md | 6 +++- .../gcc.target/powerpc/vector-rotate-left.c | 34 +++++++++++++++++++++ gcc/testsuite/lib/target-supports.exp | 12 ++++++++ 6 files changed, 111 insertions(+), 5 deletions(-) diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md index 7edc288a6565..013960438b04 100644 --- a/gcc/config/rs6000/altivec.md +++ b/gcc/config/rs6000/altivec.md @@ -1982,12 +1982,39 @@ } [(set_attr "type" "vecperm")]) +;; -mcpu=future adds a vector rotate left word variant. There is no vector +;; byte/half-word/double-word/quad-word rotate left. This insn occurs before +;; altivec_vrl<VI_char> and will match for -mcpu=future, while other cpus will +;; match the generic insn. +;; However for testing, allow other xvrl variants. In particular, XVRLD for +;; the sha3 tests for multibuf/singlebuf. (define_insn "altivec_vrl<VI_char>" - [(set (match_operand:VI2 0 "register_operand" "=v") - (rotate:VI2 (match_operand:VI2 1 "register_operand" "v") - (match_operand:VI2 2 "register_operand" "v")))] + [(set (match_operand:VI2 0 "register_operand" "=v,wa") + (rotate:VI2 (match_operand:VI2 1 "register_operand" "v,wa") + (match_operand:VI2 2 "register_operand" "v,wa")))] "<VI_unit>" - "vrl<VI_char> %0,%1,%2" + "@ + vrl<VI_char> %0,%1,%2 + xvrl<VI_char> %x0,%x1,%x2" + [(set_attr "type" "vecsimple") + (set_attr "isa" "*,xvrlw")]) + +(define_insn "*altivec_vrl<VI_char>_immediate" + [(set (match_operand:VI2 0 "register_operand" "=wa,wa,wa,wa") + (rotate:VI2 (match_operand:VI2 1 "register_operand" "wa,wa,wa,wa") + (match_operand:VI2 2 "vector_shift_immediate" "j,wM,wE,wS")))] + "TARGET_XVRLW && <VI_unit>" +{ + rtx op2 = operands[2]; + int value = 256; + int num_insns = -1; + + if (!xxspltib_constant_p (op2, <MODE>mode, &num_insns, &value)) + gcc_unreachable (); + + operands[3] = GEN_INT (value & 0xff); + return "xvrl<VI_char>i %x0,%x1,%3"; +} [(set_attr "type" "vecsimple")]) (define_insn "altivec_vrlq" diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 6485ee3eeecc..276812573977 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -728,6 +728,32 @@ return num_insns == 1; }) +;; Return 1 if the operand is a CONST_VECTOR whose elements are all the +;; same and the elements can be an immediate shift or rotate factor +(define_predicate "vector_shift_immediate" + (match_code "const_vector,vec_duplicate,const_int") +{ + int value = 256; + int num_insns = -1; + + if (zero_constant (op, mode) || all_ones_constant (op, mode)) + return true; + + if (!xxspltib_constant_p (op, mode, &num_insns, &value)) + return false; + + switch (mode) + { + case V16QImode: return IN_RANGE (value, 0, 7); + case V8HImode: return IN_RANGE (value, 0, 15); + case V4SImode: return IN_RANGE (value, 0, 31); + case V2DImode: return IN_RANGE (value, 0, 63); + default: break; + } + + return false; +}) + ;; 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" diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 9267612fbc9c..d414bc539207 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -575,6 +575,9 @@ extern int rs6000_vector_align[]; below. */ #define RS6000_FN_TARGET_INFO_HTM 1 +/* Whether we have XVRLW support. */ +#define TARGET_XVRLW TARGET_FUTURE + /* Whether the various reciprocal divide/square root estimate instructions exist, and whether we should automatically generate code for the instruction by default. */ diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 3b876462ec32..e7927b88eaf8 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -369,7 +369,7 @@ (const (symbol_ref "(enum attr_cpu) rs6000_tune"))) ;; The ISA we implement. -(define_attr "isa" "any,p5,p6,p7,p7v,p8,p8v,p9,p9v,p9kf,p9tf,p10,xxeval" +(define_attr "isa" "any,p5,p6,p7,p7v,p8,p8v,p9,p9v,p9kf,p9tf,p10,xxeval,xvrlw" (const_string "any")) ;; Is this alternative enabled for the current CPU/ISA/etc.? @@ -426,6 +426,10 @@ (match_test "TARGET_PREFIXED && TARGET_XXEVAL")) (const_int 1) + (and (eq_attr "isa" "xvrlw") + (match_test "TARGET_XVRLW")) + (const_int 1) + ] (const_int 0))) ;; If this instruction is microcoded on the CELL processor diff --git a/gcc/testsuite/gcc.target/powerpc/vector-rotate-left.c b/gcc/testsuite/gcc.target/powerpc/vector-rotate-left.c new file mode 100644 index 000000000000..5a5f37755077 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vector-rotate-left.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_future_ok } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-mdejagnu-cpu=future -O2" } */ + +/* Test whether the xvrl (vector word rotate left using VSX registers insead of + Altivec registers is generated. */ + +#include <altivec.h> + +typedef vector unsigned int v4si_t; + +v4si_t +rotl_v4si_scalar (v4si_t x, unsigned long n) +{ + __asm__ (" # %x0" : "+f" (x)); + return (x << n) | (x >> (32 - n)); /* xvrlw. */ +} + +v4si_t +rotr_v4si_scalar (v4si_t x, unsigned long n) +{ + __asm__ (" # %x0" : "+f" (x)); + return (x >> n) | (x << (32 - n)); /* xvrlw. */ +} + +v4si_t +rotl_v4si_vector (v4si_t x, v4si_t y) +{ + __asm__ (" # %x0" : "+f" (x)); /* xvrlw. */ + return vec_rl (x, y); +} + +/* { dg-final { scan-assembler-times {\mxvrlw\M} 3 } } */ diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index ee4138aa6971..a3ce3f2d875e 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -7645,6 +7645,18 @@ proc check_effective_target_power10_ok { } { } } +# Return 1 if this is a PowerPC target supporting -mcpu=future which enables +# some potential new instructions. +proc check_effective_target_powerpc_future_ok { } { + return [check_no_compiler_messages powerpc_future_ok object { + #ifndef _ARCH_PWR_FUTURE + #error "-mcpu=future is not supported" + #else + int dummy; + #endif + } "-mcpu=future"] +} + # Return 1 if this is a PowerPC target supporting -mfloat128 via either # software emulation on power7/power8 systems or hardware support on power9.