[llvm] [LSV] Merge contiguous chains across scalar types (PR #154069)

Anshil Gandhi via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 21 23:59:21 PDT 2025


================
@@ -424,6 +432,20 @@ PreservedAnalyses LoadStoreVectorizerPass::run(Function &F,
   return Changed ? PA : PreservedAnalyses::all();
 }
 
+static const Value *getUnderlyingPtrObject(const Value *Ptr) {
+  const Value *ObjPtr = llvm::getUnderlyingObject(Ptr);
+  if (const auto *Sel = dyn_cast<SelectInst>(ObjPtr)) {
+    // The select's themselves are distinct instructions even if they share
+    // the same condition and evaluate to consecutive pointers for true and
+    // false values of the condition. Therefore using the select's themselves
+    // for grouping instructions would put consecutive accesses into different
+    // lists and they won't be even checked for being consecutive, and won't
+    // be vectorized.
+    return Sel->getCondition();
+  }
+  return ObjPtr;
+}
----------------
gandhi56 wrote:

I moved this function from `collectEquivalenceClasses` function, it's used to group instructions into classes/chains. I found a test in which case returning the select condition value is useful:

```
define void @base_case(i1 %cnd, ptr addrspace(1) %a, ptr addrspace(1) %b, ptr addrspace(1) %out) {
; CHECK-LABEL: @base_case
; CHECK: load <3 x i32>
entry:
  %gep1 = getelementptr inbounds i32, ptr addrspace(1) %a, i64 1
  %gep2 = getelementptr inbounds i32, ptr addrspace(1) %a, i64 2
  %gep4 = getelementptr inbounds i32, ptr addrspace(1) %b, i64 1
  %gep5 = getelementptr inbounds i32, ptr addrspace(1) %b, i64 2
  %selected = select i1 %cnd, ptr addrspace(1) %a, ptr addrspace(1) %b
  %selected14 = select i1 %cnd, ptr addrspace(1) %gep1, ptr addrspace(1) %gep4
  %selected25 = select i1 %cnd, ptr addrspace(1) %gep2, ptr addrspace(1) %gep5
  %val0 = load i32, ptr addrspace(1) %selected, align 4
  %val1 = load i32, ptr addrspace(1) %selected14, align 4
  %val2 = load i32, ptr addrspace(1) %selected25, align 4
  ret void
}
```

In this test, `getUnderlyingObject(%selected) = getUnderlyingObject(%selected14) = getUnderlyingObject(%selected25) = %cnd`. Without the `SelectInst` handling, the underlying objects are the distinct select instructions themselves => the loads aren't vectorized.

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


More information about the llvm-commits mailing list