[SCEV] Fix nsw flags for GEP expressions

The SCEV code for constructing GEP expressions currently assumes
that the addition of the base and all the offsets is nsw if the GEP
is inbounds. While the addition of the offsets is indeed nsw, the
addition to the base address is not, as the base address is
interpreted as an unsigned value.

Fix the GEP expression code to not assume nsw for the base+offset
calculation. However, do assume nuw if we know that the offset is
non-negative. With this, we use the same behavior as the
construction of GEP addrecs does. (Modulo the fact that we
disregard SCEV unification, as the pre-existing FIXME points out).

Differential Revision: https://reviews.llvm.org/D90648
This commit is contained in:
Nikita Popov 2020-11-02 21:40:08 +01:00
parent df84941dce
commit f3124a46c1
17 changed files with 89 additions and 74 deletions

View File

@ -3437,12 +3437,12 @@ ScalarEvolution::getGEPExpr(GEPOperator *GEP,
// flow and the no-overflow bits may not be valid for the expression in any
// context. This can be fixed similarly to how these flags are handled for
// adds.
SCEV::NoWrapFlags Wrap = GEP->isInBounds() ? SCEV::FlagNSW
: SCEV::FlagAnyWrap;
SCEV::NoWrapFlags OffsetWrap =
GEP->isInBounds() ? SCEV::FlagNSW : SCEV::FlagAnyWrap;
Type *CurTy = GEP->getType();
bool FirstIter = true;
SmallVector<const SCEV *, 4> AddOps{BaseExpr};
SmallVector<const SCEV *, 4> Offsets;
for (const SCEV *IndexExpr : IndexExprs) {
// Compute the (potentially symbolic) offset in bytes for this index.
if (StructType *STy = dyn_cast<StructType>(CurTy)) {
@ -3450,7 +3450,7 @@ ScalarEvolution::getGEPExpr(GEPOperator *GEP,
ConstantInt *Index = cast<SCEVConstant>(IndexExpr)->getValue();
unsigned FieldNo = Index->getZExtValue();
const SCEV *FieldOffset = getOffsetOfExpr(IntIdxTy, STy, FieldNo);
AddOps.push_back(FieldOffset);
Offsets.push_back(FieldOffset);
// Update CurTy to the type of the field at Index.
CurTy = STy->getTypeAtIndex(Index);
@ -3470,13 +3470,23 @@ ScalarEvolution::getGEPExpr(GEPOperator *GEP,
IndexExpr = getTruncateOrSignExtend(IndexExpr, IntIdxTy);
// Multiply the index by the element size to compute the element offset.
const SCEV *LocalOffset = getMulExpr(IndexExpr, ElementSize, Wrap);
AddOps.push_back(LocalOffset);
const SCEV *LocalOffset = getMulExpr(IndexExpr, ElementSize, OffsetWrap);
Offsets.push_back(LocalOffset);
}
}
// Add the base and all the offsets together.
return getAddExpr(AddOps, Wrap);
// Handle degenerate case of GEP without offsets.
if (Offsets.empty())
return BaseExpr;
// Add the offsets together, assuming nsw if inbounds.
const SCEV *Offset = getAddExpr(Offsets, OffsetWrap);
// Add the base address and the offset. We cannot use the nsw flag, as the
// base address is unsigned. However, if we know that the offset is
// non-negative, we can use nuw.
SCEV::NoWrapFlags BaseWrap = GEP->isInBounds() && isKnownNonNegative(Offset)
? SCEV::FlagNUW : SCEV::FlagAnyWrap;
return getAddExpr(BaseExpr, Offset, BaseWrap);
}
std::tuple<SCEV *, FoldingSetNodeID, void *>

View File

@ -46,10 +46,10 @@ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
; CHECK-NEXT: {0,+,1}<%for.body> Added Flags: <nusw>
; CHECK: Expressions re-written:
; CHECK-NEXT: [PSE] %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom:
; CHECK-NEXT: ((4 * (zext i32 {1,+,1}<%for.body> to i64))<nuw><nsw> + %a)<nsw>
; CHECK-NEXT: ((4 * (zext i32 {1,+,1}<%for.body> to i64))<nuw><nsw> + %a)<nuw>
; CHECK-NEXT: --> {(4 + %a),+,4}<%for.body>
; CHECK-NEXT: [PSE] %arrayidx4 = getelementptr inbounds i32, i32* %b, i64 %conv11:
; CHECK-NEXT: ((4 * (zext i32 {0,+,1}<%for.body> to i64))<nuw><nsw> + %b)<nsw>
; CHECK-NEXT: ((4 * (zext i32 {0,+,1}<%for.body> to i64))<nuw><nsw> + %b)<nuw>
; CHECK-NEXT: --> {%b,+,4}<%for.body>
define void @test1(i64 %x, i32* %a, i32* %b) {
entry:

View File

@ -97,11 +97,11 @@ for.end: ; preds = %for.body
; CHECK-NEXT: Grouped accesses:
; CHECK-NEXT: Group {{.*}}[[ZERO]]:
; CHECK-NEXT: (Low: %c High: (80 + %c))
; CHECK-NEXT: Member: {(2 + %c)<nsw>,+,4}
; CHECK-NEXT: Member: {(2 + %c)<nuw>,+,4}
; CHECK-NEXT: Member: {%c,+,4}
; CHECK-NEXT: Group {{.*}}[[ONE]]:
; CHECK-NEXT: (Low: %a High: (42 + %a))
; CHECK-NEXT: Member: {(2 + %a)<nsw>,+,2}
; CHECK-NEXT: Member: {(2 + %a)<nuw>,+,2}
; CHECK-NEXT: Member: {%a,+,2}
; CHECK-NEXT: Group {{.*}}[[TWO]]:
; CHECK-NEXT: (Low: %b High: (40 + %b))
@ -169,7 +169,7 @@ for.end: ; preds = %for.body
; CHECK-NEXT: Grouped accesses:
; CHECK-NEXT: Group {{.*}}[[ZERO]]:
; CHECK-NEXT: (Low: %c High: (80 + %c))
; CHECK-NEXT: Member: {(2 + %c)<nsw>,+,4}
; CHECK-NEXT: Member: {(2 + %c)<nuw>,+,4}
; CHECK-NEXT: Member: {%c,+,4}
; CHECK-NEXT: Group {{.*}}[[ONE]]:
; CHECK-NEXT: (Low: %a High: (42 + %a))
@ -247,8 +247,8 @@ for.end: ; preds = %for.body
; CHECK-NEXT: %arrayidxA2 = getelementptr i16, i16* %a, i64 %ind2
; CHECK-NEXT: Grouped accesses:
; CHECK-NEXT: Group {{.*}}[[ZERO]]:
; CHECK-NEXT: (Low: ((2 * %offset) + %a)<nsw> High: (10000 + (2 * %offset) + %a))
; CHECK-NEXT: Member: {((2 * %offset) + %a)<nsw>,+,2}<nsw><%for.body>
; CHECK-NEXT: (Low: ((2 * %offset) + %a) High: (10000 + (2 * %offset) + %a))
; CHECK-NEXT: Member: {((2 * %offset) + %a),+,2}<nw><%for.body>
; CHECK-NEXT: Group {{.*}}[[ONE]]:
; CHECK-NEXT: (Low: %a High: (10000 + %a))
; CHECK-NEXT: Member: {%a,+,2}<nw><%for.body>

View File

@ -58,8 +58,8 @@ for.end: ; preds = %for.body
; Here it is not obvious what the limits are, since 'step' could be negative.
; CHECK: Low: ((60000 + %a)<nsw> umin (60000 + (-40000 * %step) + %a))
; CHECK: High: (4 + ((60000 + %a)<nsw> umax (60000 + (-40000 * %step) + %a)))
; CHECK: Low: ((60000 + %a) umin (60000 + (-40000 * %step) + %a))
; CHECK: High: (4 + ((60000 + %a) umax (60000 + (-40000 * %step) + %a)))
define void @g(i64 %step) {
entry:

View File

@ -365,7 +365,7 @@ for.end: ; preds = %for.body
; LAA-NEXT: {((2 * (sext i32 (2 * (trunc i64 %N to i32)) to i64))<nsw> + %a),+,-4}<%for.body> Added Flags: <nusw>
; LAA: [PSE] %arrayidxA = getelementptr inbounds i16, i16* %a, i32 %mul:
; LAA-NEXT: ((2 * (sext i32 {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> to i64))<nsw> + %a)<nsw>
; LAA-NEXT: ((2 * (sext i32 {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> to i64))<nsw> + %a)
; LAA-NEXT: --> {((2 * (sext i32 (2 * (trunc i64 %N to i32)) to i64))<nsw> + %a),+,-4}<%for.body>
; LV-LABEL: f5

View File

@ -29,7 +29,7 @@ define i32 @d(i32 %base) {
; CHECK-NEXT: %idxprom = sext i32 %f.0 to i64
; CHECK-NEXT: --> {(sext i32 %base to i64),+,1}<nsw><%for.cond> U: [-2147483648,-9223372036854775808) S: [-2147483648,-9223372036854775808) Exits: <<Unknown>> LoopDispositions: { %for.cond: Computable }
; CHECK-NEXT: %arrayidx = getelementptr inbounds [1 x [1 x i8]], [1 x [1 x i8]]* %e, i64 0, i64 %idxprom
; CHECK-NEXT: --> {((sext i32 %base to i64) + %e)<nsw>,+,1}<nsw><%for.cond> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Computable }
; CHECK-NEXT: --> {((sext i32 %base to i64) + %e),+,1}<nw><%for.cond> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Computable }
; CHECK-NEXT: %1 = load i32*, i32** @c, align 8
; CHECK-NEXT: --> %1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }
; CHECK-NEXT: %sub.ptr.lhs.cast = ptrtoint i32* %1 to i64
@ -39,7 +39,7 @@ define i32 @d(i32 %base) {
; CHECK-NEXT: %sub.ptr.div = sdiv exact i64 %sub.ptr.sub, 4
; CHECK-NEXT: --> %sub.ptr.div U: full-set S: [-2305843009213693952,2305843009213693952) Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }
; CHECK-NEXT: %arrayidx1 = getelementptr inbounds [1 x i8], [1 x i8]* %arrayidx, i64 0, i64 %sub.ptr.div
; CHECK-NEXT: --> ({((sext i32 %base to i64) + %e)<nsw>,+,1}<nsw><%for.cond> + %sub.ptr.div)<nsw> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }
; CHECK-NEXT: --> ({((sext i32 %base to i64) + %e),+,1}<nw><%for.cond> + %sub.ptr.div) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }
; CHECK-NEXT: %2 = load i8, i8* %arrayidx1, align 1
; CHECK-NEXT: --> %2 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }
; CHECK-NEXT: %conv = sext i8 %2 to i32

View File

@ -17,11 +17,11 @@ define i32 @test1() nounwind readnone {
; CHECK-NEXT: %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%for.body> U: [0,50) S: [0,50) Exits: 49 LoopDispositions: { %for.body: Computable }
; CHECK-NEXT: %arrayidx = getelementptr inbounds [50 x i32], [50 x i32]* @arr1, i32 0, i32 %i.03
; CHECK-NEXT: --> {@arr1,+,4}<nsw><%for.body> U: [0,-3) S: [-2147483648,2147483645) Exits: (196 + @arr1) LoopDispositions: { %for.body: Computable }
; CHECK-NEXT: --> {@arr1,+,4}<nuw><%for.body> U: [0,-3) S: [-2147483648,2147483645) Exits: (196 + @arr1) LoopDispositions: { %for.body: Computable }
; CHECK-NEXT: %0 = load i32, i32* %arrayidx, align 4
; CHECK-NEXT: --> %0 U: full-set S: full-set Exits: 50 LoopDispositions: { %for.body: Variant }
; CHECK-NEXT: %arrayidx1 = getelementptr inbounds [50 x i32], [50 x i32]* @arr2, i32 0, i32 %i.03
; CHECK-NEXT: --> {@arr2,+,4}<nsw><%for.body> U: [0,-3) S: [-2147483648,2147483645) Exits: (196 + @arr2) LoopDispositions: { %for.body: Computable }
; CHECK-NEXT: --> {@arr2,+,4}<nuw><%for.body> U: [0,-3) S: [-2147483648,2147483645) Exits: (196 + @arr2) LoopDispositions: { %for.body: Computable }
; CHECK-NEXT: %1 = load i32, i32* %arrayidx1, align 4
; CHECK-NEXT: --> %1 U: full-set S: full-set Exits: 0 LoopDispositions: { %for.body: Variant }
; CHECK-NEXT: %add = add i32 %0, %sum.04
@ -74,7 +74,7 @@ define i32 @test2() nounwind uwtable readonly {
; CHECK-NEXT: %n.01 = phi %struct.ListNode* [ bitcast ({ %struct.ListNode*, i32, [4 x i8] }* @node5 to %struct.ListNode*), %entry ], [ %1, %for.body ]
; CHECK-NEXT: --> %n.01 U: full-set S: full-set Exits: @node1 LoopDispositions: { %for.body: Variant }
; CHECK-NEXT: %i = getelementptr inbounds %struct.ListNode, %struct.ListNode* %n.01, i64 0, i32 1
; CHECK-NEXT: --> (4 + %n.01)<nsw> U: [-2147483644,-2147483648) S: [-2147483644,-2147483648) Exits: (4 + @node1)<nuw><nsw> LoopDispositions: { %for.body: Variant }
; CHECK-NEXT: --> (4 + %n.01)<nuw> U: [4,0) S: [4,0) Exits: (4 + @node1)<nuw><nsw> LoopDispositions: { %for.body: Variant }
; CHECK-NEXT: %0 = load i32, i32* %i, align 4
; CHECK-NEXT: --> %0 U: full-set S: full-set Exits: 0 LoopDispositions: { %for.body: Variant }
; CHECK-NEXT: %add = add nsw i32 %0, %sum.02

View File

@ -10,7 +10,7 @@ define void @test_guard_less_than_16(i32* nocapture %a, i64 %i) {
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
; CHECK-NEXT: --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %a, i64 %iv
; CHECK-NEXT: --> {((4 * %i) + %a)<nsw>,+,4}<nsw><%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: --> {((4 * %i) + %a),+,4}<nw><%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_less_than_16
@ -42,7 +42,7 @@ define void @test_guard_less_than_16_operands_swapped(i32* nocapture %a, i64 %i)
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
; CHECK-NEXT: --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %a, i64 %iv
; CHECK-NEXT: --> {((4 * %i) + %a)<nsw>,+,4}<nsw><%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: --> {((4 * %i) + %a),+,4}<nw><%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_less_than_16_operands_swapped
@ -74,7 +74,7 @@ define void @test_guard_less_than_16_branches_flipped(i32* nocapture %a, i64 %i)
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
; CHECK-NEXT: --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %a, i64 %iv
; CHECK-NEXT: --> {((4 * %i) + %a)<nsw>,+,4}<nsw><%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: --> {((4 * %i) + %a),+,4}<nw><%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_less_than_16_branches_flipped
@ -106,7 +106,7 @@ define void @test_guard_uge_16_branches_flipped(i32* nocapture %a, i64 %i) {
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
; CHECK-NEXT: --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %a, i64 %iv
; CHECK-NEXT: --> {((4 * %i) + %a)<nsw>,+,4}<nsw><%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: --> {((4 * %i) + %a),+,4}<nw><%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_uge_16_branches_flipped
@ -138,7 +138,7 @@ define void @test_guard_eq_12(i32* nocapture %a, i64 %N) {
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: %N LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %a, i64 %iv
; CHECK-NEXT: --> {%a,+,4}<nsw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,14) S: [1,14) Exits: (1 + %N) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_eq_12
@ -170,7 +170,7 @@ define void @test_guard_ule_12(i32* nocapture %a, i64 %N) {
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: %N LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %a, i64 %iv
; CHECK-NEXT: --> {%a,+,4}<nsw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,14) S: [1,14) Exits: (1 + %N) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_ule_12
@ -202,7 +202,7 @@ define void @test_guard_ule_12_step2(i32* nocapture %a, i64 %N) {
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,2}<nuw><nsw><%loop> U: [0,-9223372036854775808) S: [0,9223372036854775807) Exits: (2 * (%N /u 2))<nuw> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %a, i64 %iv
; CHECK-NEXT: --> {%a,+,8}<nsw><%loop> U: full-set S: full-set Exits: ((8 * (%N /u 2)) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: --> {%a,+,8}<nuw><%loop> U: full-set S: full-set Exits: ((8 * (%N /u 2)) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 2
; CHECK-NEXT: --> {2,+,2}<nuw><%loop> U: [2,-1) S: [-9223372036854775808,9223372036854775807) Exits: (2 + (2 * (%N /u 2))<nuw>) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_ule_12_step2
@ -234,7 +234,7 @@ define void @test_multiple_const_guards_order1(i32* nocapture %a, i64 %i) {
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,10) S: [0,10) Exits: %i LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %a, i64 %iv
; CHECK-NEXT: --> {%a,+,4}<nsw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,11) S: [1,11) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_multiple_const_guards_order1
@ -270,7 +270,7 @@ define void @test_multiple_const_guards_order2(i32* nocapture %a, i64 %i) {
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,10) S: [0,10) Exits: %i LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %a, i64 %iv
; CHECK-NEXT: --> {%a,+,4}<nsw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,11) S: [1,11) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_multiple_const_guards_order2
@ -307,7 +307,7 @@ define void @test_multiple_var_guards_order1(i32* nocapture %a, i64 %i, i64 %N)
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-9223372036854775808) S: [0,-9223372036854775808) Exits: %i LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %a, i64 %iv
; CHECK-NEXT: --> {%a,+,4}<nsw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_multiple_var_guards_order1
@ -344,7 +344,7 @@ define void @test_multiple_var_guards_order2(i32* nocapture %a, i64 %i, i64 %N)
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-9223372036854775808) S: [0,-9223372036854775808) Exits: %i LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %a, i64 %iv
; CHECK-NEXT: --> {%a,+,4}<nsw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_multiple_var_guards_order2
@ -381,7 +381,7 @@ define void @test_multiple_var_guards_cycle(i32* nocapture %a, i64 %i, i64 %N) {
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-9223372036854775808) S: [0,-9223372036854775808) Exits: %N LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %a, i64 %iv
; CHECK-NEXT: --> {%a,+,4}<nsw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: (1 + %N) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_multiple_var_guards_cycle
@ -417,7 +417,7 @@ define void @test_guard_ult_ne(i32* nocapture readonly %data, i64 %count) {
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %data, i64 %iv
; CHECK-NEXT: --> {%data,+,4}<nw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_ult_ne
@ -456,7 +456,7 @@ define void @test_guard_and_assume(i32* nocapture readonly %data, i64 %count) {
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %data, i64 %iv
; CHECK-NEXT: --> {%data,+,4}<nw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_and_assume
@ -537,7 +537,7 @@ define void @crash(i8* %ptr) {
; CHECK-NEXT: %lastout.2271 = phi i8* [ %incdec.ptr126, %while.body125 ], [ %ptr, %while.end117 ]
; CHECK-NEXT: --> {%ptr,+,1}<nuw><%while.body125> U: full-set S: full-set Exits: {-2,+,-1}<nw><%while.cond111> LoopDispositions: { %while.body125: Computable }
; CHECK-NEXT: %incdec.ptr126 = getelementptr inbounds i8, i8* %lastout.2271, i64 1
; CHECK-NEXT: --> {(1 + %ptr)<nsw>,+,1}<nuw><%while.body125> U: full-set S: full-set Exits: {-1,+,-1}<nw><%while.cond111> LoopDispositions: { %while.body125: Computable }
; CHECK-NEXT: --> {(1 + %ptr)<nuw>,+,1}<nuw><%while.body125> U: [1,0) S: [1,0) Exits: {-1,+,-1}<nw><%while.cond111> LoopDispositions: { %while.body125: Computable }
; CHECK-NEXT: Determining loop execution counts for: @crash
; CHECK-NEXT: Loop %while.body125: backedge-taken count is {(-2 + (-1 * %ptr)),+,-1}<nw><%while.cond111>
; CHECK-NEXT: Loop %while.body125: max backedge-taken count is -1

View File

@ -210,7 +210,7 @@ define void @f3(i8* %x_addr, i8* %y_addr, i32* %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, i8* bitcast ({ %union, [2000 x i8] }* @tmp_addr to i8*), i64 %sunkaddr3
; CHECK-NEXT: --> ((4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr)<nsw> U: [0,-3) S: [-9223372036854775808,9223372036854775805)
; CHECK-NEXT: --> ((4 * (zext i32 (4 + (4 * (%tmp /u 4))<nuw>) to i64))<nuw><nsw> + @tmp_addr)<nuw> U: [0,-3) S: [-9223372036854775808,9223372036854775805)
; CHECK-NEXT: %sunkaddr5 = getelementptr inbounds i8, i8* %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: %addr4.cast = bitcast i8* %sunkaddr5 to i32*

View File

@ -26,7 +26,7 @@ bb: ; preds = %bb.nph, %bb1
%1 = sext i32 %i.01 to i64 ; <i64> [#uses=1]
; CHECK: %2 = getelementptr inbounds double, double* %d, i64 %1
; CHECK: --> {%d,+,16}<nsw><%bb>
; CHECK: --> {%d,+,16}<nuw><%bb>
%2 = getelementptr inbounds double, double* %d, i64 %1 ; <double*> [#uses=1]
%3 = load double, double* %2, align 8 ; <double> [#uses=1]
@ -40,7 +40,7 @@ bb: ; preds = %bb.nph, %bb1
%8 = sext i32 %7 to i64 ; <i64> [#uses=1]
; CHECK: %9 = getelementptr inbounds double, double* %q, i64 %8
; CHECK: {(8 + %q)<nsw>,+,16}<nsw><%bb>
; CHECK: {(8 + %q)<nuw>,+,16}<nuw><%bb>
%9 = getelementptr inbounds double, double* %q, i64 %8 ; <double*> [#uses=1]
; Artificially repeat the above three instructions, this time using
@ -52,7 +52,7 @@ bb: ; preds = %bb.nph, %bb1
%t8 = sext i32 %t7 to i64 ; <i64> [#uses=1]
; CHECK: %t9 = getelementptr inbounds double, double* %q, i64 %t8
; CHECK: {(8 + %q)<nsw>,+,16}<nsw><%bb>
; CHECK: {(8 + %q)<nuw>,+,16}<nuw><%bb>
%t9 = getelementptr inbounds double, double* %q, i64 %t8 ; <double*> [#uses=1]
%10 = load double, double* %9, align 8 ; <double> [#uses=1]

View File

@ -24,7 +24,7 @@ bb: ; preds = %bb.nph, %bb1
%1 = sext i32 %i.01 to i64 ; <i64> [#uses=1]
; CHECK: %2 = getelementptr inbounds double, double* %d, i64 %1
; CHECK: --> {%d,+,16}<nsw><%bb>
; CHECK: --> {%d,+,16}<nuw><%bb>
%2 = getelementptr inbounds double, double* %d, i64 %1 ; <double*> [#uses=1]
%3 = load double, double* %2, align 8 ; <double> [#uses=1]
@ -38,7 +38,7 @@ bb: ; preds = %bb.nph, %bb1
%8 = sext i32 %7 to i64 ; <i64> [#uses=1]
; CHECK: %9 = getelementptr inbounds double, double* %q, i64 %8
; CHECK: {(8 + %q)<nsw>,+,16}<nsw><%bb>
; CHECK: {(8 + %q)<nuw>,+,16}<nuw><%bb>
%9 = getelementptr inbounds double, double* %q, i64 %8 ; <double*> [#uses=1]
; Artificially repeat the above three instructions, this time using
@ -50,7 +50,7 @@ bb: ; preds = %bb.nph, %bb1
%t8 = sext i32 %t7 to i64 ; <i64> [#uses=1]
; CHECK: %t9 = getelementptr inbounds double, double* %q, i64 %t8
; CHECK: {(8 + %q)<nsw>,+,16}<nsw><%bb>
; CHECK: {(8 + %q)<nuw>,+,16}<nuw><%bb>
%t9 = getelementptr inbounds double, double* %q, i64 %t8 ; <double*> [#uses=1]
%10 = load double, double* %9, align 8 ; <double> [#uses=1]

View File

@ -41,7 +41,7 @@ bb1: ; preds = %bb
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%bb>
%tmp9 = getelementptr inbounds double, double* %p, i64 %phitmp ; <double*> [#uses=1]
; CHECK: %tmp9
; CHECK-NEXT: --> {(8 + %p)<nsw>,+,8}<nsw><%bb>
; CHECK-NEXT: --> {(8 + %p)<nuw>,+,8}<nuw><%bb>
%tmp10 = load double, double* %tmp9, align 8 ; <double> [#uses=1]
%tmp11 = fcmp ogt double %tmp10, 2.000000e+00 ; <i1> [#uses=1]
br i1 %tmp11, label %bb, label %bb1.return_crit_edge
@ -69,7 +69,7 @@ for.body.i.i: ; preds = %for.body.i.i, %for.
store i32 0, i32* %__first.addr.02.i.i, align 4
%ptrincdec.i.i = getelementptr inbounds i32, i32* %__first.addr.02.i.i, i64 1
; CHECK: %ptrincdec.i.i
; CHECK-NEXT: --> {(4 + %begin)<nsw>,+,4}<nuw><%for.body.i.i>
; CHECK-NEXT: --> {(4 + %begin)<nuw>,+,4}<nuw><%for.body.i.i>
%cmp.i.i = icmp eq i32* %ptrincdec.i.i, %end
br i1 %cmp.i.i, label %for.cond.for.end_crit_edge.i.i, label %for.body.i.i
@ -95,10 +95,10 @@ for.body.i.i: ; preds = %entry, %for.body.i.
; CHECK: {1,+,1}<nuw><nsw><%for.body.i.i>
%ptrincdec.i.i = getelementptr inbounds i32, i32* %begin, i64 %tmp
; CHECK: %ptrincdec.i.i =
; CHECK: {(4 + %begin)<nsw>,+,4}<nsw><%for.body.i.i>
; CHECK: {(4 + %begin)<nuw>,+,4}<nuw><%for.body.i.i>
%__first.addr.08.i.i = getelementptr inbounds i32, i32* %begin, i64 %indvar.i.i
; CHECK: %__first.addr.08.i.i
; CHECK: {%begin,+,4}<nsw><%for.body.i.i>
; CHECK: {%begin,+,4}<nuw><%for.body.i.i>
store i32 0, i32* %__first.addr.08.i.i, align 4
%cmp.i.i = icmp eq i32* %ptrincdec.i.i, %end
br i1 %cmp.i.i, label %_ZSt4fillIPiiEvT_S1_RKT0_.exit, label %for.body.i.i
@ -127,7 +127,8 @@ exit:
}
; CHECK-LABEL: PR12375
; CHECK: --> {(4 + %arg)<nsw>,+,4}<nuw><%bb1>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (4 + (4 * ((-1 + (-1 * %arg) + ((4 + %arg)<nsw> umax (8 + %arg)<nsw>)) /u 4))<nuw> + %arg)
; CHECK: --> {(4 + %arg)<nuw>,+,4}<nuw><%bb1>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (8 + %arg)<nuw>
define i32 @PR12375(i32* readnone %arg) {
bb:
%tmp = getelementptr inbounds i32, i32* %arg, i64 2
@ -146,7 +147,7 @@ bb7: ; preds = %bb1
}
; CHECK-LABEL: PR12376
; CHECK: --> {(4 + %arg)<nsw>,+,4}<nuw><%bb2>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (4 + (4 * ((-1 + (-1 * %arg) + ((4 + %arg)<nsw> umax %arg1)) /u 4))<nuw> + %arg)
; CHECK: --> {(4 + %arg)<nuw>,+,4}<nuw><%bb2>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (4 + (4 * ((-1 + (-1 * %arg) + ((4 + %arg)<nuw> umax %arg1)) /u 4))<nuw> + %arg)
define void @PR12376(i32* nocapture %arg, i32* nocapture %arg1) {
bb:
br label %bb2

View File

@ -10,7 +10,7 @@ define i8* @FSE_decompress_usingDTable(i8* %arg, i32 %arg1, i32 %arg2, i32 %arg3
; CHECK-LABEL: 'FSE_decompress_usingDTable'
; CHECK-NEXT: Classifying expressions for: @FSE_decompress_usingDTable
; CHECK-NEXT: %i = getelementptr inbounds i8, i8* %arg, i32 %arg2
; CHECK-NEXT: --> (%arg2 + %arg)<nsw> U: full-set S: full-set
; CHECK-NEXT: --> (%arg2 + %arg) U: full-set S: full-set
; CHECK-NEXT: %i4 = sub nsw i32 0, %arg1
; CHECK-NEXT: --> (-1 * %arg1) U: full-set S: full-set
; CHECK-NEXT: %i5 = getelementptr inbounds i8, i8* %i, i32 %i4

View File

@ -194,17 +194,17 @@ define void @ptrtoint_of_gep(i8* %in, i64* %out0) {
; X64-LABEL: 'ptrtoint_of_gep'
; X64-NEXT: Classifying expressions for: @ptrtoint_of_gep
; X64-NEXT: %in_adj = getelementptr inbounds i8, i8* %in, i64 42
; X64-NEXT: --> (42 + %in)<nsw> U: [-9223372036854775766,-9223372036854775808) S: [-9223372036854775766,-9223372036854775808)
; X64-NEXT: --> (42 + %in)<nuw> U: [42,0) S: [42,0)
; X64-NEXT: %p0 = ptrtoint i8* %in_adj to i64
; X64-NEXT: --> (42 + (ptrtoint i8* %in to i64))<nsw> U: [-9223372036854775766,-9223372036854775808) S: [-9223372036854775766,-9223372036854775808)
; X64-NEXT: --> (42 + (ptrtoint i8* %in to i64))<nuw> U: [42,0) S: [42,0)
; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_gep
;
; X32-LABEL: 'ptrtoint_of_gep'
; X32-NEXT: Classifying expressions for: @ptrtoint_of_gep
; X32-NEXT: %in_adj = getelementptr inbounds i8, i8* %in, i64 42
; X32-NEXT: --> (42 + %in)<nsw> U: [-2147483606,-2147483648) S: [-2147483606,-2147483648)
; X32-NEXT: --> (42 + %in)<nuw> U: [42,0) S: [42,0)
; X32-NEXT: %p0 = ptrtoint i8* %in_adj to i64
; X32-NEXT: --> (zext i32 (42 + (ptrtoint i8* %in to i32))<nsw> to i64) U: [0,4294967296) S: [0,4294967296)
; X32-NEXT: --> (42 + (zext i32 (ptrtoint i8* %in to i32) to i64))<nuw><nsw> U: [42,4294967338) S: [42,4294967338)
; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_gep
;
%in_adj = getelementptr inbounds i8, i8* %in, i64 42
@ -224,9 +224,9 @@ define void @ptrtoint_of_addrec(i32* %in, i32 %count) {
; X64-NEXT: %i6 = phi i64 [ 0, %entry ], [ %i9, %loop ]
; X64-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-9223372036854775808) S: [0,-9223372036854775808) Exits: (-1 + (zext i32 %count to i64))<nsw> LoopDispositions: { %loop: Computable }
; X64-NEXT: %i7 = getelementptr inbounds i32, i32* %in, i64 %i6
; X64-NEXT: --> {%in,+,4}<nsw><%loop> U: full-set S: full-set Exits: (-4 + (4 * (zext i32 %count to i64))<nuw><nsw> + %in) LoopDispositions: { %loop: Computable }
; X64-NEXT: --> {%in,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * (zext i32 %count to i64))<nuw><nsw> + %in) LoopDispositions: { %loop: Computable }
; X64-NEXT: %i8 = ptrtoint i32* %i7 to i64
; X64-NEXT: --> {(ptrtoint i32* %in to i64),+,4}<nsw><%loop> U: full-set S: full-set Exits: (-4 + (4 * (zext i32 %count to i64))<nuw><nsw> + (ptrtoint i32* %in to i64)) LoopDispositions: { %loop: Computable }
; X64-NEXT: --> {(ptrtoint i32* %in to i64),+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * (zext i32 %count to i64))<nuw><nsw> + (ptrtoint i32* %in to i64)) LoopDispositions: { %loop: Computable }
; X64-NEXT: %i9 = add nuw nsw i64 %i6, 1
; X64-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: (zext i32 %count to i64) LoopDispositions: { %loop: Computable }
; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_addrec
@ -394,7 +394,7 @@ define void @pr46786_c26_char(i8* %arg, i8* %arg1, i8* %arg2) {
; X64-NEXT: %i13 = add i8 %i12, %i8
; X64-NEXT: --> (%i12 + %i8) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X64-NEXT: %i14 = getelementptr inbounds i8, i8* %i7, i64 1
; X64-NEXT: --> {(1 + %arg)<nsw>,+,1}<nuw><%bb6> U: full-set S: full-set Exits: %arg1 LoopDispositions: { %bb6: Computable }
; X64-NEXT: --> {(1 + %arg)<nuw>,+,1}<nuw><%bb6> U: [1,0) S: [1,0) Exits: %arg1 LoopDispositions: { %bb6: Computable }
; X64-NEXT: Determining loop execution counts for: @pr46786_c26_char
; X64-NEXT: Loop %bb6: backedge-taken count is (-1 + (-1 * %arg) + %arg1)
; X64-NEXT: Loop %bb6: max backedge-taken count is -2
@ -421,7 +421,7 @@ define void @pr46786_c26_char(i8* %arg, i8* %arg1, i8* %arg2) {
; X32-NEXT: %i13 = add i8 %i12, %i8
; X32-NEXT: --> (%i12 + %i8) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X32-NEXT: %i14 = getelementptr inbounds i8, i8* %i7, i64 1
; X32-NEXT: --> {(1 + %arg)<nsw>,+,1}<nuw><%bb6> U: full-set S: full-set Exits: %arg1 LoopDispositions: { %bb6: Computable }
; X32-NEXT: --> {(1 + %arg)<nuw>,+,1}<nuw><%bb6> U: [1,0) S: [1,0) Exits: %arg1 LoopDispositions: { %bb6: Computable }
; X32-NEXT: Determining loop execution counts for: @pr46786_c26_char
; X32-NEXT: Loop %bb6: backedge-taken count is (-1 + (-1 * %arg) + %arg1)
; X32-NEXT: Loop %bb6: max backedge-taken count is -2
@ -475,13 +475,13 @@ define void @pr46786_c26_int(i32* %arg, i32* %arg1, i32* %arg2) {
; X64-NEXT: %i11 = ashr exact i64 %i10, 2
; X64-NEXT: --> ((({0,+,4}<nw><%bb6> smax {0,+,-4}<nw><%bb6>) /u 4) * (1 smin (-1 smax {0,+,4}<nw><%bb6>)))<nsw> U: [-4611686018427387903,4611686018427387904) S: [-4611686018427387903,4611686018427387904) Exits: ((((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> smax (-4 * ((-4 + (-1 * %arg) + %arg1) /u 4))) /u 4) * (1 smin (-1 smax (4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw>)))<nsw> LoopDispositions: { %bb6: Computable }
; X64-NEXT: %i12 = getelementptr inbounds i32, i32* %arg2, i64 %i11
; X64-NEXT: --> ((4 * (({0,+,4}<nw><%bb6> smax {0,+,-4}<nw><%bb6>) /u 4) * (1 smin (-1 smax {0,+,4}<nw><%bb6>))) + %arg2)<nsw> U: full-set S: full-set Exits: ((4 * (((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> smax (-4 * ((-4 + (-1 * %arg) + %arg1) /u 4))) /u 4) * (1 smin (-1 smax (4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw>))) + %arg2)<nsw> LoopDispositions: { %bb6: Computable }
; X64-NEXT: --> ((4 * (({0,+,4}<nw><%bb6> smax {0,+,-4}<nw><%bb6>) /u 4) * (1 smin (-1 smax {0,+,4}<nw><%bb6>))) + %arg2) U: full-set S: full-set Exits: ((4 * (((4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> smax (-4 * ((-4 + (-1 * %arg) + %arg1) /u 4))) /u 4) * (1 smin (-1 smax (4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw>))) + %arg2) LoopDispositions: { %bb6: Computable }
; X64-NEXT: %i13 = load i32, i32* %i12, align 4
; X64-NEXT: --> %i13 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X64-NEXT: %i14 = add nsw i32 %i13, %i8
; X64-NEXT: --> (%i13 + %i8) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X64-NEXT: %i15 = getelementptr inbounds i32, i32* %i7, i64 1
; X64-NEXT: --> {(4 + %arg)<nsw>,+,4}<nuw><%bb6> U: full-set S: full-set Exits: (4 + (4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) LoopDispositions: { %bb6: Computable }
; X64-NEXT: --> {(4 + %arg)<nuw>,+,4}<nuw><%bb6> U: [4,0) S: [4,0) Exits: (4 + (4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) LoopDispositions: { %bb6: Computable }
; X64-NEXT: Determining loop execution counts for: @pr46786_c26_int
; X64-NEXT: Loop %bb6: backedge-taken count is ((-4 + (-1 * %arg) + %arg1) /u 4)
; X64-NEXT: Loop %bb6: max backedge-taken count is 4611686018427387903
@ -504,13 +504,13 @@ define void @pr46786_c26_int(i32* %arg, i32* %arg1, i32* %arg2) {
; X32-NEXT: %i11 = ashr exact i64 %i10, 2
; X32-NEXT: --> ({0,+,1}<nw><%bb6> * (1 smin {0,+,4}<nuw><nsw><%bb6>))<nuw><nsw> U: [0,1073741824) S: [0,1073741824) Exits: (((zext i32* (-4 + (-1 * %arg) + %arg1) to i64) /u 4) * (1 smin (4 * ((zext i32* (-4 + (-1 * %arg) + %arg1) to i64) /u 4))<nuw><nsw>))<nuw><nsw> LoopDispositions: { %bb6: Computable }
; X32-NEXT: %i12 = getelementptr inbounds i32, i32* %arg2, i64 %i11
; X32-NEXT: --> (((trunc i64 (1 smin {0,+,4}<nuw><nsw><%bb6>) to i32) * {0,+,4}<%bb6>) + %arg2)<nsw> U: full-set S: full-set Exits: ((4 * (trunc i64 (1 smin (4 * ((zext i32* (-4 + (-1 * %arg) + %arg1) to i64) /u 4))<nuw><nsw>) to i32) * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg2)<nsw> LoopDispositions: { %bb6: Computable }
; X32-NEXT: --> (((trunc i64 (1 smin {0,+,4}<nuw><nsw><%bb6>) to i32) * {0,+,4}<%bb6>) + %arg2) U: full-set S: full-set Exits: ((4 * (trunc i64 (1 smin (4 * ((zext i32* (-4 + (-1 * %arg) + %arg1) to i64) /u 4))<nuw><nsw>) to i32) * ((-4 + (-1 * %arg) + %arg1) /u 4)) + %arg2) LoopDispositions: { %bb6: Computable }
; X32-NEXT: %i13 = load i32, i32* %i12, align 4
; X32-NEXT: --> %i13 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X32-NEXT: %i14 = add nsw i32 %i13, %i8
; X32-NEXT: --> (%i13 + %i8) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb6: Variant }
; X32-NEXT: %i15 = getelementptr inbounds i32, i32* %i7, i64 1
; X32-NEXT: --> {(4 + %arg)<nsw>,+,4}<nuw><%bb6> U: full-set S: full-set Exits: (4 + (4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) LoopDispositions: { %bb6: Computable }
; X32-NEXT: --> {(4 + %arg)<nuw>,+,4}<nuw><%bb6> U: [4,0) S: [4,0) Exits: (4 + (4 * ((-4 + (-1 * %arg) + %arg1) /u 4))<nuw> + %arg) LoopDispositions: { %bb6: Computable }
; X32-NEXT: Determining loop execution counts for: @pr46786_c26_int
; X32-NEXT: Loop %bb6: backedge-taken count is ((-4 + (-1 * %arg) + %arg1) /u 4)
; X32-NEXT: Loop %bb6: max backedge-taken count is 1073741823

View File

@ -19,7 +19,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], [2 x i32]* %storage, i64 0, i64 %idxprom
; CHECK-NEXT: --> ((4 * ({0,+,1}<nuw><nsw><%for.cond> /u 2))<nuw><nsw> + %storage)<nsw> U: [0,-3) S: [-9223372036854775808,9223372036854775805) Exits: ((4 * ((zext i32 %width to i64) /u 2))<nuw><nsw> + %storage)<nsw> LoopDispositions: { %for.cond: Computable }
; CHECK-NEXT: --> ((4 * ({0,+,1}<nuw><nsw><%for.cond> /u 2))<nuw><nsw> + %storage)<nuw> U: [0,-3) S: [-9223372036854775808,9223372036854775805) Exits: ((4 * ((zext i32 %width to i64) /u 2))<nuw><nsw> + %storage)<nuw> LoopDispositions: { %for.cond: Computable }
; CHECK-NEXT: %1 = load i32, i32* %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)

View File

@ -19,7 +19,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], [2 x i32]* %storage, i64 0, i64 %idxprom
; CHECK-NEXT: --> ((4 * (zext i1 {false,+,true}<%for.cond> to i64))<nuw><nsw> + %storage)<nsw> U: [0,-3) S: [-9223372036854775808,9223372036854775805) Exits: ((4 * (zext i1 (trunc i32 %width to i1) to i64))<nuw><nsw> + %storage)<nsw> LoopDispositions: { %for.cond: Computable }
; CHECK-NEXT: --> ((4 * (zext i1 {false,+,true}<%for.cond> to i64))<nuw><nsw> + %storage)<nuw> U: [0,-3) S: [-9223372036854775808,9223372036854775805) Exits: ((4 * (zext i1 (trunc i32 %width to i1) to i64))<nuw><nsw> + %storage)<nuw> LoopDispositions: { %for.cond: Computable }
; CHECK-NEXT: %1 = load i32, i32* %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)

View File

@ -303,9 +303,8 @@ define void @forward_dep(i32* noalias %arg) {
; CHECK-NEXT: bb:
; CHECK-NEXT: br label [[BB7:%.*]]
; CHECK: bb7:
; CHECK-NEXT: [[DOT013:%.*]] = phi i32 [ 0, [[BB:%.*]] ], [ [[TMP15:%.*]], [[BB25:%.*]] ]
; CHECK-NEXT: [[INDVARS_IV22:%.*]] = phi i64 [ 0, [[BB]] ], [ [[INDVARS_IV_NEXT3:%.*]], [[BB25]] ]
; CHECK-NEXT: [[INDVARS_IV1:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BB25]] ], [ 0, [[BB]] ]
; CHECK-NEXT: [[DOT013:%.*]] = phi i32 [ 0, [[BB:%.*]] ], [ [[TMP15:%.*]], [[BB14:%.*]] ]
; CHECK-NEXT: [[INDVARS_IV22:%.*]] = phi i64 [ 0, [[BB]] ], [ [[INDVARS_IV_NEXT3:%.*]], [[BB14]] ]
; CHECK-NEXT: [[TMP:%.*]] = add nsw i32 [[DOT013]], -3
; CHECK-NEXT: [[TMP8:%.*]] = add nuw nsw i64 [[INDVARS_IV22]], 3
; CHECK-NEXT: [[TMP9:%.*]] = trunc i64 [[TMP8]] to i32
@ -314,8 +313,16 @@ define void @forward_dep(i32* noalias %arg) {
; CHECK-NEXT: [[TMP12:%.*]] = srem i32 [[TMP10]], [[TMP11]]
; CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds i32, i32* [[ARG:%.*]], i64 [[INDVARS_IV22]]
; CHECK-NEXT: store i32 [[TMP12]], i32* [[TMP13]], align 4
; CHECK-NEXT: br label [[BB14:%.*]]
; CHECK-NEXT: br label [[BB14]]
; CHECK: bb14:
; CHECK-NEXT: [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV22]], 1
; CHECK-NEXT: [[TMP15]] = add nuw nsw i32 [[DOT013]], 1
; CHECK-NEXT: [[EXITCOND4:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT3]], 100
; CHECK-NEXT: br i1 [[EXITCOND4]], label [[BB7]], label [[BB19_PREHEADER:%.*]]
; CHECK: bb19.preheader:
; CHECK-NEXT: br label [[BB19:%.*]]
; CHECK: bb19:
; CHECK-NEXT: [[INDVARS_IV1:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BB25:%.*]] ], [ 0, [[BB19_PREHEADER]] ]
; CHECK-NEXT: [[TMP20:%.*]] = add nsw i64 [[INDVARS_IV1]], -3
; CHECK-NEXT: [[TMP21:%.*]] = getelementptr inbounds i32, i32* [[ARG]], i64 [[TMP20]]
; CHECK-NEXT: [[TMP22:%.*]] = load i32, i32* [[TMP21]], align 4
@ -324,12 +331,9 @@ define void @forward_dep(i32* noalias %arg) {
; CHECK-NEXT: store i32 [[TMP23]], i32* [[TMP24]], align 4
; CHECK-NEXT: br label [[BB25]]
; CHECK: bb25:
; CHECK-NEXT: [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV22]], 1
; CHECK-NEXT: [[TMP15]] = add nuw nsw i32 [[DOT013]], 1
; CHECK-NEXT: [[EXITCOND4:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT3]], 100
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV1]], 1
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], 100
; CHECK-NEXT: br i1 [[EXITCOND]], label [[BB7]], label [[BB26:%.*]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[BB19]], label [[BB26:%.*]]
; CHECK: bb26:
; CHECK-NEXT: ret void
;