[llvm] 0cee548 - [SCEV][SCEVExpander] Avoid querying SCEV for non-SCEVable instructions (#214902)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 12 23:09:37 PDT 2026
Author: Jinpeng Wang
Date: 2026-08-13T06:09:33Z
New Revision: 0cee5484785e45082deb29b59fc7f3697b087319
URL: https://github.com/llvm/llvm-project/commit/0cee5484785e45082deb29b59fc7f3697b087319
DIFF: https://github.com/llvm/llvm-project/commit/0cee5484785e45082deb29b59fc7f3697b087319.diff
LOG: [SCEV][SCEVExpander] Avoid querying SCEV for non-SCEVable instructions (#214902)
`getStrengthenedNoWrapFlagsFromBinOp()` expects instructions with
SCEVable operands.
For non-SCEVable vector-typed operands, this triggers the assertion in
`getSCEV()`.
This PR guards the caller in
`dropPoisonGeneratingAnnotationsAndReinfer()` so that
nowrap flags are only re-inferred for SCEVable instructions.
The added test is a crash regression test.
Fixes #214782
Fixes #215251
Fixes #114029
Added:
llvm/test/Transforms/LoopStrengthReduce/X86/scev-vector-shl-crash.ll
Modified:
llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index 923ac3ce0bea6..a7ca2104e59c3 100644
--- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
@@ -1762,13 +1762,14 @@ void SCEVExpander::dropPoisonGeneratingAnnotationsAndReinfer(
// See if we can re-infer from first principles any of the flags we just
// dropped.
if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(I))
- if (auto Flags = SE.getStrengthenedNoWrapFlagsFromBinOp(OBO)) {
- auto *BO = cast<BinaryOperator>(I);
- BO->setHasNoUnsignedWrap(
- ScalarEvolution::maskFlags(*Flags, SCEV::FlagNUW) == SCEV::FlagNUW);
- BO->setHasNoSignedWrap(
- ScalarEvolution::maskFlags(*Flags, SCEV::FlagNSW) == SCEV::FlagNSW);
- }
+ if (SE.isSCEVable(OBO->getType()))
+ if (auto Flags = SE.getStrengthenedNoWrapFlagsFromBinOp(OBO)) {
+ auto *BO = cast<BinaryOperator>(I);
+ BO->setHasNoUnsignedWrap(
+ ScalarEvolution::maskFlags(*Flags, SCEV::FlagNUW) == SCEV::FlagNUW);
+ BO->setHasNoSignedWrap(
+ ScalarEvolution::maskFlags(*Flags, SCEV::FlagNSW) == SCEV::FlagNSW);
+ }
if (auto *NNI = dyn_cast<PossiblyNonNegInst>(I)) {
auto *Src = NNI->getOperand(0);
if (isImpliedByDomCondition(ICmpInst::ICMP_SGE, Src,
diff --git a/llvm/test/Transforms/LoopStrengthReduce/X86/scev-vector-shl-crash.ll b/llvm/test/Transforms/LoopStrengthReduce/X86/scev-vector-shl-crash.ll
new file mode 100644
index 0000000000000..e5a2e8217c8b9
--- /dev/null
+++ b/llvm/test/Transforms/LoopStrengthReduce/X86/scev-vector-shl-crash.ll
@@ -0,0 +1,39 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -mtriple=x86_64 -passes=loop-reduce -S < %s | FileCheck %s
+
+; Ensure LSR does not crash by querying ScalarEvolution for the non-SCEVable
+; vector shl while strengthening its nowrap flags.
+
+define void @snork(i64 %arg) {
+; CHECK-LABEL: define void @snork(
+; CHECK-SAME: i64 [[ARG:%.*]]) {
+; CHECK-NEXT: [[BBL:.*]]:
+; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i64> zeroinitializer, zeroinitializer
+; CHECK-NEXT: [[EXTRACTELEMENT:%.*]] = extractelement <2 x i64> [[SHL]], i64 0
+; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[ARG]], [[EXTRACTELEMENT]]
+; CHECK-NEXT: [[AND:%.*]] = and i64 [[ARG]], 1
+; CHECK-NEXT: [[SUB1:%.*]] = sub i64 [[SUB]], [[AND]]
+; CHECK-NEXT: [[ADD:%.*]] = add i64 [[EXTRACTELEMENT]], [[SUB1]]
+; CHECK-NEXT: [[TMP0:%.*]] = sub i64 -1, [[ADD]]
+; CHECK-NEXT: br label %[[BBL2:.*]]
+; CHECK: [[BBL2]]:
+; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], %[[BBL2]] ], [ [[TMP0]], %[[BBL]] ]
+; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i64 [[LSR_IV]], 0
+; CHECK-NEXT: [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -1
+; CHECK-NEXT: br label %[[BBL2]]
+;
+bbl:
+ %shl = shl nsw <2 x i64> zeroinitializer, zeroinitializer
+ %extractelement = extractelement <2 x i64> %shl, i64 0
+ %sub = sub i64 %arg, %extractelement
+ %and = and i64 %arg, 1
+ %sub1 = sub i64 %sub, %and
+ %add = add i64 %extractelement, %sub1
+ br label %bbl2
+
+bbl2:
+ %phi = phi i64 [ %add3, %bbl2 ], [ %add, %bbl ]
+ %add3 = add i64 %phi, 1
+ %icmp = icmp eq i64 %add3, 0
+ br label %bbl2
+}
More information about the llvm-commits
mailing list