xref: /llvm-project/clang/test/CodeGen/PowerPC/ppc-x86gprintrin.c (revision de7c0068329d78027df7b7184d72646c1ca9f2bd)
1 // REQUIRES: powerpc-registered-target
2 // RUN: %clang -S -emit-llvm -target powerpc64le-unknown-linux-gnu -mcpu=pwr7 -ffreestanding -DNO_WARN_X86_INTRINSICS %s \
3 // RUN:   -fno-discard-value-names -mllvm -disable-llvm-optzns -o - | llvm-cxxfilt -n | FileCheck %s
4 // RUN: %clang -S -emit-llvm -target powerpc64-unknown-linux-gnu -mcpu=pwr7 -ffreestanding -DNO_WARN_X86_INTRINSICS %s \
5 // RUN:   -fno-discard-value-names -mllvm -disable-llvm-optzns -o - | llvm-cxxfilt -n | FileCheck %s
6 
7 // RUN: %clang -S -emit-llvm -target powerpc64le-unknown-freebsd13.0 -mcpu=pwr7 -ffreestanding -DNO_WARN_X86_INTRINSICS %s \
8 // RUN:   -fno-discard-value-names -mllvm -disable-llvm-optzns -o - | llvm-cxxfilt -n | FileCheck %s
9 // RUN: %clang -S -emit-llvm -target powerpc64-unknown-freebsd13.0 -mcpu=pwr7 -ffreestanding -DNO_WARN_X86_INTRINSICS %s \
10 // RUN:   -fno-discard-value-names -mllvm -disable-llvm-optzns -o - | llvm-cxxfilt -n | FileCheck %s
11 
12 // RUN: %clang -S -emit-llvm -target powerpc64-ibm-aix -mcpu=pwr7 -ffreestanding -DNO_WARN_X86_INTRINSICS %s \
13 // RUN:   -fno-discard-value-names -mllvm -disable-llvm-optzns -o - | llvm-cxxfilt -n | FileCheck %s
14 
15 // RUN: %clang -x c++ -S -emit-llvm -target powerpc64le-unknown-linux-gnu -mcpu=pwr7 -ffreestanding -DNO_WARN_X86_INTRINSICS %s \
16 // RUN:   -fno-discard-value-names -mllvm -disable-llvm-optzns -fsyntax-only
17 
18 #include <x86gprintrin.h>
19 
20 unsigned short us;
21 unsigned ui;
22 unsigned long long ul;
23 
24 void __attribute__((noinline))
test_bmiintrin()25 test_bmiintrin() {
26   __tzcnt_u16(us);
27   __andn_u32(ui, ui);
28   _bextr_u32(ui, ui, ui);
29   __bextr_u32(ui, ui);
30   __blsi_u32(ui);
31   _blsi_u32(ui);
32   __blsmsk_u32(ui);
33   _blsmsk_u32(ui);
34   __blsr_u32(ui);
35   _blsr_u32(ui);
36   __tzcnt_u32(ui);
37   _tzcnt_u32(ui);
38   __andn_u64(ul, ul);
39   _bextr_u64(ul, ui, ui);
40   __bextr_u64(ul, ul);
41   __blsi_u64(ul);
42   _blsi_u64(ul);
43   __blsmsk_u64(ul);
44   _blsmsk_u64(ul);
45   __blsr_u64(ul);
46   _blsr_u64(ul);
47   __tzcnt_u64(ul);
48   _tzcnt_u64(ul);
49 }
50 
51 // CHECK-LABEL: @test_bmiintrin
52 
53 // CHECK-LABEL: define available_externally zeroext i16 @__tzcnt_u16(i16 noundef zeroext %{{[0-9a-zA-Z._]+}})
54 // CHECK: %[[CONV:[0-9a-zA-Z._]+]] = zext i16 %{{[0-9a-zA-Z._]+}} to i32
55 // CHECK: %[[CALL:[0-9a-zA-Z._]+]] = call i32 @llvm.cttz.i32(i32 %[[CONV]], i1 false)
56 // CHECK: trunc i32 %[[CALL]] to i16
57 
58 // CHECK-LABEL: define available_externally zeroext i32 @__andn_u32(i32 noundef zeroext %{{[0-9a-zA-Z._]+}}, i32 noundef zeroext %{{[0-9a-zA-Z._]+}})
59 // CHECK: %[[NEG:[0-9a-zA-Z._]+]] = xor i32 %{{[0-9a-zA-Z._]+}}, -1
60 // CHECK: and i32 %[[NEG]], %1
61 
62 // CHECK-LABEL: define available_externally zeroext i32 @_bextr_u32(i32 noundef zeroext %{{[0-9a-zA-Z._]+}}, i32 noundef zeroext %{{[0-9a-zA-Z._]+}}, i32 noundef zeroext %{{[0-9a-zA-Z._]+}})
63 // CHECK: %[[ADD:[0-9a-zA-Z._]+]] = add i32 %{{[0-9a-zA-Z._]+}}, %{{[0-9a-zA-Z._]+}}
64 // CHECK: %[[SUB:[0-9a-zA-Z._]+]] = sub i32 32, %[[ADD]]
65 // CHECK: %[[SHL:[0-9a-zA-Z._]+]] = shl i32 %{{[0-9a-zA-Z._]+}}, %[[SUB]]
66 // CHECK: %[[SUB]]1 = sub i32 32, %{{[0-9a-zA-Z._]+}}
67 // CHECK: lshr i32 %[[SHL]], %[[SUB]]1
68 
69 // CHECK-LABEL: define available_externally zeroext i32 @__bextr_u32(i32 noundef zeroext %{{[0-9a-zA-Z._]+}}, i32 noundef zeroext %{{[0-9a-zA-Z._]+}})
70 // CHECK: %[[AND:[0-9a-zA-Z._]+]] = and i32 %{{[0-9a-zA-Z._]+}}, 255
71 // CHECK: %[[SHR:[0-9a-zA-Z._]+]] = lshr i32 %{{[0-9a-zA-Z._]+}}, 8
72 // CHECK: and i32 %[[SHR]], 255
73 // CHECK: call zeroext i32 @_bextr_u32
74 
75 // CHECK-LABEL: define available_externally zeroext i32 @__blsi_u32(i32 noundef zeroext %{{[0-9a-zA-Z._]+}})
76 // CHECK: %[[SUB:[0-9a-zA-Z._]+]] = sub i32 0, %1
77 // CHECK: and i32 %0, %[[SUB]]
78 
79 // CHECK-LABEL: define available_externally zeroext i32 @_blsi_u32(i32 noundef zeroext %{{[0-9a-zA-Z._]+}})
80 // CHECK: call zeroext i32 @__blsi_u32
81 
82 // CHECK-LABEL: define available_externally zeroext i32 @__blsmsk_u32(i32 noundef zeroext %{{[0-9a-zA-Z._]+}})
83 // CHECK: %[[SUB:[0-9a-zA-Z._]+]] = sub i32 %{{[0-9a-zA-Z._]+}}, 1
84 // CHECK: xor i32 %{{[0-9a-zA-Z._]+}}, %[[SUB]]
85 
86 // CHECK-LABEL: define available_externally zeroext i32 @_blsmsk_u32(i32 noundef zeroext %{{[0-9a-zA-Z._]+}})
87 // CHECK: call zeroext i32 @__blsmsk_u32
88 
89 // CHECK-LABEL: define available_externally zeroext i32 @__blsr_u32(i32 noundef zeroext %{{[0-9a-zA-Z._]+}})
90 // CHECK: %[[SUB:[0-9a-zA-Z._]+]] = sub i32 %{{[0-9a-zA-Z._]+}}, 1
91 // CHECK: and i32 %{{[0-9a-zA-Z._]+}}, %[[SUB]]
92 
93 // CHECK-LABEL: define available_externally zeroext i32 @_blsr_u32(i32 noundef zeroext %{{[0-9a-zA-Z._]+}})
94 // CHECK: call zeroext i32 @__blsr_u32
95 
96 // CHECK-LABEL: define available_externally zeroext i32 @__tzcnt_u32(i32 noundef zeroext %{{[0-9a-zA-Z._]+}})
97 // CHECK: call i32 @llvm.cttz.i32(i32 %{{[0-9a-zA-Z._]+}}, i1 false)
98 
99 // CHECK-LABEL: define available_externally zeroext i32 @_tzcnt_u32(i32 noundef zeroext %{{[0-9a-zA-Z._]+}})
100 // CHECK: call i32 @llvm.cttz.i32(i32 %{{[0-9a-zA-Z._]+}}, i1 false)
101 
102 // CHECK-LABEL: define available_externally i64 @__andn_u64(i64 noundef %{{[0-9a-zA-Z._]+}}, i64 noundef %{{[0-9a-zA-Z._]+}})
103 // CHECK: %[[NEG:[0-9a-zA-Z._]+]] = xor i64 %{{[0-9a-zA-Z._]+}}, -1
104 // CHECK: and i64 %[[NEG]], %{{[0-9a-zA-Z._]+}}
105 
106 // CHECK-LABEL: define available_externally i64 @_bextr_u64(i64 noundef %{{[0-9a-zA-Z._]+}}, i32 noundef zeroext %{{[0-9a-zA-Z._]+}}, i32 noundef zeroext %{{[0-9a-zA-Z._]+}})
107 // CHECK: %[[ADD:[0-9a-zA-Z._]+]] = add i32 %{{[0-9a-zA-Z._]+}}, %{{[0-9a-zA-Z._]+}}
108 // CHECK: %[[SUB:[0-9a-zA-Z._]+]] = sub i32 64, %[[ADD]]
109 // CHECK: %[[EXT:[0-9a-zA-Z._]+]] = zext i32 %[[SUB]] to i64
110 // CHECK: %[[SHL:[0-9a-zA-Z._]+]] = shl i64 %{{[0-9a-zA-Z._]+}}, %[[EXT]]
111 // CHECK: %[[SUB1:[0-9a-zA-Z._]+]] = sub i32 64, %{{[0-9a-zA-Z._]+}}
112 // CHECK: %[[EXT2:[0-9a-zA-Z._]+]] = zext i32 %[[SUB1]] to i64
113 // CHECK: lshr i64 %[[SHL]], %[[EXT2]]
114 
115 // CHECK-LABEL: define available_externally i64 @__bextr_u64(i64 noundef %{{[0-9a-zA-Z._]+}}, i64 noundef %{{[0-9a-zA-Z._]+}})
116 // CHECK: %[[AND:[0-9a-zA-Z._]+]] = and i64 %{{[0-9a-zA-Z._]+}}, 255
117 // CHECK: trunc i64 %[[AND]] to i32
118 // CHECK: %[[AND1:[0-9a-zA-Z._]+]] = and i64 %{{[0-9a-zA-Z._]+}}, 65280
119 // CHECK: %[[SHR:[0-9a-zA-Z._]+]] = lshr i64 %[[AND1]], 8
120 // CHECK: trunc i64 %[[SHR]] to i32
121 // CHECK: call i64 @_bextr_u64
122 
123 // CHECK-LABEL: define available_externally i64 @__blsi_u64(i64 noundef %{{[0-9a-zA-Z._]+}})
124 // CHECK: %[[SUB:[0-9a-zA-Z._]+]] = sub i64 0, %{{[0-9a-zA-Z._]+}}
125 // CHECK: and i64 %0, %[[SUB]]
126 
127 // CHECK-LABEL: define available_externally i64 @_blsi_u64(i64 noundef %{{[0-9a-zA-Z._]+}})
128 // CHECK: call i64 @__blsi_u64
129 
130 // CHECK-LABEL: define available_externally i64 @__blsmsk_u64(i64 noundef %{{[0-9a-zA-Z._]+}})
131 // CHECK: %[[SUB:[0-9a-zA-Z._]+]] = sub i64 %{{[0-9a-zA-Z._]+}}, 1
132 // CHECK: xor i64 %0, %[[SUB]]
133 
134 // CHECK-LABEL: define available_externally i64 @_blsmsk_u64(i64 noundef %{{[0-9a-zA-Z._]+}})
135 // CHECK: call i64 @__blsmsk_u64
136 
137 // CHECK-LABEL: define available_externally i64 @__blsr_u64(i64 noundef %{{[0-9a-zA-Z._]+}})
138 // CHECK: %[[SUB:[0-9a-zA-Z._]+]] = sub i64 %{{[0-9a-zA-Z._]+}}, 1
139 // CHECK: and i64 %{{[0-9a-zA-Z._]+}}, %[[SUB]]
140 
141 // CHECK-LABEL: define available_externally i64 @_blsr_u64(i64 noundef %{{[0-9a-zA-Z._]+}})
142 // CHECK: call i64 @__blsr_u64
143 
144 // CHECK-LABEL: define available_externally i64 @__tzcnt_u64(i64 noundef %{{[0-9a-zA-Z._]+}})
145 // CHECK: %[[CALL:[0-9a-zA-Z._]+]] = call i64 @llvm.cttz.i64(i64 %{{[0-9a-zA-Z._]+}}, i1 false)
146 // CHECK: %[[CAST:[0-9a-zA-Z._]+]] = trunc i64 %[[CALL]] to i32
147 // CHECK: sext i32 %[[CAST]] to i64
148 
149 // CHECK-LABEL: define available_externally i64 @_tzcnt_u64(i64 noundef %{{[0-9a-zA-Z._]+}})
150 // CHECK: %[[CALL:[0-9a-zA-Z._]+]] = call i64 @llvm.cttz.i64(i64 %{{[0-9a-zA-Z._]+}}, i1 false)
151 // CHECK: %[[CAST:[0-9a-zA-Z._]+]] = trunc i64 %[[CALL]] to i32
152 // CHECK: sext i32 %[[CAST]] to i64
153 
154 void __attribute__((noinline))
test_bmi2intrin()155 test_bmi2intrin() {
156   _bzhi_u32(ui, ui);
157   _mulx_u32(ui, ui, &ui);
158   _bzhi_u64(ul, ul);
159   _mulx_u64(ul, ul, &ul);
160   _pdep_u64(ul, ul);
161   _pext_u64(ul, ul);
162   _pdep_u32(ui, ui);
163   _pext_u32(ui, ui);
164 }
165 
166 // CHECK-LABEL: @test_bmi2intrin
167 
168 // CHECK-LABEL: define available_externally zeroext i32 @_bzhi_u32(i32 noundef zeroext %{{[0-9a-zA-Z._]+}}, i32 noundef zeroext %{{[0-9a-zA-Z._]+}})
169 // CHECK: %[[SUB:[0-9a-zA-Z._]+]] = sub i32 32, %{{[0-9a-zA-Z._]+}}
170 // CHECK: %[[SHL:[0-9a-zA-Z._]+]] = shl i32 %{{[0-9a-zA-Z._]+}}, %[[SUB]]
171 // CHECK: %[[SUB1:[0-9a-zA-Z._]+]] = sub i32 32, %{{[0-9a-zA-Z._]+}}
172 // CHECK: lshr i32 %[[SHL]], %[[SUB1]]
173 
174 // CHECK-LABEL: define available_externally zeroext i32 @_mulx_u32(i32 noundef zeroext %{{[0-9a-zA-Z._]+}}, i32 noundef zeroext %{{[0-9a-zA-Z._]+}}, ptr noundef %{{[0-9a-zA-Z._]+}})
175 // CHECK: zext i32 %{{[0-9a-zA-Z._]+}} to i64
176 // CHECK: zext i32 %{{[0-9a-zA-Z._]+}} to i64
177 // CHECK: %[[SHR:[0-9a-zA-Z._]+]] = lshr i64 %{{[0-9a-zA-Z._]+}}, 32
178 // CHECK: trunc i64 %[[SHR]] to i32
179 // CHECK: trunc i64 %{{[0-9a-zA-Z._]+}} to i32
180 
181 // CHECK-LABEL: define available_externally i64 @_bzhi_u64(i64 noundef %{{[0-9a-zA-Z._]+}}, i64 noundef %{{[0-9a-zA-Z._]+}})
182 // CHECK: %[[SUB:[0-9a-zA-Z._]+]] = sub i64 64, %{{[0-9a-zA-Z._]+}}
183 // CHECK: %[[SHL:[0-9a-zA-Z._]+]] = shl i64 %{{[0-9a-zA-Z._]+}}, %[[SUB]]
184 // CHECK: %[[SUB1:[0-9a-zA-Z._]+]] = sub i64 64, %{{[0-9a-zA-Z._]+}}
185 // CHECK: lshr i64 %[[SHL]], %[[SUB1]]
186 
187 // CHECK-LABEL: define available_externally i64 @_mulx_u64(i64 noundef %{{[0-9a-zA-Z._]+}}, i64 noundef %{{[0-9a-zA-Z._]+}}, ptr noundef %{{[0-9a-zA-Z._]+}})
188 // CHECK: zext i64 %{{[0-9a-zA-Z._]+}} to i128
189 // CHECK: zext i64 %{{[0-9a-zA-Z._]+}} to i128
190 // CHECK: %[[SHR:[0-9a-zA-Z._]+]] = lshr i128 %{{[0-9a-zA-Z._]+}}, 64
191 // CHECK: trunc i128 %[[SHR]] to i64
192 // CHECK: trunc i128 %{{[0-9a-zA-Z._]+}} to i64
193 
194 // CHECK-LABEL: define available_externally i64 @_pdep_u64(i64 noundef %{{[0-9a-zA-Z._]+}}, i64 noundef %{{[0-9a-zA-Z._]+}})
195 // CHECK: %[[CALL:[0-9a-zA-Z._]+]] = call i64 @llvm.ctpop.i64(i64 %{{[0-9a-zA-Z._]+}})
196 // CHECK: %[[CAST:[0-9a-zA-Z._]+]] = trunc i64 %[[CALL]] to i32
197 // CHECK: %[[SUB:[0-9a-zA-Z._]+]] = sub nsw i32 64, %[[CAST]]
198 // CHECK: sext i32 %[[SUB]] to i64
199 // CHECK: %[[CALL2:[0-9a-zA-Z._]+]] = call i64 @llvm.ctlz.i64(i64 %{{[0-9a-zA-Z._]+}}, i1 false)
200 // CHECK: %[[CAST2:[0-9a-zA-Z._]+]] = trunc i64 %[[CALL2]] to i32
201 // CHECK: sext i32 %[[CAST2]] to i64
202 // CHECK: %[[SUB2:[0-9a-zA-Z._]+]] = sub i64 %{{[0-9a-zA-Z._]+}}, %{{[0-9a-zA-Z._]+}}
203 // CHECK: shl i64 %{{[0-9a-zA-Z._]+}}, %[[SUB2]]
204 // CHECK: %[[SHR:[0-9a-zA-Z._]+]] = lshr i64 -9223372036854775808, %{{[0-9a-zA-Z._]+}}
205 // CHECK: xor i64 %{{[0-9a-zA-Z._]+}}, %[[SHR]]
206 // CHECK: %[[SHR2:[0-9a-zA-Z._]+]] = lshr i64 -9223372036854775808, %{{[0-9a-zA-Z._]+}}
207 // CHECK: %[[AND:[0-9a-zA-Z._]+]] = and i64 %{{[0-9a-zA-Z._]+}}, %[[SHR2]]
208 // CHECK: or i64 %{{[0-9a-zA-Z._]+}}, %[[AND]]
209 // CHECK: add i64 %{{[0-9a-zA-Z._]+}}, 1
210 
211 // CHECK-LABEL: define available_externally i64 @_pext_u64(i64 noundef %{{[0-9a-zA-Z._]+}}, i64 noundef %{{[0-9a-zA-Z._]+}})
212 // CHECK: %[[CALL:[0-9a-zA-Z._]+]] = call i1 @llvm.is.constant.i64(i64 %{{[0-9a-zA-Z._]+}})
213 // CHECK: br i1 %[[CALL]], label %[[TRUECOND:[0-9a-zA-Z._]+]], label %[[FALSECOND:[0-9a-zA-Z._]+]]
214 // CHECK: [[TRUECOND]]:
215 // CHECK: %[[CALL2:[0-9a-zA-Z._]+]] = call i64 @llvm.ctpop.i64(i64 %{{[0-9a-zA-Z._]+}})
216 // CHECK: call i64 @llvm.ctlz.i64(i64 %{{[0-9a-zA-Z._]+}}, i1 false)
217 // CHECK: %[[SHL:[0-9a-zA-Z._]+]] = shl i64 %{{[0-9a-zA-Z._]+}}, 8
218 // CHECK: or i64 %[[SHL]], %{{[0-9a-zA-Z._]+}}
219 // CHECK: %[[SHR:[0-9a-zA-Z._]+]] = lshr i64 -9223372036854775808, %{{[0-9a-zA-Z._]+}}
220 // CHECK: xor i64 %{{[0-9a-zA-Z._]+}}, %[[SHR]]
221 // CHECK: add nsw i64 %{{[0-9a-zA-Z._]+}}, 1
222 // CHECK: call i64 @llvm.ppc.bpermd
223 // CHECK: [[FALSECOND]]:
224 // CHECK: call i64 @llvm.ctpop.i64(i64 %{{[0-9a-zA-Z._]+}})
225 // CHECK: call i64 @llvm.ctlz.i64(i64 %{{[0-9a-zA-Z._]+}}, i1 false)
226 // CHECK: %[[SHR2:[0-9a-zA-Z._]+]] = lshr i64 -9223372036854775808, %{{[0-9a-zA-Z._]+}}
227 // CHECK: %[[AND:[0-9a-zA-Z._]+]] = and i64 %{{[0-9a-zA-Z._]+}}, %[[SHR2]]
228 // CHECK: %[[SUB:[0-9a-zA-Z._]+]] = sub i64 %{{[0-9a-zA-Z._]+}}, %{{[0-9a-zA-Z._]+}}
229 // CHECK: lshr i64 %[[AND]], %[[SUB]]
230 // CHECK: %[[SHR3:[0-9a-zA-Z._]+]] = lshr i64 -9223372036854775808, %{{[0-9a-zA-Z._]+}}
231 // CHECK: xor i64 %{{[0-9a-zA-Z._]+}}, %[[SHR3]]
232 // CHECK: or i64 %{{[0-9a-zA-Z._]+}}, %{{[0-9a-zA-Z._]+}}
233 // CHECK: add i64 %{{[0-9a-zA-Z._]+}}, 1
234 
235 // CHECK-LABEL: define available_externally zeroext i32 @_pdep_u32(i32 noundef zeroext %{{[0-9a-zA-Z._]+}}, i32 noundef zeroext %{{[0-9a-zA-Z._]+}})
236 // CHECK: %[[CONV:[0-9a-zA-Z._]+]] = zext i32 %{{[0-9a-zA-Z._]+}} to i64
237 // CHECK: %[[CONV1:[0-9a-zA-Z._]+]] = zext i32 %{{[0-9a-zA-Z._]+}} to i64
238 // CHECK: %[[CALL:[0-9a-zA-Z._]+]] = call i64 @_pdep_u64(i64 noundef %[[CONV]], i64 noundef %[[CONV1]])
239 // CHECK: trunc i64 %[[CALL]] to i32
240 
241 // CHECK-LABEL: define available_externally zeroext i32 @_pext_u32(i32 noundef zeroext %{{[0-9a-zA-Z._]+}}, i32 noundef zeroext %{{[0-9a-zA-Z._]+}})
242 // CHECK: %[[CONV:[0-9a-zA-Z._]+]] = zext i32 %{{[0-9a-zA-Z._]+}} to i64
243 // CHECK: %[[CONV1:[0-9a-zA-Z._]+]] = zext i32 %{{[0-9a-zA-Z._]+}} to i64
244 // CHECK: %[[CALL:[0-9a-zA-Z._]+]] = call i64 @_pext_u64(i64 noundef %[[CONV]], i64 noundef %[[CONV1]])
245 // CHECK: trunc i64 %[[CALL]] to i32
246