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, i32* %a, align 4
10
; Check that the alignment has been upgraded and that the assume has not
13
; CHECK-DAG: load i32, 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, 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, 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*, 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) {
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
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*, 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*, 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 }