[llvm-branch-commits] [llvm] [SCEV] Add option to request use-specific SCEV for a GEP expr (WIP). (PR #91964)
Florian Hahn via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon May 13 06:38:56 PDT 2024
https://github.com/fhahn created https://github.com/llvm/llvm-project/pull/91964
Use SCEVUse from https://github.com/llvm/llvm-project/pull/91961 to return a SCEVUse with use-specific no-wrap flags for GEP expr, when demanded.
Clients need to opt-in, as the use-specific flags may not be valid in some contexts (e.g. backedge taken counts).
>From dea2c74ec83f390025cb0389859e472e8676c768 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Sun, 12 May 2024 09:57:54 +0100
Subject: [PATCH] [SCEV] Add option to request use-specific SCEV for a GEP expr
(WIP).
Use SCEVUse from https://github.com/llvm/llvm-project/pull/91961 to
return a SCEVUse with use-specific no-wrap flags for GEP expr, when
demanded.
Clients need to opt-in, as the use-specific flags may not be valid in
some contexts (e.g. backedge taken counts).
---
llvm/include/llvm/Analysis/ScalarEvolution.h | 14 ++++----
llvm/lib/Analysis/ScalarEvolution.cpp | 36 +++++++++++--------
.../Analysis/ScalarEvolution/min-max-exprs.ll | 2 +-
.../ScalarEvolution/no-wrap-add-exprs.ll | 12 +++----
.../no-wrap-symbolic-becount.ll | 2 +-
.../test/Analysis/ScalarEvolution/ptrtoint.ll | 4 +--
llvm/test/Analysis/ScalarEvolution/sdiv.ll | 2 +-
llvm/test/Analysis/ScalarEvolution/srem.ll | 2 +-
8 files changed, 41 insertions(+), 33 deletions(-)
diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index 2859df9964555..4ca3dbc1c6703 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -653,7 +653,7 @@ class ScalarEvolution {
/// Return a SCEV expression for the full generality of the specified
/// expression.
- SCEVUse getSCEV(Value *V);
+ SCEVUse getSCEV(Value *V, bool UseCtx = false);
/// Return an existing SCEV for V if there is one, otherwise return nullptr.
SCEVUse getExistingSCEV(Value *V);
@@ -735,9 +735,11 @@ class ScalarEvolution {
/// \p GEP The GEP. The indices contained in the GEP itself are ignored,
/// instead we use IndexExprs.
/// \p IndexExprs The expressions for the indices.
- SCEVUse getGEPExpr(GEPOperator *GEP, ArrayRef<const SCEV *> IndexExprs);
+ SCEVUse getGEPExpr(GEPOperator *GEP, ArrayRef<const SCEV *> IndexExprs,
+ bool UseCtx = false);
SCEVUse getGEPExpr(GEPOperator *GEP,
- const SmallVectorImpl<SCEVUse> &IndexExprs);
+ const SmallVectorImpl<SCEVUse> &IndexExprs,
+ bool UseCtx = false);
SCEVUse getAbsExpr(SCEVUse Op, bool IsNSW);
SCEVUse getMinMaxExpr(SCEVTypes Kind, ArrayRef<const SCEV *> Operands);
SCEVUse getMinMaxExpr(SCEVTypes Kind, SmallVectorImpl<SCEVUse> &Operands);
@@ -1783,11 +1785,11 @@ class ScalarEvolution {
/// We know that there is no SCEV for the specified value. Analyze the
/// expression recursively.
- SCEVUse createSCEV(Value *V);
+ SCEVUse createSCEV(Value *V, bool UseCtx = false);
/// We know that there is no SCEV for the specified value. Create a new SCEV
/// for \p V iteratively.
- SCEVUse createSCEVIter(Value *V);
+ SCEVUse createSCEVIter(Value *V, bool UseCtx = false);
/// Collect operands of \p V for which SCEV expressions should be constructed
/// first. Returns a SCEV directly if it can be constructed trivially for \p
/// V.
@@ -1826,7 +1828,7 @@ class ScalarEvolution {
Value *FalseVal);
/// Provide the special handling we need to analyze GEP SCEVs.
- SCEVUse createNodeForGEP(GEPOperator *GEP);
+ SCEVUse createNodeForGEP(GEPOperator *GEP, bool UseCtx = false);
/// Implementation code for getSCEVAtScope; called at most once for each
/// SCEV+Loop pair.
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 320be6f26fc0a..68f4ddd47d69a 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -2741,6 +2741,8 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
break;
// If we have an add, expand the add operands onto the end of the operands
// list.
+ // CommonFlags = maskFlags(CommonFlags, setFlags(Add->getNoWrapFlags(),
+ // static_cast<SCEV::NoWrapFlags>(Ops[Idx].getInt())));
Ops.erase(Ops.begin()+Idx);
append_range(Ops, Add->operands());
DeletedAdd = true;
@@ -3759,13 +3761,14 @@ SCEVUse ScalarEvolution::getAddRecExpr(SmallVectorImpl<SCEVUse> &Operands,
}
SCEVUse ScalarEvolution::getGEPExpr(GEPOperator *GEP,
- ArrayRef<const SCEV *> IndexExprs) {
- return getGEPExpr(GEP, SmallVector<SCEVUse>(IndexExprs));
+ ArrayRef<const SCEV *> IndexExprs,
+ bool UseCtx) {
+ return getGEPExpr(GEP, SmallVector<SCEVUse>(IndexExprs), UseCtx);
}
-SCEVUse
-ScalarEvolution::getGEPExpr(GEPOperator *GEP,
- const SmallVectorImpl<SCEVUse> &IndexExprs) {
+SCEVUse ScalarEvolution::getGEPExpr(GEPOperator *GEP,
+ const SmallVectorImpl<SCEVUse> &IndexExprs,
+ bool UseCtx) {
SCEVUse BaseExpr = getSCEV(GEP->getPointerOperand());
// getSCEV(Base)->getType() has the same address space as Base->getType()
// because SCEV::getType() preserves the address space.
@@ -3835,6 +3838,9 @@ ScalarEvolution::getGEPExpr(GEPOperator *GEP,
auto GEPExpr = getAddExpr(BaseExpr, Offset, BaseWrap);
assert(BaseExpr->getType() == GEPExpr->getType() &&
"GEP should not change type mid-flight.");
+ if (UseCtx && BaseWrap != SCEV::FlagNUW && GEP->isInBounds() &&
+ isKnownNonNegative(Offset))
+ GEPExpr = SCEVUse(&*GEPExpr, 2);
return GEPExpr;
}
@@ -4587,12 +4593,12 @@ void ScalarEvolution::insertValueToMap(Value *V, SCEVUse S) {
/// Return an existing SCEV if it exists, otherwise analyze the expression and
/// create a new one.
-SCEVUse ScalarEvolution::getSCEV(Value *V) {
+SCEVUse ScalarEvolution::getSCEV(Value *V, bool UseCtx) {
assert(isSCEVable(V->getType()) && "Value is not SCEVable!");
if (SCEVUse S = getExistingSCEV(V))
return S;
- return createSCEVIter(V);
+ return createSCEVIter(V, UseCtx);
}
SCEVUse ScalarEvolution::getExistingSCEV(Value *V) {
@@ -6283,14 +6289,14 @@ SCEVUse ScalarEvolution::createNodeForSelectOrPHI(Value *V, Value *Cond,
/// Expand GEP instructions into add and multiply operations. This allows them
/// to be analyzed by regular SCEV code.
-SCEVUse ScalarEvolution::createNodeForGEP(GEPOperator *GEP) {
+SCEVUse ScalarEvolution::createNodeForGEP(GEPOperator *GEP, bool UseCtx) {
assert(GEP->getSourceElementType()->isSized() &&
"GEP source element type must be sized");
SmallVector<SCEVUse, 4> IndexExprs;
for (Value *Index : GEP->indices())
IndexExprs.push_back(getSCEV(Index));
- return getGEPExpr(GEP, IndexExprs);
+ return getGEPExpr(GEP, IndexExprs, UseCtx);
}
APInt ScalarEvolution::getConstantMultipleImpl(SCEVUse S) {
@@ -7440,7 +7446,7 @@ bool ScalarEvolution::loopIsFiniteByAssumption(const Loop *L) {
return isFinite(L) || (isMustProgress(L) && loopHasNoSideEffects(L));
}
-SCEVUse ScalarEvolution::createSCEVIter(Value *V) {
+SCEVUse ScalarEvolution::createSCEVIter(Value *V, bool UseCtx) {
// Worklist item with a Value and a bool indicating whether all operands have
// been visited already.
using PointerTy = PointerIntPair<Value *, 1, bool>;
@@ -7459,7 +7465,7 @@ SCEVUse ScalarEvolution::createSCEVIter(Value *V) {
SCEVUse CreatedSCEV = nullptr;
// If all operands have been visited already, create the SCEV.
if (E.getInt()) {
- CreatedSCEV = createSCEV(CurV);
+ CreatedSCEV = createSCEV(CurV, UseCtx);
} else {
// Otherwise get the operands we need to create SCEV's for before creating
// the SCEV for CurV. If the SCEV for CurV can be constructed trivially,
@@ -7668,7 +7674,7 @@ SCEVUse ScalarEvolution::getOperandsToCreate(Value *V,
return nullptr;
}
-SCEVUse ScalarEvolution::createSCEV(Value *V) {
+SCEVUse ScalarEvolution::createSCEV(Value *V, bool UseCtx) {
if (!isSCEVable(V->getType()))
return getUnknown(V);
@@ -8077,7 +8083,7 @@ SCEVUse ScalarEvolution::createSCEV(Value *V) {
break;
case Instruction::GetElementPtr:
- return createNodeForGEP(cast<GEPOperator>(U));
+ return createNodeForGEP(cast<GEPOperator>(U), UseCtx);
case Instruction::PHI:
return createNodeForPHI(cast<PHINode>(U));
@@ -13621,8 +13627,8 @@ void ScalarEvolution::print(raw_ostream &OS) const {
if (isSCEVable(I.getType()) && !isa<CmpInst>(I)) {
OS << I << '\n';
OS << " --> ";
- SCEVUse SV = SE.getSCEV(&I);
- SV->print(OS);
+ SCEVUse SV = SE.getSCEV(&I, /*UseCtx=*/true);
+ SV.print(OS);
if (!isa<SCEVCouldNotCompute>(SV)) {
OS << " U: ";
SE.getUnsignedRange(SV).print(OS);
diff --git a/llvm/test/Analysis/ScalarEvolution/min-max-exprs.ll b/llvm/test/Analysis/ScalarEvolution/min-max-exprs.ll
index 6ededf2477711..a80c0f4ebc5ea 100644
--- a/llvm/test/Analysis/ScalarEvolution/min-max-exprs.ll
+++ b/llvm/test/Analysis/ScalarEvolution/min-max-exprs.ll
@@ -42,7 +42,7 @@ define void @f(ptr %A, i32 %N) {
; CHECK-NEXT: %tmp19 = select i1 %tmp14, i64 0, i64 %tmp17
; CHECK-NEXT: --> (-3 + (3 smax {0,+,1}<nuw><nsw><%bb1>))<nsw> U: [0,2147483645) S: [0,2147483645) Exits: (-3 + (3 smax (zext i32 (0 smax %N) to i64)))<nsw> LoopDispositions: { %bb1: Computable }
; CHECK-NEXT: %tmp21 = getelementptr inbounds i32, ptr %A, i64 %tmp19
-; CHECK-NEXT: --> (-12 + (4 * (3 smax {0,+,1}<nuw><nsw><%bb1>))<nuw><nsw> + %A) U: full-set S: full-set Exits: (-12 + (4 * (3 smax (zext i32 (0 smax %N) to i64)))<nuw><nsw> + %A) LoopDispositions: { %bb1: Computable }
+; CHECK-NEXT: --> (-12 + (4 * (3 smax {0,+,1}<nuw><nsw><%bb1>))<nuw><nsw> + %A)(u nuw) U: full-set S: full-set Exits: (-12 + (4 * (3 smax (zext i32 (0 smax %N) to i64)))<nuw><nsw> + %A) LoopDispositions: { %bb1: Computable }
; CHECK-NEXT: %tmp23 = add nuw nsw i32 %i.0, 1
; CHECK-NEXT: --> {1,+,1}<nuw><%bb1> U: [1,-2147483647) S: [1,-2147483647) Exits: (1 + (0 smax %N))<nuw> LoopDispositions: { %bb1: Computable }
; CHECK-NEXT: Determining loop execution counts for: @f
diff --git a/llvm/test/Analysis/ScalarEvolution/no-wrap-add-exprs.ll b/llvm/test/Analysis/ScalarEvolution/no-wrap-add-exprs.ll
index bd2ffddf396fe..4e13de3a2a09c 100644
--- a/llvm/test/Analysis/ScalarEvolution/no-wrap-add-exprs.ll
+++ b/llvm/test/Analysis/ScalarEvolution/no-wrap-add-exprs.ll
@@ -209,11 +209,11 @@ define void @f3(ptr %x_addr, ptr %y_addr, ptr %tmp_addr) {
; CHECK-NEXT: %sunkaddr3 = mul i64 %add4.zext, 4
; CHECK-NEXT: --> (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> U: [0,17179869169) S: [0,17179869181)
; CHECK-NEXT: %sunkaddr4 = getelementptr inbounds i8, ptr @tmp_addr, i64 %sunkaddr3
-; CHECK-NEXT: --> ((4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr) U: [0,-3) S: [-9223372036854775808,9223372036854775805)
+; CHECK-NEXT: --> ((4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr)(u nuw) U: [0,-3) S: [-9223372036854775808,9223372036854775805)
; CHECK-NEXT: %sunkaddr5 = getelementptr inbounds i8, ptr %sunkaddr4, i64 4096
-; CHECK-NEXT: --> (4096 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr) U: [0,-3) S: [-9223372036854775808,9223372036854775805)
+; CHECK-NEXT: --> (4096 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr)(u nuw) U: [0,-3) S: [-9223372036854775808,9223372036854775805)
; CHECK-NEXT: %addr4.cast = bitcast ptr %sunkaddr5 to ptr
-; CHECK-NEXT: --> (4096 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr) U: [0,-3) S: [-9223372036854775808,9223372036854775805)
+; CHECK-NEXT: --> (4096 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr)(u nuw) U: [0,-3) S: [-9223372036854775808,9223372036854775805)
; CHECK-NEXT: %addr4.incr = getelementptr i32, ptr %addr4.cast, i64 1
; CHECK-NEXT: --> (4100 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr) U: [0,-3) S: [-9223372036854775808,9223372036854775805)
; CHECK-NEXT: %add5 = add i32 %mul, 5
@@ -223,11 +223,11 @@ define void @f3(ptr %x_addr, ptr %y_addr, ptr %tmp_addr) {
; CHECK-NEXT: %sunkaddr0 = mul i64 %add5.zext, 4
; CHECK-NEXT: --> (4 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw>)<nuw><nsw> U: [4,17179869173) S: [4,17179869185)
; CHECK-NEXT: %sunkaddr1 = getelementptr inbounds i8, ptr @tmp_addr, i64 %sunkaddr0
-; CHECK-NEXT: --> (4 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr) U: [0,-3) S: [-9223372036854775808,9223372036854775805)
+; CHECK-NEXT: --> (4 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr)(u nuw) U: [0,-3) S: [-9223372036854775808,9223372036854775805)
; CHECK-NEXT: %sunkaddr2 = getelementptr inbounds i8, ptr %sunkaddr1, i64 4096
-; CHECK-NEXT: --> (4100 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr) U: [0,-3) S: [-9223372036854775808,9223372036854775805)
+; CHECK-NEXT: --> (4100 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr)(u nuw) U: [0,-3) S: [-9223372036854775808,9223372036854775805)
; CHECK-NEXT: %addr5.cast = bitcast ptr %sunkaddr2 to ptr
-; CHECK-NEXT: --> (4100 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr) U: [0,-3) S: [-9223372036854775808,9223372036854775805)
+; CHECK-NEXT: --> (4100 + (4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr)(u nuw) U: [0,-3) S: [-9223372036854775808,9223372036854775805)
; CHECK-NEXT: Determining loop execution counts for: @f3
;
entry:
diff --git a/llvm/test/Analysis/ScalarEvolution/no-wrap-symbolic-becount.ll b/llvm/test/Analysis/ScalarEvolution/no-wrap-symbolic-becount.ll
index e13a8976bf5ac..20ebcd6158e98 100644
--- a/llvm/test/Analysis/ScalarEvolution/no-wrap-symbolic-becount.ll
+++ b/llvm/test/Analysis/ScalarEvolution/no-wrap-symbolic-becount.ll
@@ -96,7 +96,7 @@ define void @pointer_iv_nowrap(ptr %startptr, ptr %endptr) local_unnamed_addr {
; CHECK-LABEL: 'pointer_iv_nowrap'
; CHECK-NEXT: Classifying expressions for: @pointer_iv_nowrap
; CHECK-NEXT: %init = getelementptr inbounds i8, ptr %startptr, i64 2000
-; CHECK-NEXT: --> (2000 + %startptr) U: full-set S: full-set
+; CHECK-NEXT: --> (2000 + %startptr)(u nuw) U: full-set S: full-set
; CHECK-NEXT: %iv = phi ptr [ %init, %entry ], [ %iv.next, %loop ]
; CHECK-NEXT: --> {(2000 + %startptr),+,1}<nuw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = getelementptr inbounds i8, ptr %iv, i64 1
diff --git a/llvm/test/Analysis/ScalarEvolution/ptrtoint.ll b/llvm/test/Analysis/ScalarEvolution/ptrtoint.ll
index e784d25385980..72f59682b023a 100644
--- a/llvm/test/Analysis/ScalarEvolution/ptrtoint.ll
+++ b/llvm/test/Analysis/ScalarEvolution/ptrtoint.ll
@@ -192,7 +192,7 @@ define void @ptrtoint_of_gep(ptr %in, ptr %out0) {
; X64-LABEL: 'ptrtoint_of_gep'
; X64-NEXT: Classifying expressions for: @ptrtoint_of_gep
; X64-NEXT: %in_adj = getelementptr inbounds i8, ptr %in, i64 42
-; X64-NEXT: --> (42 + %in) U: full-set S: full-set
+; X64-NEXT: --> (42 + %in)(u nuw) U: full-set S: full-set
; X64-NEXT: %p0 = ptrtoint ptr %in_adj to i64
; X64-NEXT: --> (42 + (ptrtoint ptr %in to i64)) U: full-set S: full-set
; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_gep
@@ -200,7 +200,7 @@ define void @ptrtoint_of_gep(ptr %in, ptr %out0) {
; X32-LABEL: 'ptrtoint_of_gep'
; X32-NEXT: Classifying expressions for: @ptrtoint_of_gep
; X32-NEXT: %in_adj = getelementptr inbounds i8, ptr %in, i64 42
-; X32-NEXT: --> (42 + %in) U: full-set S: full-set
+; X32-NEXT: --> (42 + %in)(u nuw) U: full-set S: full-set
; X32-NEXT: %p0 = ptrtoint ptr %in_adj to i64
; X32-NEXT: --> (zext i32 (42 + (ptrtoint ptr %in to i32)) to i64) U: [0,4294967296) S: [0,4294967296)
; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_gep
diff --git a/llvm/test/Analysis/ScalarEvolution/sdiv.ll b/llvm/test/Analysis/ScalarEvolution/sdiv.ll
index e01f84fb2226e..ce531a967f634 100644
--- a/llvm/test/Analysis/ScalarEvolution/sdiv.ll
+++ b/llvm/test/Analysis/ScalarEvolution/sdiv.ll
@@ -18,7 +18,7 @@ define dso_local void @_Z4loopi(i32 %width) local_unnamed_addr #0 {
; CHECK-NEXT: %idxprom = sext i32 %rem to i64
; CHECK-NEXT: --> ({0,+,1}<nuw><nsw><%for.cond> /u 2) U: [0,2147483648) S: [0,2147483648) Exits: ((zext i32 %width to i64) /u 2) LoopDispositions: { %for.cond: Computable }
; CHECK-NEXT: %arrayidx = getelementptr inbounds [2 x i32], ptr %storage, i64 0, i64 %idxprom
-; CHECK-NEXT: --> ((4 * ({0,+,1}<nuw><nsw><%for.cond> /u 2))<nuw><nsw> + %storage) U: [0,-3) S: [-9223372036854775808,9223372036854775805) Exits: ((4 * ((zext i32 %width to i64) /u 2))<nuw><nsw> + %storage) LoopDispositions: { %for.cond: Computable }
+; CHECK-NEXT: --> ((4 * ({0,+,1}<nuw><nsw><%for.cond> /u 2))<nuw><nsw> + %storage)(u nuw) U: [0,-3) S: [-9223372036854775808,9223372036854775805) Exits: ((4 * ((zext i32 %width to i64) /u 2))<nuw><nsw> + %storage) LoopDispositions: { %for.cond: Computable }
; CHECK-NEXT: %1 = load i32, ptr %arrayidx, align 4
; CHECK-NEXT: --> %1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }
; CHECK-NEXT: %call = call i32 @_Z3adji(i32 %1)
diff --git a/llvm/test/Analysis/ScalarEvolution/srem.ll b/llvm/test/Analysis/ScalarEvolution/srem.ll
index ff898c963d0dc..6ea3921880a2d 100644
--- a/llvm/test/Analysis/ScalarEvolution/srem.ll
+++ b/llvm/test/Analysis/ScalarEvolution/srem.ll
@@ -18,7 +18,7 @@ define dso_local void @_Z4loopi(i32 %width) local_unnamed_addr #0 {
; CHECK-NEXT: %idxprom = sext i32 %rem to i64
; CHECK-NEXT: --> (zext i1 {false,+,true}<%for.cond> to i64) U: [0,2) S: [0,2) Exits: (zext i1 (trunc i32 %width to i1) to i64) LoopDispositions: { %for.cond: Computable }
; CHECK-NEXT: %arrayidx = getelementptr inbounds [2 x i32], ptr %storage, i64 0, i64 %idxprom
-; CHECK-NEXT: --> ((4 * (zext i1 {false,+,true}<%for.cond> to i64))<nuw><nsw> + %storage) U: [4,-7) S: [-9223372036854775808,9223372036854775805) Exits: ((4 * (zext i1 (trunc i32 %width to i1) to i64))<nuw><nsw> + %storage) LoopDispositions: { %for.cond: Computable }
+; CHECK-NEXT: --> ((4 * (zext i1 {false,+,true}<%for.cond> to i64))<nuw><nsw> + %storage)(u nuw) U: [4,-7) S: [-9223372036854775808,9223372036854775805) Exits: ((4 * (zext i1 (trunc i32 %width to i1) to i64))<nuw><nsw> + %storage) LoopDispositions: { %for.cond: Computable }
; CHECK-NEXT: %1 = load i32, ptr %arrayidx, align 4
; CHECK-NEXT: --> %1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }
; CHECK-NEXT: %call = call i32 @_Z3adji(i32 %1)
More information about the llvm-branch-commits
mailing list