[llvm] 73a0b12 - [CodeGenPrepare] don't promote sdiv/srem by -1 (#218737)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 30 00:58:42 PDT 2026
Author: ʟᴜɴᴇx
Date: 2026-09-30T07:58:34Z
New Revision: 73a0b12b8ee34b9d2858cf6ca60a6154145a52ca
URL: https://github.com/llvm/llvm-project/commit/73a0b12b8ee34b9d2858cf6ca60a6154145a52ca
DIFF: https://github.com/llvm/llvm-project/commit/73a0b12b8ee34b9d2858cf6ca60a6154145a52ca.diff
LOG: [CodeGenPrepare] don't promote sdiv/srem by -1 (#218737)
`store-extract` promotion was widening sdiv/srem to the vector type
without checking if thats safe or not... and INT_MIN lane / -1 is UB.
skip sdiv/srem by -1 in `shouldPromote`, rest still promotes fine.
Fixes #218570
Added:
llvm/test/Transforms/CodeGenPrepare/X86/store-extract-division-ub.ll
Modified:
llvm/lib/CodeGen/CodeGenPrepare.cpp
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index d554a32a5d3ae..5c8fedd45902c 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -8411,16 +8411,13 @@ class VectorPromoteHelper {
/// Check if it is profitable to promote \p ToBePromoted
/// by moving downward the transition through.
bool shouldPromote(const Instruction *ToBePromoted) const {
+ if (!isSafeToSpeculativelyExecuteWithVariableReplaced(ToBePromoted))
+ return false;
// Promote only if all the operands can be statically expanded.
// Indeed, we do not want to introduce any new kind of transitions.
for (const Use &U : ToBePromoted->operands()) {
const Value *Val = U.get();
if (Val == getEndOfTransition()) {
- // If the use is a division and the transition is on the rhs,
- // we cannot promote the operation, otherwise we may create a
- // division by zero.
- if (canCauseUndefinedBehavior(ToBePromoted, U.getOperandNo()))
- return false;
continue;
}
if (!isa<ConstantInt>(Val) && !isa<UndefValue>(Val) &&
diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/store-extract-division-ub.ll b/llvm/test/Transforms/CodeGenPrepare/X86/store-extract-division-ub.ll
new file mode 100644
index 0000000000000..872a527d5de6d
--- /dev/null
+++ b/llvm/test/Transforms/CodeGenPrepare/X86/store-extract-division-ub.ll
@@ -0,0 +1,114 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; test for issue (https://github.com/llvm/llvm-project/issues/218570)
+; RUN: opt -S -passes='require<profile-summary>,function(codegenprepare)' -stress-cgp-store-extract < %s | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @no_promote_sdiv_minus_one(ptr %src, ptr %dst) {
+; CHECK-LABEL: define void @no_promote_sdiv_minus_one(
+; CHECK-SAME: ptr [[SRC:%.*]], ptr [[DST:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[V:%.*]] = load <2 x i8>, ptr [[SRC]], align 1
+; CHECK-NEXT: [[E:%.*]] = extractelement <2 x i8> [[V]], i32 0
+; CHECK-NEXT: [[R:%.*]] = sdiv i8 [[E]], -1
+; CHECK-NEXT: store i8 [[R]], ptr [[DST]], align 1
+; CHECK-NEXT: ret void
+;
+entry:
+ %v = load <2 x i8>, ptr %src, align 1
+ %e = extractelement <2 x i8> %v, i32 0
+ %r = sdiv i8 %e, -1
+ store i8 %r, ptr %dst, align 1
+ ret void
+}
+
+define void @no_promote_srem_minus_one(ptr %src, ptr %dst) {
+; CHECK-LABEL: define void @no_promote_srem_minus_one(
+; CHECK-SAME: ptr [[SRC:%.*]], ptr [[DST:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[V:%.*]] = load <2 x i8>, ptr [[SRC]], align 1
+; CHECK-NEXT: [[E:%.*]] = extractelement <2 x i8> [[V]], i32 0
+; CHECK-NEXT: [[R:%.*]] = srem i8 [[E]], -1
+; CHECK-NEXT: store i8 [[R]], ptr [[DST]], align 1
+; CHECK-NEXT: ret void
+;
+entry:
+ %v = load <2 x i8>, ptr %src, align 1
+ %e = extractelement <2 x i8> %v, i32 0
+ %r = srem i8 %e, -1
+ store i8 %r, ptr %dst, align 1
+ ret void
+}
+
+define void @no_promote_sdiv_poison(ptr %src, ptr %dst) {
+; CHECK-LABEL: define void @no_promote_sdiv_poison(
+; CHECK-SAME: ptr [[SRC:%.*]], ptr [[DST:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[V:%.*]] = load <2 x i8>, ptr [[SRC]], align 1
+; CHECK-NEXT: [[E:%.*]] = extractelement <2 x i8> [[V]], i32 0
+; CHECK-NEXT: [[R:%.*]] = sdiv i8 [[E]], poison
+; CHECK-NEXT: store i8 [[R]], ptr [[DST]], align 1
+; CHECK-NEXT: ret void
+;
+entry:
+ %v = load <2 x i8>, ptr %src, align 1
+ %e = extractelement <2 x i8> %v, i32 0
+ %r = sdiv i8 %e, poison
+ store i8 %r, ptr %dst, align 1
+ ret void
+}
+
+define void @promote_sdiv_two(ptr %src, ptr %dst) {
+; CHECK-LABEL: define void @promote_sdiv_two(
+; CHECK-SAME: ptr [[SRC:%.*]], ptr [[DST:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[V:%.*]] = load <2 x i8>, ptr [[SRC]], align 1
+; CHECK-NEXT: [[R:%.*]] = sdiv <2 x i8> [[V]], splat (i8 2)
+; CHECK-NEXT: [[E:%.*]] = extractelement <2 x i8> [[R]], i32 0
+; CHECK-NEXT: store i8 [[E]], ptr [[DST]], align 1
+; CHECK-NEXT: ret void
+;
+entry:
+ %v = load <2 x i8>, ptr %src, align 1
+ %e = extractelement <2 x i8> %v, i32 0
+ %r = sdiv i8 %e, 2
+ store i8 %r, ptr %dst, align 1
+ ret void
+}
+
+define void @promote_udiv_seven(ptr %src, ptr %dst) {
+; CHECK-LABEL: define void @promote_udiv_seven(
+; CHECK-SAME: ptr [[SRC:%.*]], ptr [[DST:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[V:%.*]] = load <2 x i8>, ptr [[SRC]], align 1
+; CHECK-NEXT: [[R:%.*]] = udiv <2 x i8> [[V]], splat (i8 7)
+; CHECK-NEXT: [[E:%.*]] = extractelement <2 x i8> [[R]], i32 0
+; CHECK-NEXT: store i8 [[E]], ptr [[DST]], align 1
+; CHECK-NEXT: ret void
+;
+entry:
+ %v = load <2 x i8>, ptr %src, align 1
+ %e = extractelement <2 x i8> %v, i32 0
+ %r = udiv i8 %e, 7
+ store i8 %r, ptr %dst, align 1
+ ret void
+}
+
+define void @no_promote_sdiv_intmin(ptr %src, ptr %dst) {
+; CHECK-LABEL: define void @no_promote_sdiv_intmin(
+; CHECK-SAME: ptr [[SRC:%.*]], ptr [[DST:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[V:%.*]] = load <2 x i8>, ptr [[SRC]], align 1
+; CHECK-NEXT: [[E:%.*]] = extractelement <2 x i8> [[V]], i32 0
+; CHECK-NEXT: [[R:%.*]] = sdiv i8 -128, [[E]]
+; CHECK-NEXT: store i8 [[R]], ptr [[DST]], align 1
+; CHECK-NEXT: ret void
+;
+entry:
+ %v = load <2 x i8>, ptr %src, align 1
+ %e = extractelement <2 x i8> %v, i32 0
+ %r = sdiv i8 -128, %e
+ store i8 %r, ptr %dst, align 1
+ ret void
+}
+
More information about the llvm-commits
mailing list