[llvm] [Attributor] Use sorted offsets for constant vector stores (PR #231079)

Jiahe Wang via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 11 23:29:40 PDT 2026


https://github.com/wjhwjhn created https://github.com/llvm/llvm-project/pull/231079

`RangeList` requires strictly increasing offsets. `handleAccess` already computes `OffsetsSorted`, but the constant-vector store path still builds its element offsets from the original unsorted set. Use `OffsetsSorted` here as well so the element offsets satisfy the same ordering requirement.

When a pointer has multiple possible offsets, iterating over the original set can produce them out of order, triggering "Expected strictly ascending offsets". The regression test reproduces this by storing a constant vector through a pointer selected between two offsets in the same allocation.

The test asserts before the fix and passes afterward with both `attributor` and `attributor-cgscc`. All 207 Attributor tests also pass on Windows with assertions enabled.

This is my first PR to LLVM, so please let me know if I've missed anything. Thanks for taking a look!

>From 11f6c0ae187f1276449f1ca16e97a89ae782e0da Mon Sep 17 00:00:00 2001
From: wjhwjhn <wjhwjhn at gmail.com>
Date: Mon, 12 Oct 2026 14:06:33 +0800
Subject: [PATCH] [Attributor] Use sorted offsets for constant vector stores

RangeList requires strictly increasing offsets. Build element offsets
from OffsetsSorted to preserve this ordering for constant vector stores.
---
 .../Transforms/IPO/AttributorAttributes.cpp    |  3 ++-
 .../constant-vector-store-offset-order.ll      | 18 ++++++++++++++++++
 2 files changed, 20 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/Transforms/Attributor/constant-vector-store-offset-order.ll

diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index e49679fe2fd68..7387d8b6c8163 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -1465,7 +1465,8 @@ struct AAPointerInfoFloating : public AAPointerInfoImpl {
       int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue();
       auto *ConstContent = cast<Constant>(*Content);
       Type *Int32Ty = Type::getInt32Ty(ElementType->getContext());
-      SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end());
+      SmallVector<int64_t> ElementOffsets(OffsetsSorted.begin(),
+                                          OffsetsSorted.end());
 
       for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) {
         Value *ElementContent = ConstantExpr::getExtractElement(
diff --git a/llvm/test/Transforms/Attributor/constant-vector-store-offset-order.ll b/llvm/test/Transforms/Attributor/constant-vector-store-offset-order.ll
new file mode 100644
index 0000000000000..9be543a545c58
--- /dev/null
+++ b/llvm/test/Transforms/Attributor/constant-vector-store-offset-order.ll
@@ -0,0 +1,18 @@
+; RUN: opt -passes=attributor -verify-each -S %s | FileCheck %s
+; RUN: opt -passes=attributor-cgscc -verify-each -S %s | FileCheck %s
+;
+; The select can refer to offsets 2 and 0 of the same allocation. Collecting
+; these offsets can produce a non-sorted SmallSet iteration order. Constant
+; vector stores must sort the offsets before constructing a RangeList.
+; Both destinations are in bounds; no target-specific behavior is required.
+
+define void @constant_vector_store(i1 %c) {
+; CHECK-LABEL: define void @constant_vector_store(
+; CHECK-NOT: store
+; CHECK: ret void
+  %base = alloca [4 x i8]
+  %hi = getelementptr i8, ptr %base, i64 2
+  %dst = select i1 %c, ptr %hi, ptr %base
+  store <2 x i8> <i8 7, i8 9>, ptr %dst, align 1
+  ret void
+}



More information about the llvm-commits mailing list