1 ; RUN: opt -S -codegenprepare -mtriple=x86_64-unknown-unknown -mattr=+bmi < %s | FileCheck %s --check-prefix=ALL --check-prefix=BMI
2 ; RUN: opt -S -codegenprepare -mtriple=x86_64-unknown-unknown -mattr=+lzcnt < %s | FileCheck %s --check-prefix=ALL --check-prefix=LZCNT
3 ; RUN: opt -S -codegenprepare -mtriple=x86_64-unknown-unknown < %s | FileCheck %s --check-prefix=ALL --check-prefix=GENERIC
6 define i64 @test1(i64 %A) {
8 ; LZCNT: [[CTLZ:%[A-Za-z0-9]+]] = call i64 @llvm.ctlz.i64(i64 %A, i1 false)
9 ; LZCNT-NEXT: ret i64 [[CTLZ]]
10 ; BMI: icmp eq i64 %A, 0
11 ; BMI: call i64 @llvm.ctlz.i64(i64 %A, i1 true)
12 ; GENERIC: icmp eq i64 %A, 0
13 ; GENERIC: call i64 @llvm.ctlz.i64(i64 %A, i1 true)
15 %tobool = icmp eq i64 %A, 0
16 br i1 %tobool, label %cond.end, label %cond.true
18 cond.true: ; preds = %entry
19 %0 = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
22 cond.end: ; preds = %entry, %cond.true
23 %cond = phi i64 [ %0, %cond.true ], [ 64, %entry ]
28 define i32 @test2(i32 %A) {
30 ; LZCNT: [[CTLZ:%[A-Za-z0-9]+]] = call i32 @llvm.ctlz.i32(i32 %A, i1 false)
31 ; LZCNT-NEXT: ret i32 [[CTLZ]]
32 ; BMI: icmp eq i32 %A, 0
33 ; BMI: call i32 @llvm.ctlz.i32(i32 %A, i1 true)
34 ; GENERIC: icmp eq i32 %A, 0
35 ; GENERIC: call i32 @llvm.ctlz.i32(i32 %A, i1 true)
37 %tobool = icmp eq i32 %A, 0
38 br i1 %tobool, label %cond.end, label %cond.true
40 cond.true: ; preds = %entry
41 %0 = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
44 cond.end: ; preds = %entry, %cond.true
45 %cond = phi i32 [ %0, %cond.true ], [ 32, %entry ]
50 define signext i16 @test3(i16 signext %A) {
52 ; LZCNT: [[CTLZ:%[A-Za-z0-9]+]] = call i16 @llvm.ctlz.i16(i16 %A, i1 false)
53 ; LZCNT-NEXT: ret i16 [[CTLZ]]
54 ; BMI: icmp eq i16 %A, 0
55 ; BMI: call i16 @llvm.ctlz.i16(i16 %A, i1 true)
56 ; GENERIC: icmp eq i16 %A, 0
57 ; GENERIC: call i16 @llvm.ctlz.i16(i16 %A, i1 true)
59 %tobool = icmp eq i16 %A, 0
60 br i1 %tobool, label %cond.end, label %cond.true
62 cond.true: ; preds = %entry
63 %0 = tail call i16 @llvm.ctlz.i16(i16 %A, i1 true)
66 cond.end: ; preds = %entry, %cond.true
67 %cond = phi i16 [ %0, %cond.true ], [ 16, %entry ]
72 define i64 @test1b(i64 %A) {
74 ; LZCNT: icmp eq i64 %A, 0
75 ; LZCNT: call i64 @llvm.cttz.i64(i64 %A, i1 true)
76 ; BMI: [[CTTZ:%[A-Za-z0-9]+]] = call i64 @llvm.cttz.i64(i64 %A, i1 false)
77 ; BMI-NEXT: ret i64 [[CTTZ]]
78 ; GENERIC: icmp eq i64 %A, 0
79 ; GENERIC: call i64 @llvm.cttz.i64(i64 %A, i1 true)
81 %tobool = icmp eq i64 %A, 0
82 br i1 %tobool, label %cond.end, label %cond.true
84 cond.true: ; preds = %entry
85 %0 = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
88 cond.end: ; preds = %entry, %cond.true
89 %cond = phi i64 [ %0, %cond.true ], [ 64, %entry ]
94 define i32 @test2b(i32 %A) {
96 ; LZCNT: icmp eq i32 %A, 0
97 ; LZCNT: call i32 @llvm.cttz.i32(i32 %A, i1 true)
98 ; BMI: [[CTTZ:%[A-Za-z0-9]+]] = call i32 @llvm.cttz.i32(i32 %A, i1 false)
99 ; BMI-NEXT: ret i32 [[CTTZ]]
100 ; GENERIC: icmp eq i32 %A, 0
101 ; GENERIC: call i32 @llvm.cttz.i32(i32 %A, i1 true)
103 %tobool = icmp eq i32 %A, 0
104 br i1 %tobool, label %cond.end, label %cond.true
106 cond.true: ; preds = %entry
107 %0 = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
110 cond.end: ; preds = %entry, %cond.true
111 %cond = phi i32 [ %0, %cond.true ], [ 32, %entry ]
116 define signext i16 @test3b(i16 signext %A) {
117 ; ALL-LABEL: @test3b(
118 ; LZCNT: icmp eq i16 %A, 0
119 ; LZCNT: call i16 @llvm.cttz.i16(i16 %A, i1 true)
120 ; BMI: [[CTTZ:%[A-Za-z0-9]+]] = call i16 @llvm.cttz.i16(i16 %A, i1 false)
121 ; BMI-NEXT: ret i16 [[CTTZ]]
122 ; GENERIC: icmp eq i16 %A, 0
123 ; GENERIC: call i16 @llvm.cttz.i16(i16 %A, i1 true)
125 %tobool = icmp eq i16 %A, 0
126 br i1 %tobool, label %cond.end, label %cond.true
128 cond.true: ; preds = %entry
129 %0 = tail call i16 @llvm.cttz.i16(i16 %A, i1 true)
132 cond.end: ; preds = %entry, %cond.true
133 %cond = phi i16 [ %0, %cond.true ], [ 16, %entry ]
138 define i64 @test1c(i64 %A) {
139 ; ALL-LABEL: @test1c(
140 ; ALL: icmp eq i64 %A, 0
141 ; ALL: call i64 @llvm.ctlz.i64(i64 %A, i1 true)
143 %tobool = icmp eq i64 %A, 0
144 br i1 %tobool, label %cond.end, label %cond.true
146 cond.true: ; preds = %entry
147 %0 = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
150 cond.end: ; preds = %entry, %cond.true
151 %cond = phi i64 [ %0, %cond.true ], [ 63, %entry ]
155 define i32 @test2c(i32 %A) {
156 ; ALL-LABEL: @test2c(
157 ; ALL: icmp eq i32 %A, 0
158 ; ALL: call i32 @llvm.ctlz.i32(i32 %A, i1 true)
160 %tobool = icmp eq i32 %A, 0
161 br i1 %tobool, label %cond.end, label %cond.true
163 cond.true: ; preds = %entry
164 %0 = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
167 cond.end: ; preds = %entry, %cond.true
168 %cond = phi i32 [ %0, %cond.true ], [ 31, %entry ]
173 define signext i16 @test3c(i16 signext %A) {
174 ; ALL-LABEL: @test3c(
175 ; ALL: icmp eq i16 %A, 0
176 ; ALL: call i16 @llvm.ctlz.i16(i16 %A, i1 true)
178 %tobool = icmp eq i16 %A, 0
179 br i1 %tobool, label %cond.end, label %cond.true
181 cond.true: ; preds = %entry
182 %0 = tail call i16 @llvm.ctlz.i16(i16 %A, i1 true)
185 cond.end: ; preds = %entry, %cond.true
186 %cond = phi i16 [ %0, %cond.true ], [ 15, %entry ]
191 define i64 @test1d(i64 %A) {
192 ; ALL-LABEL: @test1d(
193 ; ALL: icmp eq i64 %A, 0
194 ; ALL: call i64 @llvm.cttz.i64(i64 %A, i1 true)
196 %tobool = icmp eq i64 %A, 0
197 br i1 %tobool, label %cond.end, label %cond.true
199 cond.true: ; preds = %entry
200 %0 = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
203 cond.end: ; preds = %entry, %cond.true
204 %cond = phi i64 [ %0, %cond.true ], [ 63, %entry ]
209 define i32 @test2d(i32 %A) {
210 ; ALL-LABEL: @test2d(
211 ; ALL: icmp eq i32 %A, 0
212 ; ALL: call i32 @llvm.cttz.i32(i32 %A, i1 true)
214 %tobool = icmp eq i32 %A, 0
215 br i1 %tobool, label %cond.end, label %cond.true
217 cond.true: ; preds = %entry
218 %0 = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
221 cond.end: ; preds = %entry, %cond.true
222 %cond = phi i32 [ %0, %cond.true ], [ 31, %entry ]
227 define signext i16 @test3d(i16 signext %A) {
228 ; ALL-LABEL: @test3d(
229 ; ALL: icmp eq i16 %A, 0
230 ; ALL: call i16 @llvm.cttz.i16(i16 %A, i1 true)
232 %tobool = icmp eq i16 %A, 0
233 br i1 %tobool, label %cond.end, label %cond.true
235 cond.true: ; preds = %entry
236 %0 = tail call i16 @llvm.cttz.i16(i16 %A, i1 true)
239 cond.end: ; preds = %entry, %cond.true
240 %cond = phi i16 [ %0, %cond.true ], [ 15, %entry ]
245 declare i64 @llvm.ctlz.i64(i64, i1)
246 declare i32 @llvm.ctlz.i32(i32, i1)
247 declare i16 @llvm.ctlz.i16(i16, i1)
248 declare i64 @llvm.cttz.i64(i64, i1)
249 declare i32 @llvm.cttz.i32(i32, i1)
250 declare i16 @llvm.cttz.i16(i16, i1)