[llvm] [X86][DAGCombiner][SelectionDAG] - Fold Zext Build Vector to Bitcast of widen Build Vector (PR #135010)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 18 03:32:40 PDT 2025
================
@@ -14195,6 +14195,66 @@ static SDValue widenAbs(SDNode *Extend, SelectionDAG &DAG) {
return DAG.getZExtOrTrunc(NewAbs, SDLoc(Extend), VT);
}
+// Try to widen the build vector and bitcast it to the type of zext.
+// This is a special case for the 128-bit vector types. Intention is to remove
+// the zext and replace it with a bitcast the wider type. While lowering
+// the bitcast is removed and extra commutation due to zext is avoided.
+static SDValue widenBuildVec(SDNode *Extend, SelectionDAG &DAG) {
+
+ assert(Extend->getOpcode() == ISD::ZERO_EXTEND && "Expected zero extend.");
+
+ EVT ExtendVT = Extend->getValueType(0);
+
+ SDValue BV = Extend->getOperand(0);
+ if (BV.getOpcode() != ISD::BUILD_VECTOR || !BV.hasOneUse())
+ return SDValue();
+
+ SDLoc dl(BV);
+ EVT VT = BV.getValueType();
+ EVT EltVT = BV.getOperand(0).getValueType();
+ unsigned NumElts = VT.getVectorNumElements();
+
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+
+ if (TLI.getTypeAction(*DAG.getContext(), VT) !=
+ TargetLowering::TypeWidenVector)
+ return SDValue();
+
+ EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
+ unsigned WidenNumElts = WidenVT.getVectorNumElements();
+
+ SmallVector<SDValue, 16> NewOps(BV->op_begin(), BV->op_end());
+ assert(WidenNumElts >= NumElts && "Shrinking vector instead of widening!");
+ // Fill the new elements with Zero.
+ NewOps.append(WidenNumElts - NumElts, DAG.getConstant(0, dl, EltVT));
+ // Compute the step to place the elements in the right place and control the
+ // iteration.
+ unsigned step = WidenNumElts / NumElts;
+ if (WidenVT.is128BitVector()) {
+ if (step > 1 && Extend->getValueSizeInBits(0) == WidenVT.getSizeInBits()) {
+ for (int i = NumElts - 1, j = WidenNumElts - step; i > 0;
+ i--, j -= step) {
+ SDValue temp = NewOps[i];
+ NewOps[i] = NewOps[j];
+ NewOps[j] = temp;
+ }
+ // Create new build vector with WidenVT and NewOps
+ SDValue NewBV = DAG.getBuildVector(WidenVT, dl, NewOps);
+ // Replace the old build vector with the new one. Bitcast the
+ // new build vector to the type of the zext.
+ SDValue NewBVBitcast = DAG.getBitcast(ExtendVT, NewBV);
+ DAG.ReplaceAllUsesOfValueWith(SDValue(Extend, 0), NewBVBitcast);
+ LLVM_DEBUG(
+ dbgs() << DAG.getMachineFunction().getFunction().getName()
+ << " - Widening buildvector and replace zext with bitcast\n";
+ BV.dump(); Extend->dump(); dbgs() << " to \n";
+ NewBV.getNode()->dump(); NewBVBitcast->dump(););
----------------
arsenm wrote:
I would remove this whole debug print. You should see the transform triggered in the generic dag combine case. You aslo don't need all of the manual dumping, you can directly use operator<<
https://github.com/llvm/llvm-project/pull/135010
More information about the llvm-commits
mailing list