[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
Fri Jul 17 05:12:47 PDT 2026


================
@@ -27429,25 +27430,65 @@ SDValue DAGCombiner::visitVECTOR_INTERLEAVE(SDNode *N) {
   return CombineTo(N, &Ops);
 }
 
-// Helper that peeks through INSERT_SUBVECTOR/CONCAT_VECTORS to find
-// if the subvector can be sourced for free.
-static SDValue getSubVectorSrc(SDValue V, unsigned Index, EVT SubVT) {
-  if (V.getOpcode() == ISD::INSERT_SUBVECTOR &&
-      V.getOperand(1).getValueType() == SubVT &&
-      V.getConstantOperandAPInt(2) == Index) {
-    return V.getOperand(1);
-  }
+// Scan one wide operand's INSERT_SUBVECTOR chain (optionally rooted at a
+// CONCAT_VECTORS) a single time and fill in OpNo's source for each SubVT-sized
+// slot. Slots are indexed by their subvector position, so the chain is never
+// recorded wholesale. Each slot is a tuple of the extract_subvector user (if
+// any) and the matching subvector source from each wide operand; a slot whose
+// two sources are both null was never seen on either chain (i.e. it is undef).
+// The outermost definition of a slot wins; an insert that is not SubVT-aligned
+// can straddle two slots, so we stop there and leave deeper slots unavailable.
+static void collectSubVectorSrcs(
+    SDValue V, EVT SubVT, unsigned OpNo,
+    MutableArrayRef<std::tuple<SDNode *, SDValue, SDValue>> Slots) {
+  unsigned NumSubElts = SubVT.getVectorMinNumElements();
+  auto record = [&](unsigned Part, SDValue Sub) {
+    if (Part >= Slots.size())
+      return;
+    SDValue &Slot =
+        OpNo == 0 ? std::get<1>(Slots[Part]) : std::get<2>(Slots[Part]);
+    if (!Slot)
+      Slot = Sub;
+  };
   if (V.getOpcode() == ISD::CONCAT_VECTORS &&
-      V.getOperand(0).getValueType() == SubVT &&
-      (Index % SubVT.getVectorMinNumElements()) == 0) {
-    uint64_t SubIdx = Index / SubVT.getVectorMinNumElements();
-    return V.getOperand(SubIdx);
+      V.getOperand(0).getValueType() == SubVT) {
+    for (unsigned I = 0, E = V.getNumOperands(); I != E; ++I)
+      record(I, V.getOperand(I));
----------------
arsenm wrote:

Can be range loop 

https://github.com/llvm/llvm-project/pull/201056


More information about the llvm-commits mailing list