[llvm] [AMDGPU][X86][DAG] Avoid duplicate BinOp result from narrowing insert-extract sub-vector (PR #201056)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 29 05:48:38 PDT 2026
================
@@ -27267,36 +27295,106 @@ static SDValue narrowInsertExtractVectorBinOp(EVT SubVT, SDValue BinOp,
EVT VecVT = BinOp.getValueType();
SDValue Bop0 = BinOp.getOperand(0), Bop1 = BinOp.getOperand(1);
- if (VecVT != Bop0.getValueType() || VecVT != Bop1.getValueType())
+ if (VecVT != Bop0.getValueType() || VecVT != Bop1.getValueType() ||
+ VecVT.isScalableVT())
return SDValue();
- if (!TLI.isOperationLegalOrCustom(BinOpcode, SubVT, LegalOperations))
+
+ // This fold only pays off when the wide binop disappears completely, so every
+ // user must be an extract_subvector. Require them all to extract N's type so
+ // a single chain scan serves every extract, and seed the source map by index.
+ EVT SubVT = N->getValueType(0);
+ if (VecVT.getSizeInBits() <= SubVT.getSizeInBits())
return SDValue();
- SDValue Sub0 = getSubVectorSrc(Bop0, Index, SubVT);
- SDValue Sub1 = getSubVectorSrc(Bop1, Index, SubVT);
+ SmallMapVector<unsigned, std::tuple<SDNode *, SDValue, SDValue>, 4> Extracts;
+ // Scan each wide operand's chain once, filling the seeded indices' sources.
+ collectSubVectorSrcs(Bop0, SubVT, /*OpNo=*/0, Extracts);
+ collectSubVectorSrcs(Bop1, SubVT, /*OpNo=*/1, Extracts);
+
+ bool HasNonZeroExt = false;
+ bool HasNonExtUser = false;
+ for (SDNode *User : BinOp->users()) {
+ if (User->getOpcode() != ISD::EXTRACT_SUBVECTOR) {
+ HasNonExtUser = true;
+ continue;
+ }
+ if (User->getValueType(0) != SubVT ||
+ (User->getCombinerWorklistIndex() < 0 && User != N))
+ return SDValue();
+ unsigned Idx = User->getConstantOperandVal(1);
+ auto It = Extracts.find(Idx);
+ if (It == Extracts.end() || !std::get<1>(It->second) ||
+ !std::get<2>(It->second))
+ return SDValue();
+ SDNode *&ExtSubVec = std::get<0>(It->second);
+ if (!ExtSubVec) {
+ ExtSubVec = User;
+ if (Idx != 0)
+ HasNonZeroExt = true;
+ }
+ }
- // TODO: We could handle the case where only 1 operand is being inserted by
- // creating an extract of the other operand, but that requires checking
- // number of uses and/or costs.
- if (!Sub0 || !Sub1)
+ if (!TLI.isOperationLegalOrCustom(BinOpcode, SubVT, LegalOperations))
----------------
arsenm wrote:
This check should be before the user scan
https://github.com/llvm/llvm-project/pull/201056
More information about the llvm-commits
mailing list