Skip to content

Commit

Permalink
[IndVars] Check if WideInc available before trying to use it
Browse files Browse the repository at this point in the history
WideInc/WideIncExpr can be null. Previously this worked out
because the comparison with WideIncExpr would fail. Now we have
accesses to WideInc prior to that. Avoid the issue with an
explicit check.

Fixes #106239.

(cherry picked from commit c9a5e1b)
  • Loading branch information
nikic authored and tru committed Sep 3, 2024
1 parent e3abd19 commit e594b28
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 11 deletions.
28 changes: 17 additions & 11 deletions llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1928,18 +1928,24 @@ Instruction *WidenIV::widenIVUse(WidenIV::NarrowIVDefUse DU,
if (!WideAddRec.first)
return nullptr;

// Reuse the IV increment that SCEVExpander created. Recompute flags, unless
// the flags for both increments agree and it is safe to use the ones from
// the original inc. In that case, the new use of the wide increment won't
// be more poisonous.
bool NeedToRecomputeFlags =
!SCEVExpander::canReuseFlagsFromOriginalIVInc(OrigPhi, WidePhi,
DU.NarrowUse, WideInc) ||
DU.NarrowUse->hasNoUnsignedWrap() != WideInc->hasNoUnsignedWrap() ||
DU.NarrowUse->hasNoSignedWrap() != WideInc->hasNoSignedWrap();
auto CanUseWideInc = [&]() {
if (!WideInc)
return false;
// Reuse the IV increment that SCEVExpander created. Recompute flags,
// unless the flags for both increments agree and it is safe to use the
// ones from the original inc. In that case, the new use of the wide
// increment won't be more poisonous.
bool NeedToRecomputeFlags =
!SCEVExpander::canReuseFlagsFromOriginalIVInc(
OrigPhi, WidePhi, DU.NarrowUse, WideInc) ||
DU.NarrowUse->hasNoUnsignedWrap() != WideInc->hasNoUnsignedWrap() ||
DU.NarrowUse->hasNoSignedWrap() != WideInc->hasNoSignedWrap();
return WideAddRec.first == WideIncExpr &&
Rewriter.hoistIVInc(WideInc, DU.NarrowUse, NeedToRecomputeFlags);
};

Instruction *WideUse = nullptr;
if (WideAddRec.first == WideIncExpr &&
Rewriter.hoistIVInc(WideInc, DU.NarrowUse, NeedToRecomputeFlags))
if (CanUseWideInc())
WideUse = WideInc;
else {
WideUse = cloneIVUser(DU, WideAddRec.first);
Expand Down
36 changes: 36 additions & 0 deletions llvm/test/Transforms/IndVarSimplify/pr106239.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -passes=indvars < %s | FileCheck %s

target datalayout = "n8:16:32:64"

; Make sure it does not crash.

define i32 @m() {
; CHECK-LABEL: define i32 @m() {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: br label %[[FOR_BODY_I6:.*]]
; CHECK: [[FOR_BODY_I6]]:
; CHECK-NEXT: br i1 true, label %[[I_EXIT:.*]], label %[[IF_END_I:.*]]
; CHECK: [[IF_END_I]]:
; CHECK-NEXT: store i64 0, ptr null, align 8
; CHECK-NEXT: br label %[[FOR_BODY_I6]]
; CHECK: [[I_EXIT]]:
; CHECK-NEXT: ret i32 0
;
entry:
%div.i4 = sdiv i32 1, 0
br label %for.body.i6

for.body.i6: ; preds = %if.end.i, %entry
%add57.i = phi i32 [ %add.i7, %if.end.i ], [ 0, %entry ]
br i1 true, label %i.exit, label %if.end.i

if.end.i: ; preds = %for.body.i6
%add.i7 = add i32 %add57.i, %div.i4
%conv.i = zext i32 %add57.i to i64
store i64 %conv.i, ptr null, align 8
br label %for.body.i6

i.exit: ; preds = %for.body.i6
ret i32 0
}

0 comments on commit e594b28

Please sign in to comment.