1
; RUN: llc < %s -march=x86-64 -mattr=+bmi,+bmi2 | FileCheck %s
3
declare i8 @llvm.cttz.i8(i8, i1) nounwind readnone
4
declare i16 @llvm.cttz.i16(i16, i1) nounwind readnone
5
declare i32 @llvm.cttz.i32(i32, i1) nounwind readnone
6
declare i64 @llvm.cttz.i64(i64, i1) nounwind readnone
8
define i8 @t1(i8 %x) nounwind {
9
%tmp = tail call i8 @llvm.cttz.i8( i8 %x, i1 false )
15
define i16 @t2(i16 %x) nounwind {
16
%tmp = tail call i16 @llvm.cttz.i16( i16 %x, i1 false )
22
define i32 @t3(i32 %x) nounwind {
23
%tmp = tail call i32 @llvm.cttz.i32( i32 %x, i1 false )
29
define i32 @tzcnt32_load(i32* %x) nounwind {
30
%x1 = load i32, i32* %x
31
%tmp = tail call i32 @llvm.cttz.i32(i32 %x1, i1 false )
33
; CHECK-LABEL: tzcnt32_load:
34
; CHECK: tzcntl ({{.*}})
37
define i64 @t4(i64 %x) nounwind {
38
%tmp = tail call i64 @llvm.cttz.i64( i64 %x, i1 false )
44
define i8 @t5(i8 %x) nounwind {
45
%tmp = tail call i8 @llvm.cttz.i8( i8 %x, i1 true )
51
define i16 @t6(i16 %x) nounwind {
52
%tmp = tail call i16 @llvm.cttz.i16( i16 %x, i1 true )
58
define i32 @t7(i32 %x) nounwind {
59
%tmp = tail call i32 @llvm.cttz.i32( i32 %x, i1 true )
65
define i64 @t8(i64 %x) nounwind {
66
%tmp = tail call i64 @llvm.cttz.i64( i64 %x, i1 true )
72
define i32 @andn32(i32 %x, i32 %y) nounwind readnone {
73
%tmp1 = xor i32 %x, -1
74
%tmp2 = and i32 %y, %tmp1
76
; CHECK-LABEL: andn32:
80
define i32 @andn32_load(i32 %x, i32* %y) nounwind readnone {
81
%y1 = load i32, i32* %y
82
%tmp1 = xor i32 %x, -1
83
%tmp2 = and i32 %y1, %tmp1
85
; CHECK-LABEL: andn32_load:
86
; CHECK: andnl ({{.*}})
89
define i64 @andn64(i64 %x, i64 %y) nounwind readnone {
90
%tmp1 = xor i64 %x, -1
91
%tmp2 = and i64 %tmp1, %y
93
; CHECK-LABEL: andn64:
97
define i32 @bextr32(i32 %x, i32 %y) nounwind readnone {
98
%tmp = tail call i32 @llvm.x86.bmi.bextr.32(i32 %x, i32 %y)
100
; CHECK-LABEL: bextr32:
104
define i32 @bextr32_load(i32* %x, i32 %y) nounwind readnone {
105
%x1 = load i32, i32* %x
106
%tmp = tail call i32 @llvm.x86.bmi.bextr.32(i32 %x1, i32 %y)
108
; CHECK-LABEL: bextr32_load:
109
; CHECK: bextrl {{.*}}, ({{.*}}), {{.*}}
112
declare i32 @llvm.x86.bmi.bextr.32(i32, i32) nounwind readnone
114
define i32 @bextr32b(i32 %x) nounwind uwtable readnone ssp {
116
%2 = and i32 %1, 4095
118
; CHECK-LABEL: bextr32b:
122
define i32 @bextr32b_load(i32* %x) nounwind uwtable readnone ssp {
123
%1 = load i32, i32* %x
125
%3 = and i32 %2, 4095
127
; CHECK-LABEL: bextr32b_load:
128
; CHECK: bextrl {{.*}}, ({{.*}}), {{.*}}
131
define i64 @bextr64(i64 %x, i64 %y) nounwind readnone {
132
%tmp = tail call i64 @llvm.x86.bmi.bextr.64(i64 %x, i64 %y)
134
; CHECK-LABEL: bextr64:
138
declare i64 @llvm.x86.bmi.bextr.64(i64, i64) nounwind readnone
140
define i64 @bextr64b(i64 %x) nounwind uwtable readnone ssp {
142
%2 = and i64 %1, 4095
144
; CHECK-LABEL: bextr64b:
148
define i64 @bextr64b_load(i64* %x) {
149
%1 = load i64, i64* %x, align 8
151
%3 = and i64 %2, 4095
153
; CHECK-LABEL: bextr64b_load:
154
; CHECK: bextrq {{.*}}, ({{.*}}), {{.*}}
157
define i32 @non_bextr32(i32 %x) {
159
%shr = lshr i32 %x, 2
160
%and = and i32 %shr, 111
162
; CHECK-LABEL: non_bextr32:
167
define i64 @non_bextr64(i64 %x) {
169
%shr = lshr i64 %x, 2
170
%and = and i64 %shr, 8589934590
172
; CHECK-LABEL: non_bextr64:
174
; CHECK: movabsq $8589934590
178
define i32 @bzhi32(i32 %x, i32 %y) nounwind readnone {
179
%tmp = tail call i32 @llvm.x86.bmi.bzhi.32(i32 %x, i32 %y)
181
; CHECK-LABEL: bzhi32:
185
define i32 @bzhi32_load(i32* %x, i32 %y) nounwind readnone {
186
%x1 = load i32, i32* %x
187
%tmp = tail call i32 @llvm.x86.bmi.bzhi.32(i32 %x1, i32 %y)
189
; CHECK-LABEL: bzhi32_load:
190
; CHECK: bzhil {{.*}}, ({{.*}}), {{.*}}
193
declare i32 @llvm.x86.bmi.bzhi.32(i32, i32) nounwind readnone
195
define i64 @bzhi64(i64 %x, i64 %y) nounwind readnone {
196
%tmp = tail call i64 @llvm.x86.bmi.bzhi.64(i64 %x, i64 %y)
198
; CHECK-LABEL: bzhi64:
202
declare i64 @llvm.x86.bmi.bzhi.64(i64, i64) nounwind readnone
204
define i32 @bzhi32b(i32 %x, i8 zeroext %index) #0 {
206
%conv = zext i8 %index to i32
207
%shl = shl i32 1, %conv
208
%sub = add nsw i32 %shl, -1
209
%and = and i32 %sub, %x
211
; CHECK-LABEL: bzhi32b:
215
define i32 @bzhi32b_load(i32* %w, i8 zeroext %index) #0 {
217
%x = load i32, i32* %w
218
%conv = zext i8 %index to i32
219
%shl = shl i32 1, %conv
220
%sub = add nsw i32 %shl, -1
221
%and = and i32 %sub, %x
223
; CHECK-LABEL: bzhi32b_load:
224
; CHECK: bzhil {{.*}}, ({{.*}}), {{.*}}
227
define i32 @bzhi32c(i32 %x, i8 zeroext %index) #0 {
229
%conv = zext i8 %index to i32
230
%shl = shl i32 1, %conv
231
%sub = add nsw i32 %shl, -1
232
%and = and i32 %x, %sub
234
; CHECK-LABEL: bzhi32c:
238
define i64 @bzhi64b(i64 %x, i8 zeroext %index) #0 {
240
%conv = zext i8 %index to i64
241
%shl = shl i64 1, %conv
242
%sub = add nsw i64 %shl, -1
243
%and = and i64 %x, %sub
245
; CHECK-LABEL: bzhi64b:
249
define i64 @bzhi64_constant_mask(i64 %x) #0 {
251
%and = and i64 %x, 4611686018427387903
253
; CHECK-LABEL: bzhi64_constant_mask:
254
; CHECK: movb $62, %al
255
; CHECK: bzhiq %rax, %r[[ARG1:di|cx]], %rax
258
define i64 @bzhi64_small_constant_mask(i64 %x) #0 {
260
%and = and i64 %x, 2147483647
262
; CHECK-LABEL: bzhi64_small_constant_mask:
263
; CHECK: andl $2147483647, %e[[ARG1]]
266
define i32 @blsi32(i32 %x) nounwind readnone {
268
%tmp2 = and i32 %x, %tmp
270
; CHECK-LABEL: blsi32:
274
define i32 @blsi32_load(i32* %x) nounwind readnone {
275
%x1 = load i32, i32* %x
276
%tmp = sub i32 0, %x1
277
%tmp2 = and i32 %x1, %tmp
279
; CHECK-LABEL: blsi32_load:
280
; CHECK: blsil ({{.*}})
283
define i64 @blsi64(i64 %x) nounwind readnone {
285
%tmp2 = and i64 %tmp, %x
287
; CHECK-LABEL: blsi64:
291
define i32 @blsmsk32(i32 %x) nounwind readnone {
293
%tmp2 = xor i32 %x, %tmp
295
; CHECK-LABEL: blsmsk32:
299
define i32 @blsmsk32_load(i32* %x) nounwind readnone {
300
%x1 = load i32, i32* %x
301
%tmp = sub i32 %x1, 1
302
%tmp2 = xor i32 %x1, %tmp
304
; CHECK-LABEL: blsmsk32_load:
305
; CHECK: blsmskl ({{.*}})
308
define i64 @blsmsk64(i64 %x) nounwind readnone {
310
%tmp2 = xor i64 %tmp, %x
312
; CHECK-LABEL: blsmsk64:
316
define i32 @blsr32(i32 %x) nounwind readnone {
318
%tmp2 = and i32 %x, %tmp
320
; CHECK-LABEL: blsr32:
324
define i32 @blsr32_load(i32* %x) nounwind readnone {
325
%x1 = load i32, i32* %x
326
%tmp = sub i32 %x1, 1
327
%tmp2 = and i32 %x1, %tmp
329
; CHECK-LABEL: blsr32_load:
330
; CHECK: blsrl ({{.*}})
333
define i64 @blsr64(i64 %x) nounwind readnone {
335
%tmp2 = and i64 %tmp, %x
337
; CHECK-LABEL: blsr64:
341
define i32 @pdep32(i32 %x, i32 %y) nounwind readnone {
342
%tmp = tail call i32 @llvm.x86.bmi.pdep.32(i32 %x, i32 %y)
344
; CHECK-LABEL: pdep32:
348
define i32 @pdep32_load(i32 %x, i32* %y) nounwind readnone {
349
%y1 = load i32, i32* %y
350
%tmp = tail call i32 @llvm.x86.bmi.pdep.32(i32 %x, i32 %y1)
352
; CHECK-LABEL: pdep32_load:
353
; CHECK: pdepl ({{.*}})
356
declare i32 @llvm.x86.bmi.pdep.32(i32, i32) nounwind readnone
358
define i64 @pdep64(i64 %x, i64 %y) nounwind readnone {
359
%tmp = tail call i64 @llvm.x86.bmi.pdep.64(i64 %x, i64 %y)
361
; CHECK-LABEL: pdep64:
365
declare i64 @llvm.x86.bmi.pdep.64(i64, i64) nounwind readnone
367
define i32 @pext32(i32 %x, i32 %y) nounwind readnone {
368
%tmp = tail call i32 @llvm.x86.bmi.pext.32(i32 %x, i32 %y)
370
; CHECK-LABEL: pext32:
374
define i32 @pext32_load(i32 %x, i32* %y) nounwind readnone {
375
%y1 = load i32, i32* %y
376
%tmp = tail call i32 @llvm.x86.bmi.pext.32(i32 %x, i32 %y1)
378
; CHECK-LABEL: pext32_load:
379
; CHECK: pextl ({{.*}})
382
declare i32 @llvm.x86.bmi.pext.32(i32, i32) nounwind readnone
384
define i64 @pext64(i64 %x, i64 %y) nounwind readnone {
385
%tmp = tail call i64 @llvm.x86.bmi.pext.64(i64 %x, i64 %y)
387
; CHECK-LABEL: pext64:
391
declare i64 @llvm.x86.bmi.pext.64(i64, i64) nounwind readnone