1 ; RUN: opt < %s -passes="jump-threading,print<lazy-value-info>" -disable-output 2>&1 | FileCheck %s
3 ; Testing LVI cache after jump-threading
5 ; Jump-threading transforms the IR below to one where
6 ; loop and backedge basic blocks are merged into one.
7 ; basic block (named backedge) with the branch being:
8 ; %cont = icmp slt i32 %iv.next, 400
9 ; br i1 %cont, label %backedge, label %exit
10 define i8 @test1(i32 %a, i32 %length) {
11 ; CHECK-LABEL: LVI for function 'test1':
14 ; CHECK-NEXT: ; LatticeVal for: 'i32 %a' is: overdefined
15 ; CHECK-NEXT: ; LatticeVal for: 'i32 %length' is: overdefined
18 ; CHECK-LABEL: backedge:
19 ; CHECK-NEXT: ; LatticeVal for: 'i32 %a' is: overdefined
20 ; CHECK-NEXT: ; LatticeVal for: 'i32 %length' is: overdefined
21 ; CHECK-NEXT: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%backedge' is: constantrange<0, 400>
22 ; CHECK-NEXT: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%exit' is: constantrange<399, 400>
23 ; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
24 ; CHECK-NEXT: ; LatticeVal for: ' %iv.next = add nsw i32 %iv, 1' in BB: '%backedge' is: constantrange<1, 401>
25 ; CHECK-NEXT: ; LatticeVal for: ' %iv.next = add nsw i32 %iv, 1' in BB: '%exit' is: constantrange<400, 401>
26 ; CHECK-NEXT: %iv.next = add nsw i32 %iv, 1
27 ; CHECK-NEXT: ; LatticeVal for: ' %cont = icmp slt i32 %iv.next, 400' in BB: '%backedge' is: overdefined
28 ; CHECK-NEXT: ; LatticeVal for: ' %cont = icmp slt i32 %iv.next, 400' in BB: '%exit' is: constantrange<0, -1>
29 ; CHECK-NEXT: %cont = icmp slt i32 %iv.next, 400
32 %iv = phi i32 [0, %entry], [%iv.next, %backedge]
33 %cnd = icmp sge i32 %iv, 0
34 br i1 %cnd, label %backedge, label %exit
37 %iv.next = add nsw i32 %iv, 1
38 %cont = icmp slt i32 %iv.next, 400
39 br i1 %cont, label %loop, label %exit
45 ; Here JT does not transform the code, but LVICache is populated during the processing of blocks.
46 define i8 @test2(i32 %n) {
47 ; CHECK-LABEL: LVI for function 'test2':
49 ; CHECK-NEXT: ; LatticeVal for: 'i32 %n' is: overdefined
50 ; CHECK-NEXT: br label %loop
55 ; CHECK-NEXT: ; LatticeVal for: 'i32 %n' is: overdefined
56 ; CHECK-NEXT: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%loop' is: constantrange<0, 400>
57 ; CHECK-DAG: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%backedge' is: constantrange<0, -2147483648>
58 ; CHECK-DAG: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%exit' is: constantrange<0, -2147483648>
59 ; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
61 %iv = phi i32 [0, %entry], [%iv.next, %backedge]
62 ; CHECK-NEXT: ; LatticeVal for: ' %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ]' in BB: '%loop' is: overdefined
63 ; CHECK-DAG: ; LatticeVal for: ' %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ]' in BB: '%backedge' is: constantrange<1, -2147483648>
64 ; CHECK-DAG: ; LatticeVal for: ' %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ]' in BB: '%exit' is: overdefined
65 ; CHECK-NEXT: %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ]
66 %iv2 = phi i32 [%n, %entry], [%iv2.next, %backedge]
68 ; CHECK-NEXT: ; LatticeVal for: ' %cnd1 = icmp sge i32 %iv, 0' in BB: '%loop' is: overdefined
69 ; CHECK-DAG: ; LatticeVal for: ' %cnd1 = icmp sge i32 %iv, 0' in BB: '%backedge' is: overdefined
70 ; CHECK-DAG: ; LatticeVal for: ' %cnd1 = icmp sge i32 %iv, 0' in BB: '%exit' is: overdefined
71 ; CHECK-NEXT: %cnd1 = icmp sge i32 %iv, 0
72 %cnd1 = icmp sge i32 %iv, 0
73 %cnd2 = icmp sgt i32 %iv2, 0
74 ; CHECK: %cnd2 = icmp sgt i32 %iv2, 0
75 ; CHECK: ; LatticeVal for: ' %cnd = and i1 %cnd1, %cnd2' in BB: '%loop' is: overdefined
76 ; CHECK-DAG: ; LatticeVal for: ' %cnd = and i1 %cnd1, %cnd2' in BB: '%backedge' is: constantrange<-1, 0>
77 ; CHECK-DAG: ; LatticeVal for: ' %cnd = and i1 %cnd1, %cnd2' in BB: '%exit' is: overdefined
78 ; CHECK-NEXT: %cnd = and i1 %cnd1, %cnd2
79 %cnd = and i1 %cnd1, %cnd2
80 br i1 %cnd, label %backedge, label %exit
82 ; CHECK-LABEL: backedge:
83 ; CHECK-NEXT: ; LatticeVal for: 'i32 %n' is: overdefined
84 ; CHECK-NEXT: ; LatticeVal for: ' %iv.next = add nsw i32 %iv, 1' in BB: '%backedge' is: constantrange<1, -2147483648>
85 ; CHECK-NEXT: %iv.next = add nsw i32 %iv, 1
87 %iv.next = add nsw i32 %iv, 1
88 %iv2.next = sub nsw i32 %iv2, 1
89 ; CHECK: ; LatticeVal for: ' %cont1 = icmp slt i32 %iv.next, 400' in BB: '%backedge' is: overdefined
90 ; CHECK-NEXT: %cont1 = icmp slt i32 %iv.next, 400
91 %cont1 = icmp slt i32 %iv.next, 400
92 ; CHECK-NEXT: ; LatticeVal for: ' %cont2 = icmp sgt i32 %iv2.next, 0' in BB: '%backedge' is: overdefined
93 ; CHECK-NEXT: %cont2 = icmp sgt i32 %iv2.next, 0
94 %cont2 = icmp sgt i32 %iv2.next, 0
95 ; CHECK-NEXT: ; LatticeVal for: ' %cont = and i1 %cont1, %cont2' in BB: '%backedge' is: overdefined
96 ; CHECK-NEXT: %cont = and i1 %cont1, %cont2
97 %cont = and i1 %cont1, %cont2
98 br i1 %cont, label %loop, label %exit
104 ; Merging cont block into do block. Make sure that we do not incorrectly have the cont
105 ; LVI info as LVI info for the beginning of do block. LVI info for %i is Range[0,1)
106 ; at beginning of cont Block, which is incorrect at the beginning of do block.
107 define i32 @test3(i32 %i, i1 %f, i32 %n) {
108 ; CHECK-LABEL: LVI for function 'test3':
110 ; CHECK: ; LatticeVal for: 'i32 %i' is: overdefined
111 ; CHECK: %c = icmp ne i32 %i, -2134
112 ; CHECK: br i1 %c, label %cont, label %exit
114 %c = icmp ne i32 %i, -2134
115 br i1 %c, label %do, label %exit
118 %c1 = icmp ne i32 %i, -42
119 br i1 %c1, label %exit2, label %exit
122 ; Here cont is merged to do and i is any value except -2134.
123 ; i is not the single value: zero.
124 ; CHECK-NOT: ; LatticeVal for: 'i32 %i' is: constantrange<0, 1>
125 ; CHECK: ; LatticeVal for: 'i32 %i' is: constantrange<-2133, -2134>
126 ; CHECK: ; LatticeVal for: ' %cond.0 = icmp sgt i32 %i, 0' in BB: '%cont' is: overdefined
127 ; CHECK: %cond.0 = icmp sgt i32 %i, 0
128 ; CHECK: %consume = call i32 @consume
129 ; CHECK: %cond = icmp eq i32 %i, 0
130 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %cond)
131 ; CHECK: %cond.3 = icmp sgt i32 %i, %n
132 ; CHECK: br i1 %cond.3, label %exit2, label %exit
134 %cond.3 = icmp sgt i32 %i, %n
135 br i1 %cond.3, label %exit2, label %exit
138 %cond.0 = icmp sgt i32 %i, 0
139 %consume = call i32 @consume(i1 %cond.0)
140 %cond = icmp eq i32 %i, 0
141 call void (i1, ...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ]
142 %cond.2 = icmp sgt i32 %i, 0
143 br i1 %cond.2, label %exit, label %cont
146 ; CHECK-LABEL: exit2:
147 ; LatticeVal for: 'i32 %i' is: constantrange<-2134, 1>
151 ; FIXME: We should be able to merge cont into do.
152 ; When we do so, LVI for cont cannot be the one for the merged do block.
153 define i32 @test4(i32 %i, i1 %f, i32 %n) {
154 ; CHECK-LABEL: LVI for function 'test4':
156 %c = icmp ne i32 %i, -2134
157 br i1 %c, label %do, label %exit
159 exit: ; preds = %do, %cont, %exit, %entry
160 %c1 = icmp ne i32 %i, -42
161 br i1 %c1, label %exit2, label %exit
165 ; CHECK: ; LatticeVal for: 'i1 %f' is: constantrange<-1, 0>
166 ; CHECK: call void @dummy(i1 %f)
167 call void @dummy(i1 %f)
172 ; CHECK: ; LatticeVal for: 'i1 %f' is: overdefined
173 ; CHECK: call void @dummy(i1 %f)
174 ; CHECK: br i1 %cond, label %exit, label %cont
175 call void @dummy(i1 %f)
176 %consume = call i32 @exit()
177 call void @llvm.assume(i1 %f)
178 %cond = icmp eq i1 %f, false
179 br i1 %cond, label %exit, label %cont
181 exit2: ; preds = %cont, %exit
186 declare i32 @consume(i1)
187 declare void @llvm.assume(i1) nounwind
188 declare void @dummy(i1) nounwind
189 declare void @llvm.experimental.guard(i1, ...)