1 ; RUN: opt < %s -instcombine -S | FileCheck %s
2 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3 target triple = "x86_64-unknown-linux-gnu"
5 ; Function Attrs: nounwind uwtable
6 define i32 @foo1(i32* %a) #0 {
8 %0 = load i32* %a, align 4
10 ; Check that the alignment has been upgraded and that the assume has not
13 ; CHECK-DAG: load i32* %a, align 32
14 ; CHECK-DAG: call void @llvm.assume
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)
25 ; Function Attrs: nounwind uwtable
26 define i32 @foo2(i32* %a) #0 {
28 ; Same check as in @foo1, but make sure it works if the assume is first too.
30 ; CHECK-DAG: load i32* %a, align 32
31 ; CHECK-DAG: call void @llvm.assume
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)
39 %0 = load i32* %a, align 4
43 ; Function Attrs: nounwind
44 declare void @llvm.assume(i1) #1
46 define i32 @simple(i32 %a) #1 {
49 ; CHECK-LABEL: @simple
50 ; CHECK: call void @llvm.assume
53 %cmp = icmp eq i32 %a, 4
54 tail call void @llvm.assume(i1 %cmp)
58 ; Function Attrs: nounwind uwtable
59 define i32 @can1(i1 %a, i1 %b, i1 %c) {
62 %and = and i1 %and1, %c
63 tail call void @llvm.assume(i1 %and)
66 ; CHECK: call void @llvm.assume(i1 %a)
67 ; CHECK: call void @llvm.assume(i1 %b)
68 ; CHECK: call void @llvm.assume(i1 %c)
74 ; Function Attrs: nounwind uwtable
75 define i32 @can2(i1 %a, i1 %b, i1 %c) {
79 tail call void @llvm.assume(i1 %w)
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]])
91 define i32 @bar1(i32 %a) #0 {
96 ; CHECK: call void @llvm.assume
100 %cmp = icmp eq i32 %and, 1
101 tail call void @llvm.assume(i1 %cmp)
106 ; Function Attrs: nounwind uwtable
107 define i32 @bar2(i32 %a) #0 {
110 ; CHECK: call void @llvm.assume
114 %cmp = icmp eq i32 %and, 1
115 tail call void @llvm.assume(i1 %cmp)
117 %and1 = and i32 %a, 3
121 ; Function Attrs: nounwind uwtable
122 define i32 @bar3(i32 %a, i1 %x, i1 %y) #0 {
124 %and1 = and i32 %a, 3
126 ; Don't be fooled by other assumes around.
128 ; CHECK: call void @llvm.assume
131 tail call void @llvm.assume(i1 %x)
134 %cmp = icmp eq i32 %and, 1
135 tail call void @llvm.assume(i1 %cmp)
137 tail call void @llvm.assume(i1 %y)
142 ; Function Attrs: nounwind uwtable
143 define i32 @bar4(i32 %a, i32 %b) {
145 %and1 = and i32 %b, 3
148 ; CHECK: call void @llvm.assume
149 ; CHECK: call void @llvm.assume
153 %cmp = icmp eq i32 %and, 1
154 tail call void @llvm.assume(i1 %cmp)
156 %cmp2 = icmp eq i32 %a, %b
157 tail call void @llvm.assume(i1 %cmp2)
162 define i32 @icmp1(i32 %a) #0 {
164 %cmp = icmp sgt i32 %a, 5
165 tail call void @llvm.assume(i1 %cmp)
166 %conv = zext i1 %cmp to i32
169 ; CHECK-LABEL: @icmp1
170 ; CHECK: call void @llvm.assume
175 ; Function Attrs: nounwind uwtable
176 define i32 @icmp2(i32 %a) #0 {
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
184 ; CHECK-LABEL: @icmp2
185 ; CHECK: call void @llvm.assume
189 declare void @escape(i32* %a)
191 ; Do we canonicalize a nonnull assumption on a load into
193 define i1 @nonnull1(i32** %a) {
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
202 ; CHECK-LABEL: @nonnull1
204 ; CHECK-NOT: call void @llvm.assume
205 ; CHECK: ret i1 false
208 ; Make sure the above canonicalization applies only
209 ; to pointer types. Doing otherwise would be illegal.
210 define i1 @nonnull2(i32* %a) {
213 %cmp = icmp ne i32 %load, 0
214 tail call void @llvm.assume(i1 %cmp)
215 %rval = icmp eq i32 %load, 0
218 ; CHECK-LABEL: @nonnull2
219 ; CHECK-NOT: !nonnull
220 ; CHECK: call void @llvm.assume
223 ; Make sure the above canonicalization does not trigger
224 ; if the assume is control dependent on something else
225 define i1 @nonnull3(i32** %a, i1 %control) {
227 %load = load i32** %a
228 %cmp = icmp ne i32* %load, null
229 br i1 %control, label %taken, label %not_taken
231 tail call void @llvm.assume(i1 %cmp)
232 %rval = icmp eq i32* %load, null
237 ; CHECK-LABEL: @nonnull3
238 ; CHECK-NOT: !nonnull
239 ; CHECK: call void @llvm.assume
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
245 define i1 @nonnull4(i32** %a) {
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
255 ; CHECK-LABEL: @nonnull4
256 ; CHECK-NOT: !nonnull
257 ; CHECK: call void @llvm.assume
263 attributes #0 = { nounwind uwtable }
264 attributes #1 = { nounwind }