1; Test that the ffs* library call simplifier works correctly.
2;
3; RUN: opt < %s -instcombine -S                                    | FileCheck %s --check-prefix=ALL --check-prefix=GENERIC
4; RUN: opt < %s -instcombine -mtriple i386-pc-linux -S             | FileCheck %s --check-prefix=ALL --check-prefix=TARGET
5; RUN: opt < %s -instcombine -mtriple=arm64-apple-ios9.0 -S        | FileCheck %s --check-prefix=ALL --check-prefix=TARGET
6; RUN: opt < %s -instcombine -mtriple=arm64-apple-tvos9.0 -S       | FileCheck %s --check-prefix=ALL --check-prefix=TARGET
7; RUN: opt < %s -instcombine -mtriple=thumbv7k-apple-watchos2.0 -S | FileCheck %s --check-prefix=ALL --check-prefix=TARGET
8; RUN: opt < %s -instcombine -mtriple=x86_64-apple-macosx10.11 -S  | FileCheck %s --check-prefix=ALL --check-prefix=TARGET
9; RUN: opt < %s -instcombine -mtriple=x86_64-freebsd-gnu -S        | FileCheck %s --check-prefix=ALL --check-prefix=TARGET
10
11declare i32 @ffs(i32)
12declare i32 @ffsl(i32)
13declare i32 @ffsll(i64)
14
15; Check ffs(0) -> 0.
16
17define i32 @test_simplify1() {
18; ALL-LABEL: @test_simplify1(
19; ALL-NEXT:    ret i32 0
20;
21  %ret = call i32 @ffs(i32 0)
22  ret i32 %ret
23}
24
25define i32 @test_simplify2() {
26; GENERIC-LABEL: @test_simplify2(
27; GENERIC-NEXT:    [[RET:%.*]] = call i32 @ffsl(i32 0)
28; GENERIC-NEXT:    ret i32 [[RET]]
29;
30; TARGET-LABEL: @test_simplify2(
31; TARGET-NEXT:    ret i32 0
32;
33  %ret = call i32 @ffsl(i32 0)
34  ret i32 %ret
35}
36
37define i32 @test_simplify3() {
38; GENERIC-LABEL: @test_simplify3(
39; GENERIC-NEXT:    [[RET:%.*]] = call i32 @ffsll(i64 0)
40; GENERIC-NEXT:    ret i32 [[RET]]
41;
42; TARGET-LABEL: @test_simplify3(
43; TARGET-NEXT:    ret i32 0
44;
45  %ret = call i32 @ffsll(i64 0)
46  ret i32 %ret
47}
48
49; Check ffs(c) -> cttz(c) + 1, where 'c' is a constant.
50
51define i32 @test_simplify4() {
52; ALL-LABEL: @test_simplify4(
53; ALL-NEXT:    ret i32 1
54;
55  %ret = call i32 @ffs(i32 1)
56  ret i32 %ret
57}
58
59define i32 @test_simplify5() {
60; ALL-LABEL: @test_simplify5(
61; ALL-NEXT:    ret i32 12
62;
63  %ret = call i32 @ffs(i32 2048)
64  ret i32 %ret
65}
66
67define i32 @test_simplify6() {
68; ALL-LABEL: @test_simplify6(
69; ALL-NEXT:    ret i32 17
70;
71  %ret = call i32 @ffs(i32 65536)
72  ret i32 %ret
73}
74
75define i32 @test_simplify7() {
76; GENERIC-LABEL: @test_simplify7(
77; GENERIC-NEXT:    [[RET:%.*]] = call i32 @ffsl(i32 65536)
78; GENERIC-NEXT:    ret i32 [[RET]]
79;
80; TARGET-LABEL: @test_simplify7(
81; TARGET-NEXT:    ret i32 17
82;
83  %ret = call i32 @ffsl(i32 65536)
84  ret i32 %ret
85}
86
87define i32 @test_simplify8() {
88; GENERIC-LABEL: @test_simplify8(
89; GENERIC-NEXT:    [[RET:%.*]] = call i32 @ffsll(i64 1024)
90; GENERIC-NEXT:    ret i32 [[RET]]
91;
92; TARGET-LABEL: @test_simplify8(
93; TARGET-NEXT:    ret i32 11
94;
95  %ret = call i32 @ffsll(i64 1024)
96  ret i32 %ret
97}
98
99define i32 @test_simplify9() {
100; GENERIC-LABEL: @test_simplify9(
101; GENERIC-NEXT:    [[RET:%.*]] = call i32 @ffsll(i64 65536)
102; GENERIC-NEXT:    ret i32 [[RET]]
103;
104; TARGET-LABEL: @test_simplify9(
105; TARGET-NEXT:    ret i32 17
106;
107  %ret = call i32 @ffsll(i64 65536)
108  ret i32 %ret
109}
110
111define i32 @test_simplify10() {
112; GENERIC-LABEL: @test_simplify10(
113; GENERIC-NEXT:    [[RET:%.*]] = call i32 @ffsll(i64 17179869184)
114; GENERIC-NEXT:    ret i32 [[RET]]
115;
116; TARGET-LABEL: @test_simplify10(
117; TARGET-NEXT:    ret i32 35
118;
119  %ret = call i32 @ffsll(i64 17179869184)
120  ret i32 %ret
121}
122
123define i32 @test_simplify11() {
124; GENERIC-LABEL: @test_simplify11(
125; GENERIC-NEXT:    [[RET:%.*]] = call i32 @ffsll(i64 281474976710656)
126; GENERIC-NEXT:    ret i32 [[RET]]
127;
128; TARGET-LABEL: @test_simplify11(
129; TARGET-NEXT:    ret i32 49
130;
131  %ret = call i32 @ffsll(i64 281474976710656)
132  ret i32 %ret
133}
134
135define i32 @test_simplify12() {
136; GENERIC-LABEL: @test_simplify12(
137; GENERIC-NEXT:    [[RET:%.*]] = call i32 @ffsll(i64 1152921504606846976)
138; GENERIC-NEXT:    ret i32 [[RET]]
139;
140; TARGET-LABEL: @test_simplify12(
141; TARGET-NEXT:    ret i32 61
142;
143  %ret = call i32 @ffsll(i64 1152921504606846976)
144  ret i32 %ret
145}
146
147; Check ffs(x) -> x != 0 ? (i32)llvm.cttz(x) + 1 : 0.
148
149define i32 @test_simplify13(i32 %x) {
150; ALL-LABEL: @test_simplify13(
151; ALL-NEXT:    [[CTTZ:%.*]] = call i32 @llvm.cttz.i32(i32 %x, i1 true), !range !0
152; ALL-NEXT:    [[TMP1:%.*]] = add nuw nsw i32 [[CTTZ]], 1
153; ALL-NEXT:    [[TMP2:%.*]] = icmp eq i32 %x, 0
154; ALL-NEXT:    [[TMP3:%.*]] = select i1 [[TMP2]], i32 0, i32 [[TMP1]]
155; ALL-NEXT:    ret i32 [[TMP3]]
156;
157  %ret = call i32 @ffs(i32 %x)
158  ret i32 %ret
159}
160
161define i32 @test_simplify14(i32 %x) {
162; GENERIC-LABEL: @test_simplify14(
163; GENERIC-NEXT:    [[RET:%.*]] = call i32 @ffsl(i32 %x)
164; GENERIC-NEXT:    ret i32 [[RET]]
165;
166; TARGET-LABEL: @test_simplify14(
167; TARGET-NEXT:    [[CTTZ:%.*]] = call i32 @llvm.cttz.i32(i32 %x, i1 true), !range !0
168; TARGET-NEXT:    [[TMP1:%.*]] = add nuw nsw i32 [[CTTZ]], 1
169; TARGET-NEXT:    [[TMP2:%.*]] = icmp eq i32 %x, 0
170; TARGET-NEXT:    [[TMP3:%.*]] = select i1 [[TMP2]], i32 0, i32 [[TMP1]]
171; TARGET-NEXT:    ret i32 [[TMP3]]
172;
173  %ret = call i32 @ffsl(i32 %x)
174  ret i32 %ret
175}
176
177define i32 @test_simplify15(i64 %x) {
178; GENERIC-LABEL: @test_simplify15(
179; GENERIC-NEXT:    [[RET:%.*]] = call i32 @ffsll(i64 %x)
180; GENERIC-NEXT:    ret i32 [[RET]]
181;
182; TARGET-LABEL: @test_simplify15(
183; TARGET-NEXT:    [[CTTZ:%.*]] = call i64 @llvm.cttz.i64(i64 %x, i1 true), !range !1
184; TARGET-NEXT:    [[TMP1:%.*]] = trunc i64 [[CTTZ]] to i32
185; TARGET-NEXT:    [[TMP2:%.*]] = add nuw nsw i32 [[TMP1]], 1
186; TARGET-NEXT:    [[TMP3:%.*]] = icmp eq i64 %x, 0
187; TARGET-NEXT:    [[TMP4:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
188; TARGET-NEXT:    ret i32 [[TMP4]]
189;
190  %ret = call i32 @ffsll(i64 %x)
191  ret i32 %ret
192}
193
194