[llvm] [AMDGPU] Legalize 64bit elements for BUILD_VECTOR on gfx942 (PR #145052)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 30 03:50:36 PDT 2025
================
@@ -15896,6 +15936,92 @@ SDValue SITargetLowering::performClampCombine(SDNode *N,
return SDValue(CSrc, 0);
}
+SDValue
+SITargetLowering::performBuildVectorCombine(SDNode *N,
+ DAGCombinerInfo &DCI) const {
+ const GCNSubtarget *ST = getSubtarget();
+ if (DCI.Level < AfterLegalizeDAG || !ST->hasMovB64())
+ return SDValue();
+
+ SelectionDAG &DAG = DCI.DAG;
+ SDLoc SL(N);
+
+ EVT VT = N->getValueType(0);
+ EVT EltVT = VT.getVectorElementType();
+ unsigned SizeBits = VT.getSizeInBits();
+ unsigned EltSize = EltVT.getSizeInBits();
+
+ // Skip if:
+ // - Value type isn't multiple of 64 bit (e.g., v3i32), or
+ // - Element type has already been combined into 64b elements
+ if ((SizeBits % 64) != 0 || EltVT == MVT::i64 || EltVT == MVT::f64)
+ return SDValue();
+
+ // Construct the 64b values.
+ SmallVector<uint64_t, 8> ImmVals;
+ uint64_t ImmVal = 0;
+ uint64_t ImmSize = 0;
+ for (SDValue Opand : N->ops()) {
+ // Build_vector with constants only.
+ ConstantSDNode *C = dyn_cast<ConstantSDNode>(Opand);
+ ConstantFPSDNode *FPC = dyn_cast<ConstantFPSDNode>(Opand);
+ BuildVectorSDNode *BV =
+ dyn_cast<BuildVectorSDNode>(peekThroughBitcasts(Opand));
+
+ if (!C && !FPC && !BV)
+ return SDValue();
+
+ uint64_t Val = 0;
+ if (BV) {
+ if (!BV->isConstant())
+ return SDValue();
+ bool IsLE = DAG.getDataLayout().isLittleEndian();
+ BitVector UndefElements;
+ SmallVector<APInt> RawBits;
+ if (!BV->getConstantRawBits(IsLE, EltSize, RawBits, UndefElements))
+ return SDValue();
+
+ assert(RawBits.size() == 1 &&
+ "BuildVector constant value retrieval expected 1 element");
+
+ if (UndefElements.any())
+ return SDValue();
+
+ Val = RawBits[0].getZExtValue();
+ } else
+ Val = C ? C->getZExtValue()
+ : FPC->getValueAPF().bitcastToAPInt().getZExtValue();
+ ImmVal |= Val << ImmSize;
+ ImmSize += EltSize;
+ if (ImmSize == 64) {
+ if (!isUInt<32>(ImmVal))
+ return SDValue();
+ ImmVals.push_back(ImmVal);
+ ImmVal = 0;
+ ImmSize = 0;
+ }
+ }
+
+ // Avoid emitting build_vector with 1 element and directly emit value.
+ if (ImmVals.size() == 1) {
+ SDValue Val = DAG.getConstant(ImmVals[0], SL, MVT::i64);
+ return DAG.getBitcast(VT, Val);
+ }
+
+ // Construct and return build_vector with 64b elements.
+ if (!ImmVals.empty()) {
+ SmallVector<SDValue, 8> VectorConsts;
+ for (uint64_t I : ImmVals)
+ VectorConsts.push_back(DAG.getConstant(I, SL, MVT::i64));
----------------
arsenm wrote:
Size the vector to start and avoid push_back in loop
https://github.com/llvm/llvm-project/pull/145052
More information about the llvm-commits
mailing list