[llvm] 1c825be - [VectorCombine] Check load offsets in APInt before narrowing shuffle indices (#210904)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 23 04:00:30 PDT 2026
Author: hanbeom
Date: 2026-07-23T20:00:25+09:00
New Revision: 1c825be24005af24237748ae98dae9cd4711bcdc
URL: https://github.com/llvm/llvm-project/commit/1c825be24005af24237748ae98dae9cd4711bcdc
DIFF: https://github.com/llvm/llvm-project/commit/1c825be24005af24237748ae98dae9cd4711bcdc.diff
LOG: [VectorCombine] Check load offsets in APInt before narrowing shuffle indices (#210904)
vectorizeLoadInsert narrowed the APInt element offset to unsigned before
checking its range. Large offsets could wrap and select the wrong vector
element.
Check the offset range as an APInt before converting it to the shuffle
index. This prevents invalid load widening and is covered by
a regression test.
Fixes #210903
Added:
Modified:
llvm/lib/Transforms/Vectorize/VectorCombine.cpp
llvm/test/Transforms/VectorCombine/X86/load-inseltpoison.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
index 741bd4460a5ab..005497e3ada45 100644
--- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
@@ -295,9 +295,10 @@ bool VectorCombine::vectorizeLoadInsert(Instruction &I) {
return false;
// If we load MinVecNumElts, will our target element still be loaded?
- OffsetEltIndex = Offset.udiv(ScalarSizeInBytes).getZExtValue();
- if (OffsetEltIndex >= MinVecNumElts)
+ APInt OffsetEltIndexAP = Offset.udiv(ScalarSizeInBytes);
+ if (OffsetEltIndexAP.uge(MinVecNumElts))
return false;
+ OffsetEltIndex = OffsetEltIndexAP.getZExtValue();
if (!isSafeToLoadUnconditionally(SrcPtr, MinVecTy, Align(1), *DL, Load,
SQ.AC, SQ.DT))
diff --git a/llvm/test/Transforms/VectorCombine/X86/load-inseltpoison.ll b/llvm/test/Transforms/VectorCombine/X86/load-inseltpoison.ll
index e8381d1b206e2..8cd99bbf31a8c 100644
--- a/llvm/test/Transforms/VectorCombine/X86/load-inseltpoison.ll
+++ b/llvm/test/Transforms/VectorCombine/X86/load-inseltpoison.ll
@@ -336,6 +336,22 @@ define <4 x i32> @gep013_bitcast_load_i32_insert_v4i32(ptr align 1 dereferenceab
ret <4 x i32> %r
}
+; The element index is 2^32 and does not fit in unsigned. It must be rejected
+; before conversion to the shuffle-mask index type.
+
+define <4 x i32> @load_insert_large_offset(ptr align 16 dereferenceable(17179869188) %p) {
+; CHECK-LABEL: @load_insert_large_offset(
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 17179869184
+; CHECK-NEXT: [[S:%.*]] = load i32, ptr [[GEP]], align 4
+; CHECK-NEXT: [[R:%.*]] = insertelement <4 x i32> poison, i32 [[S]], i64 0
+; CHECK-NEXT: ret <4 x i32> [[R]]
+;
+ %gep = getelementptr inbounds i8, ptr %p, i64 17179869184
+ %s = load i32, ptr %gep, align 4
+ %r = insertelement <4 x i32> poison, i32 %s, i64 0
+ ret <4 x i32> %r
+}
+
; If there are enough dereferenceable bytes, we can offset the vector load.
define <8 x i16> @gep10_load_i16_insert_v8i16(ptr align 16 dereferenceable(32) %p) nofree nosync {
More information about the llvm-commits
mailing list