[SimplifyLibCalls] Correctly set the is_zero_undef flag for llvm.cttz
[oota-llvm.git] / test / Transforms / InstCombine / ffs-1.ll
1 ; Test that the ffs* library call simplifier works correctly.
2 ;
3 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 ; RUN: opt < %s -mtriple i386-pc-linux -instcombine -S | FileCheck %s -check-prefix=CHECK-LINUX
5
6 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
7
8 declare i32 @ffs(i32)
9 declare i32 @ffsl(i32)
10 declare i32 @ffsll(i64)
11
12 ; Check ffs(0) -> 0.
13
14 define i32 @test_simplify1() {
15 ; CHECK-LABEL: @test_simplify1(
16   %ret = call i32 @ffs(i32 0)
17   ret i32 %ret
18 ; CHECK-NEXT: ret i32 0
19 }
20
21 define i32 @test_simplify2() {
22 ; CHECK-LINUX-LABEL: @test_simplify2(
23   %ret = call i32 @ffsl(i32 0)
24   ret i32 %ret
25 ; CHECK-LINUX-NEXT: ret i32 0
26 }
27
28 define i32 @test_simplify3() {
29 ; CHECK-LINUX-LABEL: @test_simplify3(
30   %ret = call i32 @ffsll(i64 0)
31   ret i32 %ret
32 ; CHECK-LINUX-NEXT: ret i32 0
33 }
34
35 ; Check ffs(c) -> cttz(c) + 1, where 'c' is a constant.
36
37 define i32 @test_simplify4() {
38 ; CHECK-LABEL: @test_simplify4(
39   %ret = call i32 @ffs(i32 1)
40   ret i32 %ret
41 ; CHECK-NEXT: ret i32 1
42 }
43
44 define i32 @test_simplify5() {
45 ; CHECK-LABEL: @test_simplify5(
46   %ret = call i32 @ffs(i32 2048)
47   ret i32 %ret
48 ; CHECK-NEXT: ret i32 12
49 }
50
51 define i32 @test_simplify6() {
52 ; CHECK-LABEL: @test_simplify6(
53   %ret = call i32 @ffs(i32 65536)
54   ret i32 %ret
55 ; CHECK-NEXT: ret i32 17
56 }
57
58 define i32 @test_simplify7() {
59 ; CHECK-LINUX-LABEL: @test_simplify7(
60   %ret = call i32 @ffsl(i32 65536)
61   ret i32 %ret
62 ; CHECK-LINUX-NEXT: ret i32 17
63 }
64
65 define i32 @test_simplify8() {
66 ; CHECK-LINUX-LABEL: @test_simplify8(
67   %ret = call i32 @ffsll(i64 1024)
68   ret i32 %ret
69 ; CHECK-LINUX-NEXT: ret i32 11
70 }
71
72 define i32 @test_simplify9() {
73 ; CHECK-LINUX-LABEL: @test_simplify9(
74   %ret = call i32 @ffsll(i64 65536)
75   ret i32 %ret
76 ; CHECK-LINUX-NEXT: ret i32 17
77 }
78
79 define i32 @test_simplify10() {
80 ; CHECK-LINUX-LABEL: @test_simplify10(
81   %ret = call i32 @ffsll(i64 17179869184)
82   ret i32 %ret
83 ; CHECK-LINUX-NEXT: ret i32 35
84 }
85
86 define i32 @test_simplify11() {
87 ; CHECK-LINUX-LABEL: @test_simplify11(
88   %ret = call i32 @ffsll(i64 281474976710656)
89   ret i32 %ret
90 ; CHECK-LINUX-NEXT: ret i32 49
91 }
92
93 define i32 @test_simplify12() {
94 ; CHECK-LINUX-LABEL: @test_simplify12(
95   %ret = call i32 @ffsll(i64 1152921504606846976)
96   ret i32 %ret
97 ; CHECK-LINUX-NEXT: ret i32 61
98 }
99
100 ; Check ffs(x) -> x != 0 ? (i32)llvm.cttz(x) + 1 : 0.
101
102 define i32 @test_simplify13(i32 %x) {
103 ; CHECK-LABEL: @test_simplify13(
104   %ret = call i32 @ffs(i32 %x)
105 ; CHECK-NEXT: [[CTTZ:%[a-z0-9]+]] = call i32 @llvm.cttz.i32(i32 %x, i1 true)
106 ; CHECK-NEXT: [[INC:%[a-z0-9]+]] = add nuw nsw i32 [[CTTZ]], 1
107 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i32 %x, 0
108 ; CHECK-NEXT: [[RET:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[INC]], i32 0
109   ret i32 %ret
110 ; CHECK-NEXT: ret i32 [[RET]]
111 }
112
113 define i32 @test_simplify14(i32 %x) {
114 ; CHECK-LINUX-LABEL: @test_simplify14(
115   %ret = call i32 @ffsl(i32 %x)
116 ; CHECK-LINUX-NEXT: [[CTTZ:%[a-z0-9]+]] = call i32 @llvm.cttz.i32(i32 %x, i1 true)
117 ; CHECK-LINUX-NEXT: [[INC:%[a-z0-9]+]] = add nuw nsw i32 [[CTTZ]], 1
118 ; CHECK-LINUX-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i32 %x, 0
119 ; CHECK-LINUX-NEXT: [[RET:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[INC]], i32 0
120   ret i32 %ret
121 ; CHECK-LINUX-NEXT: ret i32 [[RET]]
122 }
123
124 define i32 @test_simplify15(i64 %x) {
125 ; CHECK-LINUX-LABEL: @test_simplify15(
126   %ret = call i32 @ffsll(i64 %x)
127 ; CHECK-LINUX-NEXT: [[CTTZ:%[a-z0-9]+]] = call i64 @llvm.cttz.i64(i64 %x, i1 true)
128 ; CHECK-LINUX-NEXT: [[INC:%[a-z0-9]+]] = add nuw nsw i64 [[CTTZ]], 1
129 ; CHECK-LINUX-NEXT: [[TRUNC:%[a-z0-9]+]] = trunc i64 [[INC]] to i32
130 ; CHECK-LINUX-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i64 %x, 0
131 ; CHECK-LINUX-NEXT: [[RET:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[TRUNC]], i32 0
132   ret i32 %ret
133 ; CHECK-LINUX-NEXT: ret i32 [[RET]]
134 }