blob: 7e45c04622ac74461cc5526b09013a5f87ff6ac9 [file] [log] [blame]
Hal Finkelf5867a72014-07-25 21:45:17 +00001; 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
Hal Finkel60db0582014-09-07 18:57:58 +00005; Function Attrs: nounwind uwtable
6define i32 @foo1(i32* %a) #0 {
7entry:
8 %0 = load 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* %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* %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* %a, align 4
40 ret i32 %0
41}
42
Hal Finkelf5867a72014-07-25 21:45:17 +000043; Function Attrs: nounwind
44declare void @llvm.assume(i1) #1
45
Hal Finkel93873cc12014-09-07 21:28:34 +000046define 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
Hal Finkelf5867a72014-07-25 21:45:17 +000058; 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
Hal Finkel60db0582014-09-07 18:57:58 +000091define 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
Philip Reames66c6de62014-11-11 23:33:19 +0000189declare 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** %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* %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** %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** %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
Hal Finkelf5867a72014-07-25 21:45:17 +0000263attributes #0 = { nounwind uwtable }
264attributes #1 = { nounwind }
265