• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt < %s -jump-threading -S -verify | FileCheck %s
2
3target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
4target triple = "x86_64-unknown-linux-gnu"
5
6@a = global i32 0, align 4
7
8define void @foo(i32 %cond1, i32 %cond2) {
9; CHECK-LABEL: @foo
10; CHECK-LABEL: entry
11entry:
12  %tobool = icmp eq i32 %cond1, 0
13  br i1 %tobool, label %bb.cond2, label %bb.f1
14
15bb.f1:
16  call void @f1()
17  br label %bb.cond2
18; Verify that we branch on cond2 without checking ptr.
19; CHECK:      call void @f1()
20; CHECK-NEXT: icmp eq i32 %cond2, 0
21; CHECK-NEXT: label %bb.f4, label %bb.f2
22
23bb.cond2:
24  %ptr = phi i32* [ null, %bb.f1 ], [ @a, %entry ]
25  %tobool1 = icmp eq i32 %cond2, 0
26  br i1 %tobool1, label %bb.file, label %bb.f2
27; Verify that we branch on cond2 without checking ptr.
28; CHECK:      icmp eq i32 %cond2, 0
29; CHECK-NEXT: label %bb.f3, label %bb.f2
30
31bb.f2:
32  call void @f2()
33  br label %exit
34
35; Verify that we eliminate this basic block.
36; CHECK-NOT: bb.file:
37bb.file:
38  %cmp = icmp eq i32* %ptr, null
39  br i1 %cmp, label %bb.f4, label %bb.f3
40
41bb.f3:
42  call void @f3()
43  br label %exit
44
45bb.f4:
46  call void @f4()
47  br label %exit
48
49exit:
50  ret void
51}
52
53declare void @f1()
54
55declare void @f2()
56
57declare void @f3()
58
59declare void @f4()
60
61
62define void @foo2(i32 %cond1, i32 %cond2) {
63; CHECK-LABEL: @foo2
64; CHECK-LABEL: entry
65entry:
66  %tobool = icmp ne i32 %cond1, 0
67  br i1 %tobool, label %bb.f1, label %bb.f2
68
69bb.f1:
70  call void @f1()
71  br label %bb.cond2
72; Verify that we branch on cond2 without checking tobool again.
73; CHECK:      call void @f1()
74; CHECK-NEXT: icmp eq i32 %cond2, 0
75; CHECK-NEXT: label %exit, label %bb.f3
76
77bb.f2:
78  call void @f2()
79  br label %bb.cond2
80; Verify that we branch on cond2 without checking tobool again.
81; CHECK:      call void @f2()
82; CHECK-NEXT: icmp eq i32 %cond2, 0
83; CHECK-NEXT: label %exit, label %bb.f4
84
85bb.cond2:
86  %tobool1 = icmp eq i32 %cond2, 0
87  br i1 %tobool1, label %exit, label %bb.cond1again
88
89; Verify that we eliminate this basic block.
90; CHECK-NOT: bb.cond1again:
91bb.cond1again:
92  br i1 %tobool, label %bb.f3, label %bb.f4
93
94bb.f3:
95  call void @f3()
96  br label %exit
97
98bb.f4:
99  call void @f4()
100  br label %exit
101
102exit:
103  ret void
104}
105
106
107; Verify that we do *not* thread any edge.  We used to evaluate
108; constant expressions like:
109;
110;   icmp ugt i8* null, inttoptr (i64 4 to i8*)
111;
112; as "true", causing jump threading to a wrong destination.
113define void @foo3(i8* %arg1, i8* %arg2) {
114; CHECK-LABEL: @foo
115; CHECK-NOT: bb_{{[^ ]*}}.thread:
116entry:
117  %cmp1 = icmp eq i8* %arg1, null
118  br i1 %cmp1, label %bb_bar1, label %bb_end
119
120bb_bar1:
121  call void @bar(i32 1)
122  br label %bb_end
123
124bb_end:
125  %cmp2 = icmp ne i8* %arg2, null
126  br i1 %cmp2, label %bb_cont, label %bb_bar2
127
128bb_bar2:
129  call void @bar(i32 2)
130  br label %bb_exit
131
132bb_cont:
133  %cmp3 = icmp ule i8* %arg1, inttoptr (i64 4 to i8*)
134  br i1 %cmp3, label %bb_exit, label %bb_bar3
135
136bb_bar3:
137  call void @bar(i32 3)
138  br label %bb_exit
139
140bb_exit:
141  ret void
142}
143
144declare void @bar(i32)
145
146
147;; Test that we skip unconditional PredBB when threading jumps through two
148;; successive basic blocks.
149
150define i32 @foo4(i32* %0) {
151; CHECK-LABEL: @f
152; CHECK: br i1 %good, label %pred.bb, label %pred.pred.bb
153entry:
154  %size = call i64 @get_size(i32* %0)
155  %good = icmp ugt i64 %size, 3
156  br i1 %good, label %pred.bb, label %pred.pred.bb
157
158; CHECK:      pred.pred.bb:
159; CHECK:       br label %pred.bb
160; CHECK:      pred.bb:
161; CHECK:       br label %bb
162; CHECK:      bb:
163pred.pred.bb:                                        ; preds = %entry
164  call void @effect()
165  br label %pred.bb
166pred.bb:                                             ; preds = %pred.pred.bb, %entry
167  %v = load i32, i32* %0
168  br label %bb
169
170bb:                                                  ; preds = %pred.bb
171  call void @effect1(i8* blockaddress(@foo4, %bb))
172  br i1 %good, label %cont2, label %cont1
173
174cont1:                                               ; preds = %bb
175  br i1 %good, label %exit, label %cont2
176cont2:                                               ; preds = %bb
177  br label %exit
178exit:                                                ; preds = %cont1, %cont2
179  ret i32 %v
180}
181
182declare i64 @get_size(i32*)
183declare void @effect()
184declare void @effect1(i8*)
185