[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / fold-csel-cttz-and.ll
blobe2ea83d54633e6f2f76fccbc02a47bb34f468cef
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=aarch64 < %s | FileCheck %s
4 ;; Check the transformation
5 ;; CSEL 0, cttz, cc -> AND cttz numbits-1
6 ;; for cttz in the case of i32 and i64 respectively
8 ;; Cases for which the optimzation takes place
9 define i32 @cttzi32(i32 %x) {
10 ; CHECK-LABEL: cttzi32:
11 ; CHECK:       // %bb.0: // %entry
12 ; CHECK-NEXT:    rbit w8, w0
13 ; CHECK-NEXT:    clz w8, w8
14 ; CHECK-NEXT:    and w0, w8, #0x1f
15 ; CHECK-NEXT:    ret
16 entry:
17   %0 = call i32 @llvm.cttz.i32(i32 %x, i1 true)
18   %1 = icmp eq i32 %x, 0
19   %2 = select i1 %1, i32 0, i32 %0
20   ret i32 %2
23 define i64 @cttzi64(i64 %x) {
24 ; CHECK-LABEL: cttzi64:
25 ; CHECK:       // %bb.0: // %entry
26 ; CHECK-NEXT:    rbit x8, x0
27 ; CHECK-NEXT:    clz x8, x8
28 ; CHECK-NEXT:    and x0, x8, #0x3f
29 ; CHECK-NEXT:    ret
30 entry:
31   %0 = call i64 @llvm.cttz.i64(i64 %x, i1 true)
32   %1 = icmp eq i64 %x, 0
33   %2 = select i1 %1, i64 0, i64 %0
34   ret i64 %2
37 define i32 @cttzi32ne(i32 %x) {
38 ; CHECK-LABEL: cttzi32ne:
39 ; CHECK:       // %bb.0: // %entry
40 ; CHECK-NEXT:    rbit w8, w0
41 ; CHECK-NEXT:    clz w8, w8
42 ; CHECK-NEXT:    and w0, w8, #0x1f
43 ; CHECK-NEXT:    ret
44 entry:
45   %0 = call i32 @llvm.cttz.i32(i32 %x, i1 true)
46   %1 = icmp ne i32 %x, 0
47   %2 = select i1 %1, i32 %0, i32 0
48   ret i32 %2
51 define i64 @cttzi64ne(i64 %x) {
52 ; CHECK-LABEL: cttzi64ne:
53 ; CHECK:       // %bb.0: // %entry
54 ; CHECK-NEXT:    rbit x8, x0
55 ; CHECK-NEXT:    clz x8, x8
56 ; CHECK-NEXT:    and x0, x8, #0x3f
57 ; CHECK-NEXT:    ret
58 entry:
59   %0 = call i64 @llvm.cttz.i64(i64 %x, i1 true)
60   %1 = icmp ne i64 %x, 0
61   %2 = select i1 %1, i64 %0, i64 0
62   ret i64 %2
65 define i32 @cttztrunc(i64 %x) {
66 ; CHECK-LABEL: cttztrunc:
67 ; CHECK:       // %bb.0: // %entry
68 ; CHECK-NEXT:    rbit x8, x0
69 ; CHECK-NEXT:    clz x8, x8
70 ; CHECK-NEXT:    and w0, w8, #0x3f
71 ; CHECK-NEXT:    ret
72 entry:
73   %0 = call i64 @llvm.cttz.i64(i64 %x, i1 true)
74   %1 = icmp eq i64 %x, 0
75   %2 = select i1 %1, i64 0, i64 %0
76   %3 = trunc i64 %2 to i32
77   ret i32 %3
80 ;; Cases for which the optimization does not take place
81 define i32 @cttzne(i32 %x) {
82 ; CHECK-LABEL: cttzne:
83 ; CHECK:       // %bb.0: // %entry
84 ; CHECK-NEXT:    rbit w8, w0
85 ; CHECK-NEXT:    cmp w0, #0
86 ; CHECK-NEXT:    clz w8, w8
87 ; CHECK-NEXT:    csel w0, wzr, w8, ne
88 ; CHECK-NEXT:    ret
89 entry:
90   %0 = call i32 @llvm.cttz.i32(i32 %x, i1 true)
91   %1 = icmp ne i32 %x, 0
92   %2 = select i1 %1, i32 0, i32 %0
93   ret i32 %2
96 define i32 @cttzxnot0(i32 %x) {
97 ; CHECK-LABEL: cttzxnot0:
98 ; CHECK:       // %bb.0: // %entry
99 ; CHECK-NEXT:    rbit w8, w0
100 ; CHECK-NEXT:    cmp w0, #10
101 ; CHECK-NEXT:    clz w8, w8
102 ; CHECK-NEXT:    csel w0, wzr, w8, eq
103 ; CHECK-NEXT:    ret
104 entry:
105   %0 = call i32 @llvm.cttz.i32(i32 %x, i1 true)
106   %1 = icmp eq i32 %x, 10
107   %2 = select i1 %1, i32 0, i32 %0
108   ret i32 %2
111 define i32 @cttzlhsnot0(i32 %x) {
112 ; CHECK-LABEL: cttzlhsnot0:
113 ; CHECK:       // %bb.0: // %entry
114 ; CHECK-NEXT:    rbit w9, w0
115 ; CHECK-NEXT:    mov w8, #10 // =0xa
116 ; CHECK-NEXT:    cmp w0, #0
117 ; CHECK-NEXT:    clz w9, w9
118 ; CHECK-NEXT:    csel w0, w8, w9, eq
119 ; CHECK-NEXT:    ret
120 entry:
121   %0 = call i32 @llvm.cttz.i32(i32 %x, i1 true)
122   %1 = icmp eq i32 %x, 0
123   %2 = select i1 %1, i32 10, i32 %0
124   ret i32 %2
127 define i32 @notcttz(i32 %x) {
128 ; CHECK-LABEL: notcttz:
129 ; CHECK:       // %bb.0: // %entry
130 ; CHECK-NEXT:    clz w8, w0
131 ; CHECK-NEXT:    cmp w0, #0
132 ; CHECK-NEXT:    csel w0, wzr, w8, eq
133 ; CHECK-NEXT:    ret
134 entry:
135   %0 = call i32 @llvm.ctlz.i32(i32 %x, i1 true)
136   %1 = icmp eq i32 %x, 0
137   %2 = select i1 %1, i32 0, i32 %0
138   ret i32 %2
141 define i32 @cttzlhsnotx(i32 %x, i32 %y) {
142 ; CHECK-LABEL: cttzlhsnotx:
143 ; CHECK:       // %bb.0: // %entry
144 ; CHECK-NEXT:    rbit w8, w0
145 ; CHECK-NEXT:    cmp w1, #0
146 ; CHECK-NEXT:    clz w8, w8
147 ; CHECK-NEXT:    csel w0, wzr, w8, eq
148 ; CHECK-NEXT:    ret
149 entry:
150   %0 = call i32 @llvm.cttz.i32(i32 %x, i1 true)
151   %1 = icmp eq i32 %y, 0
152   %2 = select i1 %1, i32 0, i32 %0
153   ret i32 %2
156 declare i32 @llvm.cttz.i32(i32, i1)
158 declare i64 @llvm.cttz.i64(i64, i1)
160 declare i32 @llvm.ctlz.i32(i32, i1)