We know that certain pointers (e.g. non-extern-weak globals or allocas in default address space) are not null, in which case the lowest address they can be allocated at is their alignment. This allows us to calculate better exit counts for loops that have an additional null check in the guarding condition (see alloca_icmp_null_exit_count). Differential Revision: https://reviews.llvm.org/D153624
76 lines
4.0 KiB
LLVM
76 lines
4.0 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
|
|
; RUN: opt < %s "-passes=print<scalar-evolution>" -disable-output 2>&1 | FileCheck %s
|
|
|
|
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
|
target triple = "x86_64-unknown-linux-gnu"
|
|
|
|
define dso_local void @_Z4loopi(i32 %width) local_unnamed_addr #0 {
|
|
; CHECK-LABEL: '_Z4loopi'
|
|
; CHECK-NEXT: Classifying expressions for: @_Z4loopi
|
|
; CHECK-NEXT: %storage = alloca [2 x i32], align 4
|
|
; CHECK-NEXT: --> %storage U: [4,-11) S: [-9223372036854775808,9223372036854775805)
|
|
; CHECK-NEXT: %0 = bitcast ptr %storage to ptr
|
|
; CHECK-NEXT: --> %storage U: [4,-11) S: [-9223372036854775808,9223372036854775805)
|
|
; CHECK-NEXT: %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
|
|
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%for.cond> U: [0,-2147483648) S: [0,-2147483648) Exits: %width LoopDispositions: { %for.cond: Computable }
|
|
; CHECK-NEXT: %rem = sdiv i32 %i.0, 2
|
|
; CHECK-NEXT: --> ({0,+,1}<nuw><nsw><%for.cond> /u 2) U: [0,1073741824) S: [0,1073741824) Exits: (%width /u 2) LoopDispositions: { %for.cond: Computable }
|
|
; 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: %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)
|
|
; CHECK-NEXT: --> %call U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }
|
|
; CHECK-NEXT: %2 = load i32, ptr %arrayidx, align 4
|
|
; CHECK-NEXT: --> %2 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }
|
|
; CHECK-NEXT: %add = add nsw i32 %2, %call
|
|
; CHECK-NEXT: --> (%2 + %call) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }
|
|
; CHECK-NEXT: %inc = add nsw i32 %i.0, 1
|
|
; CHECK-NEXT: --> {1,+,1}<nuw><%for.cond> U: [1,0) S: [1,0) Exits: (1 + %width) LoopDispositions: { %for.cond: Computable }
|
|
; CHECK-NEXT: Determining loop execution counts for: @_Z4loopi
|
|
; CHECK-NEXT: Loop %for.cond: backedge-taken count is %width
|
|
; CHECK-NEXT: Loop %for.cond: constant max backedge-taken count is -1
|
|
; CHECK-NEXT: Loop %for.cond: symbolic max backedge-taken count is %width
|
|
; CHECK-NEXT: Loop %for.cond: Predicated backedge-taken count is %width
|
|
; CHECK-NEXT: Predicates:
|
|
; CHECK: Loop %for.cond: Trip multiple is 1
|
|
;
|
|
entry:
|
|
%storage = alloca [2 x i32], align 4
|
|
%0 = bitcast ptr %storage to ptr
|
|
call void @llvm.lifetime.start.p0(i64 8, ptr %0) #4
|
|
call void @llvm.memset.p0.i64(ptr align 4 %0, i8 0, i64 8, i1 false)
|
|
br label %for.cond
|
|
|
|
for.cond:
|
|
%i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
|
|
%cmp = icmp ne i32 %i.0, %width
|
|
br i1 %cmp, label %for.body, label %for.cond.cleanup
|
|
|
|
for.cond.cleanup:
|
|
call void @llvm.lifetime.end.p0(i64 8, ptr %0) #4
|
|
ret void
|
|
|
|
for.body:
|
|
%rem = sdiv i32 %i.0, 2
|
|
%idxprom = sext i32 %rem to i64
|
|
%arrayidx = getelementptr inbounds [2 x i32], ptr %storage, i64 0, i64 %idxprom
|
|
%1 = load i32, ptr %arrayidx, align 4
|
|
%call = call i32 @_Z3adji(i32 %1)
|
|
%2 = load i32, ptr %arrayidx, align 4
|
|
%add = add nsw i32 %2, %call
|
|
store i32 %add, ptr %arrayidx, align 4
|
|
%inc = add nsw i32 %i.0, 1
|
|
br label %for.cond
|
|
}
|
|
|
|
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1
|
|
|
|
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #2
|
|
|
|
declare dso_local i32 @_Z3adji(i32) local_unnamed_addr #3
|
|
|
|
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1
|