[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