[llvm] 44c4c02 - [X86] Move PSHUF(SHIFT(X,C0),C1) -> SHIFT(PSHUF(X,C1),C0) to canonicalizeShuffleWithOp (#225313)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 22 00:50:13 PDT 2026
Author: Simon Pilgrim
Date: 2026-09-22T07:50:07Z
New Revision: 44c4c0220a09a1468c04d9d8319197a078dfbe3b
URL: https://github.com/llvm/llvm-project/commit/44c4c0220a09a1468c04d9d8319197a078dfbe3b
DIFF: https://github.com/llvm/llvm-project/commit/44c4c0220a09a1468c04d9d8319197a078dfbe3b.diff
LOG: [X86] Move PSHUF(SHIFT(X,C0),C1) -> SHIFT(PSHUF(X,C1),C0) to canonicalizeShuffleWithOp (#225313)
No need for this to be in combineTargetShuffle, and we can generalize it
to work with more shuffles in a future patch.
Added:
Modified:
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/test/CodeGen/X86/vector-sext.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 508464c7b4125..c8c58a310604d 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -43224,18 +43224,48 @@ static SDValue canonicalizeShuffleWithOp(SDValue N, SelectionDAG &DAG,
DAG.getBitcast(OpVT, RHS)));
}
}
- if (SrcOpcode == ISD::SINT_TO_FP && IsSafeToMoveShuffle(N0, SrcOpcode) &&
- OpVT.getScalarSizeInBits() ==
- N0.getOperand(0).getScalarValueSizeInBits()) {
- SDValue Res = DAG.getBitcast(ShuffleVT, N0.getOperand(0));
- if (Opc == X86ISD::VPERMV)
- Res = DAG.getNode(Opc, DL, ShuffleVT, N.getOperand(0), Res);
- else if (N.getNumOperands() == 2)
- Res = DAG.getNode(Opc, DL, ShuffleVT, Res, N.getOperand(1));
- else
- Res = DAG.getNode(Opc, DL, ShuffleVT, Res);
- Res = DAG.getBitcast(N0.getOperand(0).getValueType(), Res);
- return DAG.getBitcast(ShuffleVT, DAG.getNode(SrcOpcode, DL, OpVT, Res));
+ switch (SrcOpcode) {
+ case ISD::SINT_TO_FP:
+ if (IsSafeToMoveShuffle(N0, SrcOpcode) &&
+ OpVT.getScalarSizeInBits() ==
+ N0.getOperand(0).getScalarValueSizeInBits()) {
+ SDValue Res = DAG.getBitcast(ShuffleVT, N0.getOperand(0));
+ if (Opc == X86ISD::VPERMV)
+ Res = DAG.getNode(Opc, DL, ShuffleVT, N.getOperand(0), Res);
+ else if (N.getNumOperands() == 2)
+ Res = DAG.getNode(Opc, DL, ShuffleVT, Res, N.getOperand(1));
+ else
+ Res = DAG.getNode(Opc, DL, ShuffleVT, Res);
+ Res = DAG.getBitcast(N0.getOperand(0).getValueType(), Res);
+ return DAG.getBitcast(ShuffleVT,
+ DAG.getNode(SrcOpcode, DL, OpVT, Res));
+ }
+ break;
+ case X86ISD::VSHL:
+ case X86ISD::VSRL:
+ case X86ISD::VSRA:
+ case X86ISD::VSHLI:
+ case X86ISD::VSRLI:
+ case X86ISD::VSRAI:
+ case X86ISD::VROTLI:
+ case X86ISD::VROTRI:
+ // Move shuffle through shifts as it might help load folding.
+ // TODO: Relax shuffle constraint.
+ if ((Opc == X86ISD::PSHUFD || Opc == X86ISD::PSHUFLW ||
+ Opc == X86ISD::PSHUFHW) &&
+ IsSafeToMoveShuffle(N0, SrcOpcode)) {
+ SDValue Res = DAG.getBitcast(ShuffleVT, N0.getOperand(0));
+ if (Opc == X86ISD::VPERMV)
+ Res = DAG.getNode(Opc, DL, ShuffleVT, N.getOperand(0), Res);
+ else if (N.getNumOperands() == 2)
+ Res = DAG.getNode(Opc, DL, ShuffleVT, Res, N.getOperand(1));
+ else
+ Res = DAG.getNode(Opc, DL, ShuffleVT, Res);
+ Res = DAG.getBitcast(N0.getOperand(0).getValueType(), Res);
+ return DAG.getBitcast(ShuffleVT, DAG.getNode(SrcOpcode, DL, OpVT, Res,
+ N0.getOperand(1)));
+ }
+ break;
}
}
break;
@@ -44018,32 +44048,6 @@ static SDValue combineTargetShuffle(SDValue N, const SDLoc &DL,
case X86ISD::PSHUFD:
case X86ISD::PSHUFLW:
case X86ISD::PSHUFHW: {
- SDValue N0 = N.getOperand(0);
- SDValue N1 = N.getOperand(1);
- if (N0->hasOneUse()) {
- SDValue V = peekThroughOneUseBitcasts(N0);
- switch (V.getOpcode()) {
- case X86ISD::VSHL:
- case X86ISD::VSRL:
- case X86ISD::VSRA:
- case X86ISD::VSHLI:
- case X86ISD::VSRLI:
- case X86ISD::VSRAI:
- case X86ISD::VROTLI:
- case X86ISD::VROTRI: {
- MVT InnerVT = V.getSimpleValueType();
- if (InnerVT.getScalarSizeInBits() <= VT.getScalarSizeInBits()) {
- SDValue Res = DAG.getNode(Opcode, DL, VT,
- DAG.getBitcast(VT, V.getOperand(0)), N1);
- Res = DAG.getBitcast(InnerVT, Res);
- Res = DAG.getNode(V.getOpcode(), DL, InnerVT, Res, V.getOperand(1));
- return DAG.getBitcast(VT, Res);
- }
- break;
- }
- }
- }
-
Mask = getPSHUFShuffleMask(N);
assert(Mask.size() == 4);
break;
diff --git a/llvm/test/CodeGen/X86/vector-sext.ll b/llvm/test/CodeGen/X86/vector-sext.ll
index 95f9b71d70376..11d503f82d0dc 100644
--- a/llvm/test/CodeGen/X86/vector-sext.ll
+++ b/llvm/test/CodeGen/X86/vector-sext.ll
@@ -1827,10 +1827,10 @@ define <4 x i64> @load_sext_4i1_to_4i64(ptr%ptr) {
; SSE41-NEXT: shrb $2, %cl
; SSE41-NEXT: andb $1, %cl
; SSE41-NEXT: movzbl %cl, %ecx
+; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm1[0,0,1,1]
; SSE41-NEXT: pinsrb $8, %ecx, %xmm1
; SSE41-NEXT: shrb $3, %al
; SSE41-NEXT: movzbl %al, %eax
-; SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm1[0,0,1,1]
; SSE41-NEXT: pinsrb $12, %eax, %xmm1
; SSE41-NEXT: pslld $31, %xmm0
; SSE41-NEXT: psrad $31, %xmm0
@@ -1957,10 +1957,10 @@ define <4 x i64> @load_sext_4i1_to_4i64(ptr%ptr) {
; X86-SSE41-NEXT: shrb $2, %cl
; X86-SSE41-NEXT: andb $1, %cl
; X86-SSE41-NEXT: movzbl %cl, %ecx
+; X86-SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm1[0,0,1,1]
; X86-SSE41-NEXT: pinsrb $8, %ecx, %xmm1
; X86-SSE41-NEXT: shrb $3, %al
; X86-SSE41-NEXT: movzbl %al, %eax
-; X86-SSE41-NEXT: pshufd {{.*#+}} xmm0 = xmm1[0,0,1,1]
; X86-SSE41-NEXT: pinsrb $12, %eax, %xmm1
; X86-SSE41-NEXT: pslld $31, %xmm0
; X86-SSE41-NEXT: psrad $31, %xmm0
More information about the llvm-commits
mailing list