[llvm] [X86] Make ISD::ROTL/ROTR vXi16 vector rotates legal on VBMI2 targets (PR #184768)
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 6 01:04:07 PST 2026
https://github.com/RKSimon updated https://github.com/llvm/llvm-project/pull/184768
>From 921197861f5a904af4f25d6a3d442e7a2b5f4ac6 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Thu, 5 Mar 2026 10:46:20 +0000
Subject: [PATCH 1/2] [X86] Make ISD::ROTL/ROTR vXi16 vector rotates legal on
VBMI2 targets
Move funnel shift expansion to tablegen - allows late folding to rotate nodes, reduces multiuse issues and will make future GlobalISel support easier.
Fixes #184002
---
llvm/lib/Target/X86/X86ISelLowering.cpp | 15 ++++----
llvm/lib/Target/X86/X86InstrAVX512.td | 49 +++++++++++++++++++++++++
2 files changed, 56 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 6bb558f4ef6da..b0f0d4882b397 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -2134,8 +2134,8 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
setOperationAction(ISD::FSHR, VT, Legal);
}
- setOperationAction(ISD::ROTL, MVT::v32i16, Custom);
- setOperationAction(ISD::ROTR, MVT::v32i16, Custom);
+ setOperationAction(ISD::ROTL, MVT::v32i16, Legal);
+ setOperationAction(ISD::ROTR, MVT::v32i16, Legal);
}
// Only PCLMUL required as we always unroll clmul vectors.
@@ -2162,6 +2162,11 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
setOperationAction(ISD::FSHL, VT, Legal);
setOperationAction(ISD::FSHR, VT, Legal);
}
+
+ setOperationAction(ISD::ROTL, MVT::v16i16, Legal);
+ setOperationAction(ISD::ROTR, MVT::v16i16, Legal);
+ setOperationAction(ISD::ROTL, MVT::v8i16, Legal);
+ setOperationAction(ISD::ROTR, MVT::v8i16, Legal);
}
// This block controls legalization for operations that don't have
@@ -31932,12 +31937,6 @@ static SDValue LowerRotate(SDValue Op, const X86Subtarget &Subtarget,
if (IsCstSplat && CstSplatValue.urem(EltSizeInBits) == 0)
return R;
- // AVX512 VBMI2 vXi16 - lower to funnel shifts.
- if (Subtarget.hasVBMI2() && 16 == EltSizeInBits) {
- unsigned FunnelOpc = IsROTL ? ISD::FSHL : ISD::FSHR;
- return DAG.getNode(FunnelOpc, DL, VT, R, R, Amt);
- }
-
SDValue Z = DAG.getConstant(0, DL, VT);
if (!IsROTL) {
diff --git a/llvm/lib/Target/X86/X86InstrAVX512.td b/llvm/lib/Target/X86/X86InstrAVX512.td
index 3b456aee7fceb..e15d97e97492e 100644
--- a/llvm/lib/Target/X86/X86InstrAVX512.td
+++ b/llvm/lib/Target/X86/X86InstrAVX512.td
@@ -12495,6 +12495,55 @@ let Predicates = [HasVBMI2, NoVLX] in {
defm : vbmi2_funnel_novlx<v32i16_info, v8i16x_info, VPSHRDWZrri, X86VShrd, VPSHRDVWZr, fshr, 1>;
}
+// Use VPSHLD/VPSHRD to implement rotations.
+multiclass vbmi2_rotate<X86VectorVTInfo _, Instruction InstrStrRI, SDNode OpNodeRI,
+ Instruction InstrStrRR, SDNode OpNodeRR> {
+ def : Pat<(_.VT (OpNodeRI (_.VT _.RC:$src1), (i8 timm:$src2))),
+ (InstrStrRI (_.VT _.RC:$src1), (_.VT _.RC:$src1), timm:$src2)>;
+
+ def : Pat<(_.VT (OpNodeRR (_.VT _.RC:$src1), (_.VT _.RC:$src2))),
+ (InstrStrRR (_.VT _.RC:$src1), (_.VT _.RC:$src1), (_.VT _.RC:$src2))>;
+}
+
+let Predicates = [HasVBMI2] in {
+ defm : vbmi2_rotate<v32i16_info, VPSHLDWZrri, X86vrotli, VPSHLDVWZr, rotl>;
+ defm : vbmi2_rotate<v32i16_info, VPSHRDWZrri, X86vrotri, VPSHRDVWZr, rotr>;
+}
+
+let Predicates = [HasVBMI2, HasVLX] in {
+ defm : vbmi2_rotate<v16i16x_info, VPSHLDWZ256rri, X86vrotli, VPSHLDVWZ256r, rotl>;
+ defm : vbmi2_rotate<v16i16x_info, VPSHRDWZ256rri, X86vrotri, VPSHRDVWZ256r, rotr>;
+ defm : vbmi2_rotate<v8i16x_info, VPSHLDWZ128rri, X86vrotli, VPSHLDVWZ128r, rotl>;
+ defm : vbmi2_rotate<v8i16x_info, VPSHRDWZ128rri, X86vrotri, VPSHRDVWZ128r, rotr>;
+}
+
+multiclass vbmi2_rotate_novlx<X86VectorVTInfo Dst, X86VectorVTInfo Src,
+ Instruction InstrStrRI, SDNode OpNodeRI,
+ Instruction InstrStrRR, SDNode OpNodeRR> {
+ def : Pat<(Src.VT (OpNodeRI (Src.VT Src.RC:$src1), (i8 timm:$src2))),
+ (EXTRACT_SUBREG
+ (InstrStrRI
+ (INSERT_SUBREG (Dst.VT (IMPLICIT_DEF)), Src.RC:$src1, Src.SubRegIdx),
+ (INSERT_SUBREG (Dst.VT (IMPLICIT_DEF)), Src.RC:$src1, Src.SubRegIdx),
+ timm:$src2),
+ Src.SubRegIdx)>;
+
+ def : Pat<(Src.VT (OpNodeRR (Src.VT Src.RC:$src1), (Src.VT Src.RC:$src2))),
+ (EXTRACT_SUBREG
+ (InstrStrRR
+ (INSERT_SUBREG (Dst.VT (IMPLICIT_DEF)), Src.RC:$src1, Src.SubRegIdx),
+ (INSERT_SUBREG (Dst.VT (IMPLICIT_DEF)), Src.RC:$src1, Src.SubRegIdx),
+ (INSERT_SUBREG (Dst.VT (IMPLICIT_DEF)), Src.RC:$src2, Src.SubRegIdx)),
+ Src.SubRegIdx)>;
+}
+
+let Predicates = [HasVBMI2, NoVLX] in {
+ defm : vbmi2_rotate_novlx<v32i16_info, v16i16x_info, VPSHLDWZrri, X86vrotli, VPSHLDVWZr, rotl>;
+ defm : vbmi2_rotate_novlx<v32i16_info, v16i16x_info, VPSHRDWZrri, X86vrotri, VPSHRDVWZr, rotr>;
+ defm : vbmi2_rotate_novlx<v32i16_info, v8i16x_info, VPSHLDWZrri, X86vrotli, VPSHLDVWZr, rotl>;
+ defm : vbmi2_rotate_novlx<v32i16_info, v8i16x_info, VPSHRDWZrri, X86vrotri, VPSHRDVWZr, rotr>;
+}
+
//===----------------------------------------------------------------------===//
// VNNI
//===----------------------------------------------------------------------===//
>From f19ddc480237dae169591c2ec1d77796c791c851 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Fri, 6 Mar 2026 09:03:48 +0000
Subject: [PATCH 2/2] indentation
---
llvm/lib/Target/X86/X86InstrAVX512.td | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/X86/X86InstrAVX512.td b/llvm/lib/Target/X86/X86InstrAVX512.td
index e15d97e97492e..35e424a1879f3 100644
--- a/llvm/lib/Target/X86/X86InstrAVX512.td
+++ b/llvm/lib/Target/X86/X86InstrAVX512.td
@@ -12497,7 +12497,7 @@ let Predicates = [HasVBMI2, NoVLX] in {
// Use VPSHLD/VPSHRD to implement rotations.
multiclass vbmi2_rotate<X86VectorVTInfo _, Instruction InstrStrRI, SDNode OpNodeRI,
- Instruction InstrStrRR, SDNode OpNodeRR> {
+ Instruction InstrStrRR, SDNode OpNodeRR> {
def : Pat<(_.VT (OpNodeRI (_.VT _.RC:$src1), (i8 timm:$src2))),
(InstrStrRI (_.VT _.RC:$src1), (_.VT _.RC:$src1), timm:$src2)>;
More information about the llvm-commits
mailing list