1; RUN: opt < %s -instcombine -S | FileCheck %s
2target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3target triple = "x86_64-unknown-linux-gnu"
4
5; Function Attrs: nounwind uwtable
6define i32 @foo1(i32* %a) #0 {
7entry:
8  %0 = load i32, i32* %a, align 4
9
10; Check that the alignment has been upgraded and that the assume has not
11; been removed:
12; CHECK-LABEL: @foo1
13; CHECK-DAG: load i32, i32* %a, align 32
14; CHECK-DAG: call void @llvm.assume
15; CHECK: ret i32
16
17  %ptrint = ptrtoint i32* %a to i64
18  %maskedptr = and i64 %ptrint, 31
19  %maskcond = icmp eq i64 %maskedptr, 0
20  tail call void @llvm.assume(i1 %maskcond)
21
22  ret i32 %0
23}
24
25; Function Attrs: nounwind uwtable
26define i32 @foo2(i32* %a) #0 {
27entry:
28; Same check as in @foo1, but make sure it works if the assume is first too.
29; CHECK-LABEL: @foo2
30; CHECK-DAG: load i32, i32* %a, align 32
31; CHECK-DAG: call void @llvm.assume
32; CHECK: ret i32
33
34  %ptrint = ptrtoint i32* %a to i64
35  %maskedptr = and i64 %ptrint, 31
36  %maskcond = icmp eq i64 %maskedptr, 0
37  tail call void @llvm.assume(i1 %maskcond)
38
39  %0 = load i32, i32* %a, align 4
40  ret i32 %0
41}
42
43; Function Attrs: nounwind
44declare void @llvm.assume(i1) #1
45
46define i32 @simple(i32 %a) #1 {
47entry:
48
49; CHECK-LABEL: @simple
50; CHECK: call void @llvm.assume
51; CHECK: ret i32 4
52
53  %cmp = icmp eq i32 %a, 4
54  tail call void @llvm.assume(i1 %cmp)
55  ret i32 %a
56}
57
58; Function Attrs: nounwind uwtable
59define i32 @can1(i1 %a, i1 %b, i1 %c) {
60entry:
61  %and1 = and i1 %a, %b
62  %and  = and i1 %and1, %c
63  tail call void @llvm.assume(i1 %and)
64
65; CHECK-LABEL: @can1
66; CHECK: call void @llvm.assume(i1 %a)
67; CHECK: call void @llvm.assume(i1 %b)
68; CHECK: call void @llvm.assume(i1 %c)
69; CHECK: ret i32
70
71  ret i32 5
72}
73
74; Function Attrs: nounwind uwtable
75define i32 @can2(i1 %a, i1 %b, i1 %c) {
76entry:
77  %v = or i1 %a, %b
78  %w = xor i1 %v, 1
79  tail call void @llvm.assume(i1 %w)
80
81; CHECK-LABEL: @can2
82; CHECK: %[[V1:[^ ]+]] = xor i1 %a, true
83; CHECK: call void @llvm.assume(i1 %[[V1]])
84; CHECK: %[[V2:[^ ]+]] = xor i1 %b, true
85; CHECK: call void @llvm.assume(i1 %[[V2]])
86; CHECK: ret i32
87
88  ret i32 5
89}
90
91define i32 @bar1(i32 %a) #0 {
92entry:
93  %and1 = and i32 %a, 3
94
95; CHECK-LABEL: @bar1
96; CHECK: call void @llvm.assume
97; CHECK: ret i32 1
98
99  %and = and i32 %a, 7
100  %cmp = icmp eq i32 %and, 1
101  tail call void @llvm.assume(i1 %cmp)
102
103  ret i32 %and1
104}
105
106; Function Attrs: nounwind uwtable
107define i32 @bar2(i32 %a) #0 {
108entry:
109; CHECK-LABEL: @bar2
110; CHECK: call void @llvm.assume
111; CHECK: ret i32 1
112
113  %and = and i32 %a, 7
114  %cmp = icmp eq i32 %and, 1
115  tail call void @llvm.assume(i1 %cmp)
116
117  %and1 = and i32 %a, 3
118  ret i32 %and1
119}
120
121; Function Attrs: nounwind uwtable
122define i32 @bar3(i32 %a, i1 %x, i1 %y) #0 {
123entry:
124  %and1 = and i32 %a, 3
125
126; Don't be fooled by other assumes around.
127; CHECK-LABEL: @bar3
128; CHECK: call void @llvm.assume
129; CHECK: ret i32 1
130
131  tail call void @llvm.assume(i1 %x)
132
133  %and = and i32 %a, 7
134  %cmp = icmp eq i32 %and, 1
135  tail call void @llvm.assume(i1 %cmp)
136
137  tail call void @llvm.assume(i1 %y)
138
139  ret i32 %and1
140}
141
142; Function Attrs: nounwind uwtable
143define i32 @bar4(i32 %a, i32 %b) {
144entry:
145  %and1 = and i32 %b, 3
146
147; CHECK-LABEL: @bar4
148; CHECK: call void @llvm.assume
149; CHECK: call void @llvm.assume
150; CHECK: ret i32 1
151
152  %and = and i32 %a, 7
153  %cmp = icmp eq i32 %and, 1
154  tail call void @llvm.assume(i1 %cmp)
155
156  %cmp2 = icmp eq i32 %a, %b
157  tail call void @llvm.assume(i1 %cmp2)
158
159  ret i32 %and1
160}
161
162define i32 @icmp1(i32 %a) #0 {
163entry:
164  %cmp = icmp sgt i32 %a, 5
165  tail call void @llvm.assume(i1 %cmp)
166  %conv = zext i1 %cmp to i32
167  ret i32 %conv
168
169; CHECK-LABEL: @icmp1
170; CHECK: call void @llvm.assume
171; CHECK: ret i32 1
172
173}
174
175; Function Attrs: nounwind uwtable
176define i32 @icmp2(i32 %a) #0 {
177entry:
178  %cmp = icmp sgt i32 %a, 5
179  tail call void @llvm.assume(i1 %cmp)
180  %0 = zext i1 %cmp to i32
181  %lnot.ext = xor i32 %0, 1
182  ret i32 %lnot.ext
183
184; CHECK-LABEL: @icmp2
185; CHECK: call void @llvm.assume
186; CHECK: ret i32 0
187}
188
189declare void @escape(i32* %a)
190
191; Do we canonicalize a nonnull assumption on a load into
192; metadata form?
193define i1 @nonnull1(i32** %a) {
194entry:
195  %load = load i32*, i32** %a
196  %cmp = icmp ne i32* %load, null
197  tail call void @llvm.assume(i1 %cmp)
198  tail call void @escape(i32* %load)
199  %rval = icmp eq i32* %load, null
200  ret i1 %rval
201
202; CHECK-LABEL: @nonnull1
203; CHECK: !nonnull
204; CHECK-NOT: call void @llvm.assume
205; CHECK: ret i1 false
206}
207
208; Make sure the above canonicalization applies only
209; to pointer types.  Doing otherwise would be illegal.
210define i1 @nonnull2(i32* %a) {
211entry:
212  %load = load i32, i32* %a
213  %cmp = icmp ne i32 %load, 0
214  tail call void @llvm.assume(i1 %cmp)
215  %rval = icmp eq i32 %load, 0
216  ret i1 %rval
217
218; CHECK-LABEL: @nonnull2
219; CHECK-NOT: !nonnull
220; CHECK: call void @llvm.assume
221}
222
223; Make sure the above canonicalization does not trigger
224; if the assume is control dependent on something else
225define i1 @nonnull3(i32** %a, i1 %control) {
226entry:
227  %load = load i32*, i32** %a
228  %cmp = icmp ne i32* %load, null
229  br i1 %control, label %taken, label %not_taken
230taken:
231  tail call void @llvm.assume(i1 %cmp)
232  %rval = icmp eq i32* %load, null
233  ret i1 %rval
234not_taken:
235  ret i1 true
236
237; CHECK-LABEL: @nonnull3
238; CHECK-NOT: !nonnull
239; CHECK: call void @llvm.assume
240}
241
242; Make sure the above canonicalization does not trigger
243; if the path from the load to the assume is potentially
244; interrupted by an exception being thrown
245define i1 @nonnull4(i32** %a) {
246entry:
247  %load = load i32*, i32** %a
248  ;; This call may throw!
249  tail call void @escape(i32* %load)
250  %cmp = icmp ne i32* %load, null
251  tail call void @llvm.assume(i1 %cmp)
252  %rval = icmp eq i32* %load, null
253  ret i1 %rval
254
255; CHECK-LABEL: @nonnull4
256; CHECK-NOT: !nonnull
257; CHECK: call void @llvm.assume
258}
259
260
261
262
263attributes #0 = { nounwind uwtable }
264attributes #1 = { nounwind }
265
266