Imported Upstream version 5.18.0.205

Former-commit-id: 7f59f7e792705db773f1caecdaa823092f4e2927
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-11-16 08:20:38 +00:00
parent 5cd5df71cc
commit 8e12397d70
28486 changed files with 3867013 additions and 66 deletions

View File

@ -0,0 +1,64 @@
; Test that the lazy value analysis gets invalidated when its dependencies go
; away. Sadly, you can neither print nor verify LVI so we just have to require
; it and check that the pass manager does the right thing.
;
; Check basic invalidation.
; RUN: opt -disable-output -disable-verify -debug-pass-manager %s 2>&1 \
; RUN: -passes='require<lazy-value-info>,invalidate<lazy-value-info>,require<lazy-value-info>' \
; RUN: | FileCheck %s --check-prefix=CHECK-INVALIDATE
; CHECK-INVALIDATE: Running pass: RequireAnalysisPass
; CHECK-INVALIDATE: Running analysis: LazyValueAnalysis
; CHECK-INVALIDATE: Running pass: InvalidateAnalysisPass
; CHECK-INVALIDATE: Invalidating analysis: LazyValueAnalysis
; CHECK-INVALIDATE: Running pass: RequireAnalysisPass
; CHECK-INVALIDATE: Running analysis: LazyValueAnalysis
;
; Check DomTree specifically.
; RUN: opt -disable-output -disable-verify -debug-pass-manager %s 2>&1 \
; RUN: -passes='require<domtree>,require<lazy-value-info>,invalidate<domtree>,require<lazy-value-info>' \
; RUN: | FileCheck %s --check-prefix=CHECK-DT-INVALIDATE
; CHECK-DT-INVALIDATE: Running pass: RequireAnalysisPass
; CHECK-DT-INVALIDATE: Running analysis: LazyValueAnalysis
; CHECK-DT-INVALIDATE: Running pass: InvalidateAnalysisPass
; CHECK-DT-INVALIDATE: Invalidating analysis: DominatorTreeAnalysis
; CHECK-DT-INVALIDATE: Invalidating analysis: LazyValueAnalysis
; CHECK-AC-INVALIDATE: Running pass: RequireAnalysisPass
; CHECK-DT-INVALIDATE: Running analysis: LazyValueAnalysis
target triple = "x86_64-unknown-linux-gnu"
@.str = private unnamed_addr constant [8 x i8] c"a = %l\0A\00", align 1
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
declare void @hoo(i64*)
declare i32 @printf(i8* nocapture readonly, ...)
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
define void @goo(i32 %N, i64* %b) {
entry:
%a.i = alloca i64, align 8
%tmp = bitcast i64* %a.i to i8*
%c = getelementptr inbounds i64, i64* %b, i64 0
br label %for.cond
for.cond: ; preds = %for.body, %entry
%i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
%cmp = icmp slt i32 %i.0, %N
br i1 %cmp, label %for.body, label %for.end
for.body: ; preds = %for.cond
call void @llvm.lifetime.start.p0i8(i64 8, i8* %tmp)
call void @hoo(i64* %a.i)
call void @hoo(i64* %c)
%tmp1 = load volatile i64, i64* %a.i, align 8
%call.i = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0), i64 %tmp1)
call void @llvm.lifetime.end.p0i8(i64 8, i8* %tmp)
%inc = add nsw i32 %i.0, 1
br label %for.cond
for.end: ; preds = %for.cond
ret void
}

View File

@ -0,0 +1,186 @@
; RUN: opt < %s -jump-threading -print-lvi-after-jump-threading -disable-output 2>&1 | FileCheck %s
; Testing LVI cache after jump-threading
; Jump-threading transforms the IR below to one where
; loop and backedge basic blocks are merged into one.
; basic block (named backedge) with the branch being:
; %cont = icmp slt i32 %iv.next, 400
; br i1 %cont, label %backedge, label %exit
define i8 @test1(i32 %a, i32 %length) {
; CHECK-LABEL: LVI for function 'test1':
entry:
; CHECK-LABEL: entry:
; CHECK-NEXT: ; LatticeVal for: 'i32 %a' is: overdefined
; CHECK-NEXT: ; LatticeVal for: 'i32 %length' is: overdefined
br label %loop
; CHECK-LABEL: backedge:
; CHECK-NEXT: ; LatticeVal for: 'i32 %a' is: overdefined
; CHECK-NEXT: ; LatticeVal for: 'i32 %length' is: overdefined
; CHECK-NEXT: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%backedge' is: constantrange<0, 400>
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
; CHECK-NEXT: ; LatticeVal for: ' %iv.next = add nsw i32 %iv, 1' in BB: '%backedge' is: constantrange<1, 401>
; CHECK-NEXT: %iv.next = add nsw i32 %iv, 1
; CHECK-NEXT: ; LatticeVal for: ' %cont = icmp slt i32 %iv.next, 400' in BB: '%backedge' is: overdefined
; CHECK-NEXT: %cont = icmp slt i32 %iv.next, 400
; CHECK-NOT: loop
loop:
%iv = phi i32 [0, %entry], [%iv.next, %backedge]
%cnd = icmp sge i32 %iv, 0
br i1 %cnd, label %backedge, label %exit
backedge:
%iv.next = add nsw i32 %iv, 1
%cont = icmp slt i32 %iv.next, 400
br i1 %cont, label %loop, label %exit
exit:
ret i8 0
}
; Here JT does not transform the code, but LVICache is populated during the processing of blocks.
define i8 @test2(i32 %n) {
; CHECK-LABEL: LVI for function 'test2':
; CHECK-LABEL: entry:
; CHECK-NEXT: ; LatticeVal for: 'i32 %n' is: overdefined
; CHECK-NEXT: br label %loop
entry:
br label %loop
; CHECK-LABEL: loop:
; CHECK-NEXT: ; LatticeVal for: 'i32 %n' is: overdefined
; CHECK-NEXT: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%loop' is: constantrange<0, -2147483647>
; CHECK-DAG: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%backedge' is: constantrange<0, -2147483648>
; CHECK-DAG: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%exit' is: constantrange<0, -2147483647>
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
loop:
%iv = phi i32 [0, %entry], [%iv.next, %backedge]
; CHECK-NEXT: ; LatticeVal for: ' %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ]' in BB: '%loop' is: overdefined
; CHECK-DAG: ; LatticeVal for: ' %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ]' in BB: '%backedge' is: constantrange<1, -2147483648>
; CHECK-DAG: ; LatticeVal for: ' %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ]' in BB: '%exit' is: overdefined
; CHECK-NEXT: %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ]
%iv2 = phi i32 [%n, %entry], [%iv2.next, %backedge]
; CHECK-NEXT: ; LatticeVal for: ' %cnd1 = icmp sge i32 %iv, 0' in BB: '%loop' is: overdefined
; CHECK-DAG: ; LatticeVal for: ' %cnd1 = icmp sge i32 %iv, 0' in BB: '%backedge' is: overdefined
; CHECK-DAG: ; LatticeVal for: ' %cnd1 = icmp sge i32 %iv, 0' in BB: '%exit' is: overdefined
; CHECK-NEXT: %cnd1 = icmp sge i32 %iv, 0
%cnd1 = icmp sge i32 %iv, 0
%cnd2 = icmp sgt i32 %iv2, 0
; CHECK: %cnd2 = icmp sgt i32 %iv2, 0
; CHECK: ; LatticeVal for: ' %cnd = and i1 %cnd1, %cnd2' in BB: '%loop' is: overdefined
; CHECK-DAG: ; LatticeVal for: ' %cnd = and i1 %cnd1, %cnd2' in BB: '%backedge' is: constantrange<-1, 0>
; CHECK-DAG: ; LatticeVal for: ' %cnd = and i1 %cnd1, %cnd2' in BB: '%exit' is: overdefined
; CHECK-NEXT: %cnd = and i1 %cnd1, %cnd2
%cnd = and i1 %cnd1, %cnd2
br i1 %cnd, label %backedge, label %exit
; CHECK-LABEL: backedge:
; CHECK-NEXT: ; LatticeVal for: 'i32 %n' is: overdefined
; CHECK-NEXT: ; LatticeVal for: ' %iv.next = add nsw i32 %iv, 1' in BB: '%backedge' is: constantrange<1, -2147483647>
; CHECK-NEXT: %iv.next = add nsw i32 %iv, 1
backedge:
%iv.next = add nsw i32 %iv, 1
%iv2.next = sub nsw i32 %iv2, 1
; CHECK: ; LatticeVal for: ' %cont1 = icmp slt i32 %iv.next, 400' in BB: '%backedge' is: overdefined
; CHECK-NEXT: %cont1 = icmp slt i32 %iv.next, 400
%cont1 = icmp slt i32 %iv.next, 400
; CHECK-NEXT: ; LatticeVal for: ' %cont2 = icmp sgt i32 %iv2.next, 0' in BB: '%backedge' is: overdefined
; CHECK-NEXT: %cont2 = icmp sgt i32 %iv2.next, 0
%cont2 = icmp sgt i32 %iv2.next, 0
; CHECK-NEXT: ; LatticeVal for: ' %cont = and i1 %cont1, %cont2' in BB: '%backedge' is: overdefined
; CHECK-NEXT: %cont = and i1 %cont1, %cont2
%cont = and i1 %cont1, %cont2
br i1 %cont, label %loop, label %exit
exit:
ret i8 0
}
; Merging cont block into do block. Make sure that we do not incorrectly have the cont
; LVI info as LVI info for the beginning of do block. LVI info for %i is Range[0,1)
; at beginning of cont Block, which is incorrect at the beginning of do block.
define i32 @test3(i32 %i, i1 %f, i32 %n) {
; CHECK-LABEL: LVI for function 'test3':
; CHECK-LABEL: entry
; CHECK: ; LatticeVal for: 'i32 %i' is: overdefined
; CHECK: %c = icmp ne i32 %i, -2134
; CHECK: br i1 %c, label %cont, label %exit
entry:
%c = icmp ne i32 %i, -2134
br i1 %c, label %do, label %exit
exit:
%c1 = icmp ne i32 %i, -42
br i1 %c1, label %exit2, label %exit
; CHECK-LABEL: cont:
; Here cont is merged to do and i is any value except -2134.
; i is not the single value: zero.
; CHECK-NOT: ; LatticeVal for: 'i32 %i' is: constantrange<0, 1>
; CHECK: ; LatticeVal for: 'i32 %i' is: constantrange<-2133, -2134>
; CHECK: ; LatticeVal for: ' %cond.0 = icmp sgt i32 %i, 0' in BB: '%cont' is: overdefined
; CHECK: %cond.0 = icmp sgt i32 %i, 0
; CHECK: %consume = call i32 @consume
; CHECK: %cond = icmp eq i32 %i, 0
; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %cond)
; CHECK: %cond.3 = icmp sgt i32 %i, %n
; CHECK: br i1 %cond.3, label %exit2, label %exit
cont:
%cond.3 = icmp sgt i32 %i, %n
br i1 %cond.3, label %exit2, label %exit
do:
%cond.0 = icmp sgt i32 %i, 0
%consume = call i32 @consume(i1 %cond.0)
%cond = icmp eq i32 %i, 0
call void (i1, ...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ]
%cond.2 = icmp sgt i32 %i, 0
br i1 %cond.2, label %exit, label %cont
exit2:
; CHECK-LABEL: exit2:
; LatticeVal for: 'i32 %i' is: constantrange<-2134, 1>
ret i32 30
}
; FIXME: We should be able to merge cont into do.
; When we do so, LVI for cont cannot be the one for the merged do block.
define i32 @test4(i32 %i, i1 %f, i32 %n) {
; CHECK-LABEL: LVI for function 'test4':
entry:
%c = icmp ne i32 %i, -2134
br i1 %c, label %do, label %exit
exit: ; preds = %do, %cont, %exit, %entry
%c1 = icmp ne i32 %i, -42
br i1 %c1, label %exit2, label %exit
cont: ; preds = %do
; CHECK-LABEL: cont:
; CHECK: ; LatticeVal for: 'i1 %f' is: constantrange<-1, 0>
; CHECK: call void @dummy(i1 %f)
call void @dummy(i1 %f)
br label %exit2
do: ; preds = %entry
; CHECK-LABEL: do:
; CHECK: ; LatticeVal for: 'i1 %f' is: overdefined
; CHECK: call void @dummy(i1 %f)
; CHECK: br i1 %cond, label %exit, label %cont
call void @dummy(i1 %f)
%consume = call i32 @exit()
call void @llvm.assume(i1 %f)
%cond = icmp eq i1 %f, false
br i1 %cond, label %exit, label %cont
exit2: ; preds = %cont, %exit
ret i32 30
}
declare i32 @exit()
declare i32 @consume(i1)
declare void @llvm.assume(i1) nounwind
declare void @dummy(i1) nounwind
declare void @llvm.experimental.guard(i1, ...)

View File

@ -0,0 +1,27 @@
; RUN: opt -correlated-propagation -S %s | FileCheck %s
; CHECK-LABEL: @test-ashr
; CHECK: bb_then
; CHECK: %. = select i1 true, i32 3, i32 2
define i32 @test-ashr(i32 %c) {
chk65:
%cmp = icmp sgt i32 %c, 65
br i1 %cmp, label %return, label %chk0
chk0:
%cmp1 = icmp slt i32 %c, 0
br i1 %cmp, label %return, label %bb_if
bb_if:
%ashr.val = ashr exact i32 %c, 2
%cmp2 = icmp sgt i32 %ashr.val, 15
br i1 %cmp2, label %bb_then, label %return
bb_then:
%cmp3 = icmp eq i32 %ashr.val, 16
%. = select i1 %cmp3, i32 3, i32 2
br label %return
return:
%retval = phi i32 [0, %chk65], [1, %chk0], [%., %bb_then], [4, %bb_if]
ret i32 %retval
}