[llvm] 71079fc - [X86] Move IsElementEquivalent above shuffle comparison helpers. NFC.
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Sun Jun 1 07:06:40 PDT 2025
Author: Simon Pilgrim
Date: 2025-06-01T15:05:44+01:00
New Revision: 71079fcb8e2f3f25bf06740d4bbc498ee075459c
URL: https://github.com/llvm/llvm-project/commit/71079fcb8e2f3f25bf06740d4bbc498ee075459c
DIFF: https://github.com/llvm/llvm-project/commit/71079fcb8e2f3f25bf06740d4bbc498ee075459c.diff
LOG: [X86] Move IsElementEquivalent above shuffle comparison helpers. NFC.
No change - but makes it easier for the shuffle helpers to call IsElementEquivalent.
Added:
Modified:
llvm/lib/Target/X86/X86ISelLowering.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index c5d92d5034e8f..b1a3e3c006bb3 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -9793,6 +9793,93 @@ static SDValue LowerCONCAT_VECTORS(SDValue Op,
// patterns.
//===----------------------------------------------------------------------===//
+/// Checks whether the vector elements referenced by two shuffle masks are
+/// equivalent.
+static bool IsElementEquivalent(int MaskSize, SDValue Op, SDValue ExpectedOp,
+ int Idx, int ExpectedIdx) {
+ assert(0 <= Idx && Idx < MaskSize && 0 <= ExpectedIdx &&
+ ExpectedIdx < MaskSize && "Out of range element index");
+ if (!Op || !ExpectedOp || Op.getOpcode() != ExpectedOp.getOpcode())
+ return false;
+
+ EVT VT = Op.getValueType();
+ switch (Op.getOpcode()) {
+ case ISD::BUILD_VECTOR:
+ // If the values are build vectors, we can look through them to find
+ // equivalent inputs that make the shuffles equivalent.
+ // TODO: Handle MaskSize != Op.getNumOperands()?
+ if (MaskSize == (int)Op.getNumOperands() &&
+ MaskSize == (int)ExpectedOp.getNumOperands())
+ return Op.getOperand(Idx) == ExpectedOp.getOperand(ExpectedIdx);
+ break;
+ case ISD::BITCAST: {
+ SDValue Src = peekThroughBitcasts(Op);
+ EVT SrcVT = Src.getValueType();
+ if (Op == ExpectedOp && SrcVT.isVector() &&
+ (int)VT.getVectorNumElements() == MaskSize) {
+ if ((SrcVT.getScalarSizeInBits() % VT.getScalarSizeInBits()) == 0) {
+ unsigned Scale = SrcVT.getScalarSizeInBits() / VT.getScalarSizeInBits();
+ return (Idx % Scale) == (ExpectedIdx % Scale) &&
+ IsElementEquivalent(SrcVT.getVectorNumElements(), Src, Src,
+ Idx / Scale, ExpectedIdx / Scale);
+ }
+ if ((VT.getScalarSizeInBits() % SrcVT.getScalarSizeInBits()) == 0) {
+ unsigned Scale = VT.getScalarSizeInBits() / SrcVT.getScalarSizeInBits();
+ for (unsigned I = 0; I != Scale; ++I)
+ if (!IsElementEquivalent(SrcVT.getVectorNumElements(), Src, Src,
+ (Idx * Scale) + I,
+ (ExpectedIdx * Scale) + I))
+ return false;
+ return true;
+ }
+ }
+ break;
+ }
+ case ISD::VECTOR_SHUFFLE: {
+ auto *SVN = cast<ShuffleVectorSDNode>(Op);
+ return Op == ExpectedOp && (int)VT.getVectorNumElements() == MaskSize &&
+ SVN->getMaskElt(Idx) == SVN->getMaskElt(ExpectedIdx);
+ }
+ case X86ISD::VBROADCAST:
+ case X86ISD::VBROADCAST_LOAD:
+ // TODO: Handle MaskSize != VT.getVectorNumElements()?
+ return (Op == ExpectedOp && (int)VT.getVectorNumElements() == MaskSize);
+ case X86ISD::SUBV_BROADCAST_LOAD:
+ // TODO: Handle MaskSize != VT.getVectorNumElements()?
+ if (Op == ExpectedOp && (int)VT.getVectorNumElements() == MaskSize) {
+ auto *MemOp = cast<MemSDNode>(Op);
+ unsigned NumMemElts = MemOp->getMemoryVT().getVectorNumElements();
+ return (Idx % NumMemElts) == (ExpectedIdx % NumMemElts);
+ }
+ break;
+ case X86ISD::HADD:
+ case X86ISD::HSUB:
+ case X86ISD::FHADD:
+ case X86ISD::FHSUB:
+ case X86ISD::PACKSS:
+ case X86ISD::PACKUS:
+ // HOP(X,X) can refer to the elt from the lower/upper half of a lane.
+ // TODO: Handle MaskSize != NumElts?
+ // TODO: Handle HOP(X,Y) vs HOP(Y,X) equivalence cases.
+ if (Op == ExpectedOp && Op.getOperand(0) == Op.getOperand(1)) {
+ int NumElts = VT.getVectorNumElements();
+ if (MaskSize == NumElts) {
+ int NumLanes = VT.getSizeInBits() / 128;
+ int NumEltsPerLane = NumElts / NumLanes;
+ int NumHalfEltsPerLane = NumEltsPerLane / 2;
+ bool SameLane =
+ (Idx / NumEltsPerLane) == (ExpectedIdx / NumEltsPerLane);
+ bool SameElt =
+ (Idx % NumHalfEltsPerLane) == (ExpectedIdx % NumHalfEltsPerLane);
+ return SameLane && SameElt;
+ }
+ }
+ break;
+ }
+
+ return false;
+}
+
/// Tiny helper function to identify a no-op mask.
///
/// This is a somewhat boring predicate function. It checks whether the mask
@@ -9968,93 +10055,6 @@ static bool isRepeatedTargetShuffleMask(unsigned LaneSizeInBits, MVT VT,
Mask, RepeatedMask);
}
-/// Checks whether the vector elements referenced by two shuffle masks are
-/// equivalent.
-static bool IsElementEquivalent(int MaskSize, SDValue Op, SDValue ExpectedOp,
- int Idx, int ExpectedIdx) {
- assert(0 <= Idx && Idx < MaskSize && 0 <= ExpectedIdx &&
- ExpectedIdx < MaskSize && "Out of range element index");
- if (!Op || !ExpectedOp || Op.getOpcode() != ExpectedOp.getOpcode())
- return false;
-
- EVT VT = Op.getValueType();
- switch (Op.getOpcode()) {
- case ISD::BUILD_VECTOR:
- // If the values are build vectors, we can look through them to find
- // equivalent inputs that make the shuffles equivalent.
- // TODO: Handle MaskSize != Op.getNumOperands()?
- if (MaskSize == (int)Op.getNumOperands() &&
- MaskSize == (int)ExpectedOp.getNumOperands())
- return Op.getOperand(Idx) == ExpectedOp.getOperand(ExpectedIdx);
- break;
- case ISD::BITCAST: {
- SDValue Src = peekThroughBitcasts(Op);
- EVT SrcVT = Src.getValueType();
- if (Op == ExpectedOp && SrcVT.isVector() &&
- (int)VT.getVectorNumElements() == MaskSize) {
- if ((SrcVT.getScalarSizeInBits() % VT.getScalarSizeInBits()) == 0) {
- unsigned Scale = SrcVT.getScalarSizeInBits() / VT.getScalarSizeInBits();
- return (Idx % Scale) == (ExpectedIdx % Scale) &&
- IsElementEquivalent(SrcVT.getVectorNumElements(), Src, Src,
- Idx / Scale, ExpectedIdx / Scale);
- }
- if ((VT.getScalarSizeInBits() % SrcVT.getScalarSizeInBits()) == 0) {
- unsigned Scale = VT.getScalarSizeInBits() / SrcVT.getScalarSizeInBits();
- for (unsigned I = 0; I != Scale; ++I)
- if (!IsElementEquivalent(SrcVT.getVectorNumElements(), Src, Src,
- (Idx * Scale) + I,
- (ExpectedIdx * Scale) + I))
- return false;
- return true;
- }
- }
- break;
- }
- case ISD::VECTOR_SHUFFLE: {
- auto *SVN = cast<ShuffleVectorSDNode>(Op);
- return Op == ExpectedOp && (int)VT.getVectorNumElements() == MaskSize &&
- SVN->getMaskElt(Idx) == SVN->getMaskElt(ExpectedIdx);
- }
- case X86ISD::VBROADCAST:
- case X86ISD::VBROADCAST_LOAD:
- // TODO: Handle MaskSize != VT.getVectorNumElements()?
- return (Op == ExpectedOp && (int)VT.getVectorNumElements() == MaskSize);
- case X86ISD::SUBV_BROADCAST_LOAD:
- // TODO: Handle MaskSize != VT.getVectorNumElements()?
- if (Op == ExpectedOp && (int)VT.getVectorNumElements() == MaskSize) {
- auto *MemOp = cast<MemSDNode>(Op);
- unsigned NumMemElts = MemOp->getMemoryVT().getVectorNumElements();
- return (Idx % NumMemElts) == (ExpectedIdx % NumMemElts);
- }
- break;
- case X86ISD::HADD:
- case X86ISD::HSUB:
- case X86ISD::FHADD:
- case X86ISD::FHSUB:
- case X86ISD::PACKSS:
- case X86ISD::PACKUS:
- // HOP(X,X) can refer to the elt from the lower/upper half of a lane.
- // TODO: Handle MaskSize != NumElts?
- // TODO: Handle HOP(X,Y) vs HOP(Y,X) equivalence cases.
- if (Op == ExpectedOp && Op.getOperand(0) == Op.getOperand(1)) {
- int NumElts = VT.getVectorNumElements();
- if (MaskSize == NumElts) {
- int NumLanes = VT.getSizeInBits() / 128;
- int NumEltsPerLane = NumElts / NumLanes;
- int NumHalfEltsPerLane = NumEltsPerLane / 2;
- bool SameLane =
- (Idx / NumEltsPerLane) == (ExpectedIdx / NumEltsPerLane);
- bool SameElt =
- (Idx % NumHalfEltsPerLane) == (ExpectedIdx % NumHalfEltsPerLane);
- return SameLane && SameElt;
- }
- }
- break;
- }
-
- return false;
-}
-
/// Checks whether a shuffle mask is equivalent to an explicit list of
/// arguments.
///
More information about the llvm-commits
mailing list