1962c6fdaSSanjay Patel; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
21ea84653SJuneyoung Lee; RUN: opt < %s -jump-threading -S -verify | FileCheck %s
31ea84653SJuneyoung Lee
41ea84653SJuneyoung Leetarget datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
51ea84653SJuneyoung Leetarget triple = "x86_64-unknown-linux-gnu"
61ea84653SJuneyoung Lee
71ea84653SJuneyoung Lee@a = global i32 0, align 4
81ea84653SJuneyoung Lee
9962c6fdaSSanjay Patel; Verify that we branch (twice) on cond2 without checking ptr.
10962c6fdaSSanjay Patel; Verify that we eliminate "bb.file".
11962c6fdaSSanjay Patel
121ea84653SJuneyoung Leedefine void @foo(i32 %cond1, i32 %cond2) {
13962c6fdaSSanjay Patel; CHECK-LABEL: @foo(
14962c6fdaSSanjay Patel; CHECK-NEXT:  entry:
15962c6fdaSSanjay Patel; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[COND1:%.*]], 0
16962c6fdaSSanjay Patel; CHECK-NEXT:    br i1 [[TOBOOL]], label [[BB_COND2_THREAD:%.*]], label [[BB_COND2:%.*]]
17962c6fdaSSanjay Patel; CHECK:       bb.cond2:
18962c6fdaSSanjay Patel; CHECK-NEXT:    call void @f1()
19962c6fdaSSanjay Patel; CHECK-NEXT:    [[TOBOOL1:%.*]] = icmp eq i32 [[COND2:%.*]], 0
20962c6fdaSSanjay Patel; CHECK-NEXT:    br i1 [[TOBOOL1]], label [[BB_F4:%.*]], label [[BB_F2:%.*]]
21962c6fdaSSanjay Patel; CHECK:       bb.cond2.thread:
22962c6fdaSSanjay Patel; CHECK-NEXT:    [[TOBOOL12:%.*]] = icmp eq i32 [[COND2]], 0
23962c6fdaSSanjay Patel; CHECK-NEXT:    br i1 [[TOBOOL12]], label [[BB_F3:%.*]], label [[BB_F2]]
24962c6fdaSSanjay Patel; CHECK:       bb.f2:
25962c6fdaSSanjay Patel; CHECK-NEXT:    call void @f2()
26962c6fdaSSanjay Patel; CHECK-NEXT:    br label [[EXIT:%.*]]
27962c6fdaSSanjay Patel; CHECK:       bb.f3:
28962c6fdaSSanjay Patel; CHECK-NEXT:    call void @f3()
29962c6fdaSSanjay Patel; CHECK-NEXT:    br label [[EXIT]]
30962c6fdaSSanjay Patel; CHECK:       bb.f4:
31962c6fdaSSanjay Patel; CHECK-NEXT:    [[PTR3:%.*]] = phi i32* [ null, [[BB_COND2]] ]
32962c6fdaSSanjay Patel; CHECK-NEXT:    call void @f4()
33962c6fdaSSanjay Patel; CHECK-NEXT:    br label [[EXIT]]
34962c6fdaSSanjay Patel; CHECK:       exit:
35962c6fdaSSanjay Patel; CHECK-NEXT:    ret void
36962c6fdaSSanjay Patel;
371ea84653SJuneyoung Leeentry:
381ea84653SJuneyoung Lee  %tobool = icmp eq i32 %cond1, 0
391ea84653SJuneyoung Lee  br i1 %tobool, label %bb.cond2, label %bb.f1
401ea84653SJuneyoung Lee
411ea84653SJuneyoung Leebb.f1:
421ea84653SJuneyoung Lee  call void @f1()
431ea84653SJuneyoung Lee  br label %bb.cond2
441ea84653SJuneyoung Lee
451ea84653SJuneyoung Leebb.cond2:
461ea84653SJuneyoung Lee  %ptr = phi i32* [ null, %bb.f1 ], [ @a, %entry ]
471ea84653SJuneyoung Lee  %tobool1 = icmp eq i32 %cond2, 0
481ea84653SJuneyoung Lee  br i1 %tobool1, label %bb.file, label %bb.f2
491ea84653SJuneyoung Lee
501ea84653SJuneyoung Leebb.f2:
511ea84653SJuneyoung Lee  call void @f2()
521ea84653SJuneyoung Lee  br label %exit
531ea84653SJuneyoung Lee
541ea84653SJuneyoung Leebb.file:
551ea84653SJuneyoung Lee  %cmp = icmp eq i32* %ptr, null
561ea84653SJuneyoung Lee  br i1 %cmp, label %bb.f4, label %bb.f3
571ea84653SJuneyoung Lee
581ea84653SJuneyoung Leebb.f3:
591ea84653SJuneyoung Lee  call void @f3()
601ea84653SJuneyoung Lee  br label %exit
611ea84653SJuneyoung Lee
621ea84653SJuneyoung Leebb.f4:
631ea84653SJuneyoung Lee  call void @f4()
641ea84653SJuneyoung Lee  br label %exit
651ea84653SJuneyoung Lee
661ea84653SJuneyoung Leeexit:
671ea84653SJuneyoung Lee  ret void
681ea84653SJuneyoung Lee}
691ea84653SJuneyoung Lee
701ea84653SJuneyoung Leedeclare void @f1()
711ea84653SJuneyoung Leedeclare void @f2()
721ea84653SJuneyoung Leedeclare void @f3()
731ea84653SJuneyoung Leedeclare void @f4()
741ea84653SJuneyoung Lee
751ea84653SJuneyoung Lee
76962c6fdaSSanjay Patel; Verify that we branch (twice) on cond2 without checking tobool again.
77962c6fdaSSanjay Patel; Verify that we eliminate "bb.cond1again".
78962c6fdaSSanjay Patel
791ea84653SJuneyoung Leedefine void @foo2(i32 %cond1, i32 %cond2) {
80962c6fdaSSanjay Patel; CHECK-LABEL: @foo2(
81962c6fdaSSanjay Patel; CHECK-NEXT:  entry:
82962c6fdaSSanjay Patel; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[COND1:%.*]], 0
83962c6fdaSSanjay Patel; CHECK-NEXT:    br i1 [[TOBOOL]], label [[BB_COND2:%.*]], label [[BB_COND2_THREAD:%.*]]
84962c6fdaSSanjay Patel; CHECK:       bb.cond2:
85962c6fdaSSanjay Patel; CHECK-NEXT:    call void @f1()
86962c6fdaSSanjay Patel; CHECK-NEXT:    [[TOBOOL1:%.*]] = icmp eq i32 [[COND2:%.*]], 0
87962c6fdaSSanjay Patel; CHECK-NEXT:    br i1 [[TOBOOL1]], label [[EXIT:%.*]], label [[BB_F3:%.*]]
88962c6fdaSSanjay Patel; CHECK:       bb.cond2.thread:
89962c6fdaSSanjay Patel; CHECK-NEXT:    call void @f2()
90962c6fdaSSanjay Patel; CHECK-NEXT:    [[TOBOOL11:%.*]] = icmp eq i32 [[COND2]], 0
91962c6fdaSSanjay Patel; CHECK-NEXT:    br i1 [[TOBOOL11]], label [[EXIT]], label [[BB_F4:%.*]]
92962c6fdaSSanjay Patel; CHECK:       bb.f3:
93962c6fdaSSanjay Patel; CHECK-NEXT:    call void @f3()
94962c6fdaSSanjay Patel; CHECK-NEXT:    br label [[EXIT]]
95962c6fdaSSanjay Patel; CHECK:       bb.f4:
96962c6fdaSSanjay Patel; CHECK-NEXT:    call void @f4()
97962c6fdaSSanjay Patel; CHECK-NEXT:    br label [[EXIT]]
98962c6fdaSSanjay Patel; CHECK:       exit:
99962c6fdaSSanjay Patel; CHECK-NEXT:    ret void
100962c6fdaSSanjay Patel;
1011ea84653SJuneyoung Leeentry:
1021ea84653SJuneyoung Lee  %tobool = icmp ne i32 %cond1, 0
1031ea84653SJuneyoung Lee  br i1 %tobool, label %bb.f1, label %bb.f2
1041ea84653SJuneyoung Lee
1051ea84653SJuneyoung Leebb.f1:
1061ea84653SJuneyoung Lee  call void @f1()
1071ea84653SJuneyoung Lee  br label %bb.cond2
1081ea84653SJuneyoung Lee
1091ea84653SJuneyoung Leebb.f2:
1101ea84653SJuneyoung Lee  call void @f2()
1111ea84653SJuneyoung Lee  br label %bb.cond2
1121ea84653SJuneyoung Lee
1131ea84653SJuneyoung Leebb.cond2:
1141ea84653SJuneyoung Lee  %tobool1 = icmp eq i32 %cond2, 0
1151ea84653SJuneyoung Lee  br i1 %tobool1, label %exit, label %bb.cond1again
1161ea84653SJuneyoung Lee
1171ea84653SJuneyoung Leebb.cond1again:
1181ea84653SJuneyoung Lee  br i1 %tobool, label %bb.f3, label %bb.f4
1191ea84653SJuneyoung Lee
1201ea84653SJuneyoung Leebb.f3:
1211ea84653SJuneyoung Lee  call void @f3()
1221ea84653SJuneyoung Lee  br label %exit
1231ea84653SJuneyoung Lee
1241ea84653SJuneyoung Leebb.f4:
1251ea84653SJuneyoung Lee  call void @f4()
1261ea84653SJuneyoung Lee  br label %exit
1271ea84653SJuneyoung Lee
1281ea84653SJuneyoung Leeexit:
1291ea84653SJuneyoung Lee  ret void
1301ea84653SJuneyoung Lee}
1311ea84653SJuneyoung Lee
1321ea84653SJuneyoung Lee
1331ea84653SJuneyoung Lee; Verify that we do *not* thread any edge.  We used to evaluate
1341ea84653SJuneyoung Lee; constant expressions like:
1351ea84653SJuneyoung Lee;
1361ea84653SJuneyoung Lee;   icmp ugt i8* null, inttoptr (i64 4 to i8*)
1371ea84653SJuneyoung Lee;
1381ea84653SJuneyoung Lee; as "true", causing jump threading to a wrong destination.
139962c6fdaSSanjay Patel
140a093942cSSanjay Pateldefine void @icmp_ult_null_constexpr(i8* %arg1, i8* %arg2) {
141a093942cSSanjay Patel; CHECK-LABEL: @icmp_ult_null_constexpr(
142a093942cSSanjay Patel; CHECK-NEXT:  entry:
143a093942cSSanjay Patel; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8* [[ARG1:%.*]], null
144a093942cSSanjay Patel; CHECK-NEXT:    br i1 [[CMP1]], label [[BB_BAR1:%.*]], label [[BB_END:%.*]]
145a093942cSSanjay Patel; CHECK:       bb_bar1:
146a093942cSSanjay Patel; CHECK-NEXT:    call void @bar(i32 1)
147a093942cSSanjay Patel; CHECK-NEXT:    br label [[BB_END]]
148a093942cSSanjay Patel; CHECK:       bb_end:
149a093942cSSanjay Patel; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i8* [[ARG2:%.*]], null
150a093942cSSanjay Patel; CHECK-NEXT:    br i1 [[CMP2]], label [[BB_CONT:%.*]], label [[BB_BAR2:%.*]]
151a093942cSSanjay Patel; CHECK:       bb_bar2:
152a093942cSSanjay Patel; CHECK-NEXT:    call void @bar(i32 2)
153a093942cSSanjay Patel; CHECK-NEXT:    br label [[BB_EXIT:%.*]]
154a093942cSSanjay Patel; CHECK:       bb_cont:
155a093942cSSanjay Patel; CHECK-NEXT:    [[CMP3:%.*]] = icmp ult i8* [[ARG1]], inttoptr (i64 4 to i8*)
156a093942cSSanjay Patel; CHECK-NEXT:    br i1 [[CMP3]], label [[BB_EXIT]], label [[BB_BAR3:%.*]]
157a093942cSSanjay Patel; CHECK:       bb_bar3:
158a093942cSSanjay Patel; CHECK-NEXT:    call void @bar(i32 3)
159a093942cSSanjay Patel; CHECK-NEXT:    br label [[BB_EXIT]]
160a093942cSSanjay Patel; CHECK:       bb_exit:
161a093942cSSanjay Patel; CHECK-NEXT:    ret void
162a093942cSSanjay Patel;
163a093942cSSanjay Patelentry:
164a093942cSSanjay Patel  %cmp1 = icmp eq i8* %arg1, null
165a093942cSSanjay Patel  br i1 %cmp1, label %bb_bar1, label %bb_end
166a093942cSSanjay Patel
167a093942cSSanjay Patelbb_bar1:
168a093942cSSanjay Patel  call void @bar(i32 1)
169a093942cSSanjay Patel  br label %bb_end
170a093942cSSanjay Patel
171a093942cSSanjay Patelbb_end:
172a093942cSSanjay Patel  %cmp2 = icmp ne i8* %arg2, null
173a093942cSSanjay Patel  br i1 %cmp2, label %bb_cont, label %bb_bar2
174a093942cSSanjay Patel
175a093942cSSanjay Patelbb_bar2:
176a093942cSSanjay Patel  call void @bar(i32 2)
177a093942cSSanjay Patel  br label %bb_exit
178a093942cSSanjay Patel
179a093942cSSanjay Patelbb_cont:
180a093942cSSanjay Patel  %cmp3 = icmp ult i8* %arg1, inttoptr (i64 4 to i8*)
181a093942cSSanjay Patel  br i1 %cmp3, label %bb_exit, label %bb_bar3
182a093942cSSanjay Patel
183a093942cSSanjay Patelbb_bar3:
184a093942cSSanjay Patel  call void @bar(i32 3)
185a093942cSSanjay Patel  br label %bb_exit
186a093942cSSanjay Patel
187a093942cSSanjay Patelbb_exit:
188a093942cSSanjay Patel  ret void
189a093942cSSanjay Patel}
190a093942cSSanjay Patel
191*f75b5305SSanjay Patel; This is a special-case of the above pattern:
192a093942cSSanjay Patel; Null is guaranteed to be unsigned <= all values.
193a093942cSSanjay Patel
194a093942cSSanjay Pateldefine void @icmp_ule_null_constexpr(i8* %arg1, i8* %arg2) {
195a093942cSSanjay Patel; CHECK-LABEL: @icmp_ule_null_constexpr(
196962c6fdaSSanjay Patel; CHECK-NEXT:  entry:
197962c6fdaSSanjay Patel; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8* [[ARG1:%.*]], null
198*f75b5305SSanjay Patel; CHECK-NEXT:    br i1 [[CMP1]], label [[BB_END_THREAD:%.*]], label [[BB_END:%.*]]
199962c6fdaSSanjay Patel; CHECK:       bb_end:
200962c6fdaSSanjay Patel; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i8* [[ARG2:%.*]], null
201962c6fdaSSanjay Patel; CHECK-NEXT:    br i1 [[CMP2]], label [[BB_CONT:%.*]], label [[BB_BAR2:%.*]]
202*f75b5305SSanjay Patel; CHECK:       bb_end.thread:
203*f75b5305SSanjay Patel; CHECK-NEXT:    call void @bar(i32 1)
204*f75b5305SSanjay Patel; CHECK-NEXT:    [[CMP21:%.*]] = icmp ne i8* [[ARG2]], null
205*f75b5305SSanjay Patel; CHECK-NEXT:    br i1 [[CMP21]], label [[BB_EXIT:%.*]], label [[BB_BAR2]]
206962c6fdaSSanjay Patel; CHECK:       bb_bar2:
207962c6fdaSSanjay Patel; CHECK-NEXT:    call void @bar(i32 2)
208*f75b5305SSanjay Patel; CHECK-NEXT:    br label [[BB_EXIT]]
209962c6fdaSSanjay Patel; CHECK:       bb_cont:
210962c6fdaSSanjay Patel; CHECK-NEXT:    [[CMP3:%.*]] = icmp ule i8* [[ARG1]], inttoptr (i64 4 to i8*)
211962c6fdaSSanjay Patel; CHECK-NEXT:    br i1 [[CMP3]], label [[BB_EXIT]], label [[BB_BAR3:%.*]]
212962c6fdaSSanjay Patel; CHECK:       bb_bar3:
213962c6fdaSSanjay Patel; CHECK-NEXT:    call void @bar(i32 3)
214962c6fdaSSanjay Patel; CHECK-NEXT:    br label [[BB_EXIT]]
215962c6fdaSSanjay Patel; CHECK:       bb_exit:
216962c6fdaSSanjay Patel; CHECK-NEXT:    ret void
217962c6fdaSSanjay Patel;
2181ea84653SJuneyoung Leeentry:
2191ea84653SJuneyoung Lee  %cmp1 = icmp eq i8* %arg1, null
2201ea84653SJuneyoung Lee  br i1 %cmp1, label %bb_bar1, label %bb_end
2211ea84653SJuneyoung Lee
2221ea84653SJuneyoung Leebb_bar1:
2231ea84653SJuneyoung Lee  call void @bar(i32 1)
2241ea84653SJuneyoung Lee  br label %bb_end
2251ea84653SJuneyoung Lee
2261ea84653SJuneyoung Leebb_end:
2271ea84653SJuneyoung Lee  %cmp2 = icmp ne i8* %arg2, null
2281ea84653SJuneyoung Lee  br i1 %cmp2, label %bb_cont, label %bb_bar2
2291ea84653SJuneyoung Lee
2301ea84653SJuneyoung Leebb_bar2:
2311ea84653SJuneyoung Lee  call void @bar(i32 2)
2321ea84653SJuneyoung Lee  br label %bb_exit
2331ea84653SJuneyoung Lee
2341ea84653SJuneyoung Leebb_cont:
2351ea84653SJuneyoung Lee  %cmp3 = icmp ule i8* %arg1, inttoptr (i64 4 to i8*)
2361ea84653SJuneyoung Lee  br i1 %cmp3, label %bb_exit, label %bb_bar3
2371ea84653SJuneyoung Lee
2381ea84653SJuneyoung Leebb_bar3:
2391ea84653SJuneyoung Lee  call void @bar(i32 3)
2401ea84653SJuneyoung Lee  br label %bb_exit
2411ea84653SJuneyoung Lee
2421ea84653SJuneyoung Leebb_exit:
2431ea84653SJuneyoung Lee  ret void
2441ea84653SJuneyoung Lee}
2451ea84653SJuneyoung Lee
2461ea84653SJuneyoung Leedeclare void @bar(i32)
2471ea84653SJuneyoung Lee
2481ea84653SJuneyoung Lee
2491ea84653SJuneyoung Lee;; Test that we skip unconditional PredBB when threading jumps through two
2501ea84653SJuneyoung Lee;; successive basic blocks.
2511ea84653SJuneyoung Lee
2521ea84653SJuneyoung Leedefine i32 @foo4(i32* %0) {
253962c6fdaSSanjay Patel; CHECK-LABEL: @foo4(
254962c6fdaSSanjay Patel; CHECK-NEXT:  entry:
255962c6fdaSSanjay Patel; CHECK-NEXT:    [[SIZE:%.*]] = call i64 @get_size(i32* [[TMP0:%.*]])
256962c6fdaSSanjay Patel; CHECK-NEXT:    [[GOOD:%.*]] = icmp ugt i64 [[SIZE]], 3
257962c6fdaSSanjay Patel; CHECK-NEXT:    br i1 [[GOOD]], label [[PRED_BB:%.*]], label [[PRED_PRED_BB:%.*]]
258962c6fdaSSanjay Patel; CHECK:       pred.pred.bb:
259962c6fdaSSanjay Patel; CHECK-NEXT:    call void @effect()
260962c6fdaSSanjay Patel; CHECK-NEXT:    br label [[PRED_BB]]
261962c6fdaSSanjay Patel; CHECK:       pred.bb:
262962c6fdaSSanjay Patel; CHECK-NEXT:    [[V:%.*]] = load i32, i32* [[TMP0]], align 4
263962c6fdaSSanjay Patel; CHECK-NEXT:    br label [[BB:%.*]]
264962c6fdaSSanjay Patel; CHECK:       bb:
265962c6fdaSSanjay Patel; CHECK-NEXT:    call void @effect1(i8* blockaddress(@foo4, [[BB]]))
266962c6fdaSSanjay Patel; CHECK-NEXT:    br i1 [[GOOD]], label [[EXIT:%.*]], label [[EXIT]]
267962c6fdaSSanjay Patel; CHECK:       exit:
268962c6fdaSSanjay Patel; CHECK-NEXT:    ret i32 [[V]]
269962c6fdaSSanjay Patel;
2701ea84653SJuneyoung Leeentry:
2711ea84653SJuneyoung Lee  %size = call i64 @get_size(i32* %0)
2721ea84653SJuneyoung Lee  %good = icmp ugt i64 %size, 3
2731ea84653SJuneyoung Lee  br i1 %good, label %pred.bb, label %pred.pred.bb
2741ea84653SJuneyoung Lee
2751ea84653SJuneyoung Leepred.pred.bb:                                        ; preds = %entry
2761ea84653SJuneyoung Lee  call void @effect()
2771ea84653SJuneyoung Lee  br label %pred.bb
2781ea84653SJuneyoung Leepred.bb:                                             ; preds = %pred.pred.bb, %entry
2791ea84653SJuneyoung Lee  %v = load i32, i32* %0
2801ea84653SJuneyoung Lee  br label %bb
2811ea84653SJuneyoung Lee
2821ea84653SJuneyoung Leebb:                                                  ; preds = %pred.bb
2831ea84653SJuneyoung Lee  call void @effect1(i8* blockaddress(@foo4, %bb))
2841ea84653SJuneyoung Lee  br i1 %good, label %cont2, label %cont1
2851ea84653SJuneyoung Lee
2861ea84653SJuneyoung Leecont1:                                               ; preds = %bb
2871ea84653SJuneyoung Lee  br i1 %good, label %exit, label %cont2
2881ea84653SJuneyoung Leecont2:                                               ; preds = %bb
2891ea84653SJuneyoung Lee  br label %exit
2901ea84653SJuneyoung Leeexit:                                                ; preds = %cont1, %cont2
2911ea84653SJuneyoung Lee  ret i32 %v
2921ea84653SJuneyoung Lee}
2931ea84653SJuneyoung Lee
2941ea84653SJuneyoung Leedeclare i64 @get_size(i32*)
2951ea84653SJuneyoung Leedeclare void @effect()
2961ea84653SJuneyoung Leedeclare void @effect1(i8*)
297