211 lines · c
1// RUN: %clang_cc1 -x c -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-unknown-linux -target-feature +avx512dq -fclangir -emit-cir -o %t.cir -Wall -Werror
2// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
3// RUN: %clang_cc1 -x c -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-unknown-linux -target-feature +avx512dq -fclangir -emit-llvm -o %t.ll -Wall -Werror
4// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
5
6// RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-unknown-linux -target-feature +avx512dq -fno-signed-char -fclangir -emit-cir -o %t.cir -Wall -Werror
7// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
8// RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-unknown-linux -target-feature +avx512dq -fno-signed-char -fclangir -emit-llvm -o %t.ll -Wall -Werror
9// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
10
11// RUN: %clang_cc1 -x c -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-unknown-linux -target-feature +avx512dq -emit-llvm -o - -Wall -Werror | FileCheck %s -check-prefix=OGCG
12// RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-unknown-linux -target-feature +avx512dq -emit-llvm -o - -Wall -Werror | FileCheck %s -check-prefix=OGCG
13
14#include <immintrin.h>
15
16__mmask8 test_kadd_mask8(__mmask8 A, __mmask8 B) {
17 // CIR-LABEL: _kadd_mask8
18 // CIR: cir.cast bitcast {{.*}} : !u8i -> !cir.vector<8 x !cir.int<u, 1>>
19 // CIR: cir.cast bitcast {{.*}} : !u8i -> !cir.vector<8 x !cir.int<u, 1>>
20 // CIR: cir.call_llvm_intrinsic "x86.avx512.kadd.b"
21 // CIR: cir.cast bitcast {{.*}} : !cir.vector<8 x !cir.int<u, 1>> -> !u8i
22
23 // LLVM-LABEL: _kadd_mask8
24 // LLVM: [[L:%.*]] = bitcast i8 %{{.*}} to <8 x i1>
25 // LLVM: [[R:%.*]] = bitcast i8 %{{.*}} to <8 x i1>
26 // LLVM: [[RES:%.*]] = call <8 x i1> @llvm.x86.avx512.kadd.b(<8 x i1> [[L]], <8 x i1> [[R]])
27 // LLVM: bitcast <8 x i1> [[RES]] to i8
28
29 // OGCG-LABEL: _kadd_mask8
30 // OGCG: bitcast i8 %{{.*}} to <8 x i1>
31 // OGCG: bitcast i8 %{{.*}} to <8 x i1>
32 // OGCG: call <8 x i1> @llvm.x86.avx512.kadd.b
33 // OGCG: bitcast <8 x i1> {{.*}} to i8
34 return _kadd_mask8(A, B);
35}
36
37__mmask16 test_kadd_mask16(__mmask16 A, __mmask16 B) {
38 // CIR-LABEL: _kadd_mask16
39 // CIR: cir.cast bitcast {{.*}} : !u16i -> !cir.vector<16 x !cir.int<u, 1>>
40 // CIR: cir.cast bitcast {{.*}} : !u16i -> !cir.vector<16 x !cir.int<u, 1>>
41 // CIR: cir.call_llvm_intrinsic "x86.avx512.kadd.w"
42 // CIR: cir.cast bitcast {{.*}} : !cir.vector<16 x !cir.int<u, 1>> -> !u16i
43
44 // LLVM-LABEL: _kadd_mask16
45 // LLVM: [[L:%.*]] = bitcast i16 %{{.*}} to <16 x i1>
46 // LLVM: [[R:%.*]] = bitcast i16 %{{.*}} to <16 x i1>
47 // LLVM: [[RES:%.*]] = call <16 x i1> @llvm.x86.avx512.kadd.w(<16 x i1> [[L]], <16 x i1> [[R]])
48 // LLVM: bitcast <16 x i1> [[RES]] to i16
49
50 // OGCG-LABEL: _kadd_mask16
51 // OGCG: bitcast i16 %{{.*}} to <16 x i1>
52 // OGCG: bitcast i16 %{{.*}} to <16 x i1>
53 // OGCG: call <16 x i1> @llvm.x86.avx512.kadd.w
54 // OGCG: bitcast <16 x i1> {{.*}} to i16
55 return _kadd_mask16(A, B);
56}
57
58__mmask8 test_kand_mask8(__mmask8 A, __mmask8 B) {
59 // CIR-LABEL: _kand_mask8
60 // CIR: cir.cast bitcast {{.*}} : !u8i -> !cir.vector<8 x !cir.int<u, 1>>
61 // CIR: cir.cast bitcast {{.*}} : !u8i -> !cir.vector<8 x !cir.int<u, 1>>
62 // CIR: cir.binop(and, {{.*}}, {{.*}}) : !cir.vector<8 x !cir.int<u, 1>>
63 // CIR: cir.cast bitcast {{.*}} : !cir.vector<8 x !cir.int<u, 1>> -> !u8i
64
65 // LLVM-LABEL: _kand_mask8
66 // LLVM: [[L:%.*]] = bitcast i8 %{{.*}} to <8 x i1>
67 // LLVM: [[R:%.*]] = bitcast i8 %{{.*}} to <8 x i1>
68 // LLVM: [[RES:%.*]] = and <8 x i1> [[L]], [[R]]
69 // LLVM: bitcast <8 x i1> [[RES]] to i8
70
71 // OGCG-LABEL: _kand_mask8
72 // OGCG: bitcast i8 %{{.*}} to <8 x i1>
73 // OGCG: bitcast i8 %{{.*}} to <8 x i1>
74 // OGCG: and <8 x i1>
75 // OGCG: bitcast <8 x i1> {{.*}} to i8
76 return _kand_mask8(A, B);
77}
78
79
80__mmask8 test_kandn_mask8(__mmask8 A, __mmask8 B) {
81 // CIR-LABEL: _kandn_mask8
82 // CIR: cir.cast bitcast {{.*}} : !u8i -> !cir.vector<8 x !cir.int<u, 1>>
83 // CIR: cir.cast bitcast {{.*}} : !u8i -> !cir.vector<8 x !cir.int<u, 1>>
84 // CIR: cir.unary(not, {{.*}}) : !cir.vector<8 x !cir.int<u, 1>>
85 // CIR: cir.binop(and, {{.*}}, {{.*}}) : !cir.vector<8 x !cir.int<u, 1>>
86 // CIR: cir.cast bitcast {{.*}} : !cir.vector<8 x !cir.int<u, 1>> -> !u8i
87
88 // LLVM-LABEL: _kandn_mask8
89 // LLVM: [[L:%.*]] = bitcast i8 %{{.*}} to <8 x i1>
90 // LLVM: [[R:%.*]] = bitcast i8 %{{.*}} to <8 x i1>
91 // LLVM: xor <8 x i1> [[L]], splat (i1 true)
92 // LLVM: and <8 x i1>
93 // LLVM: bitcast <8 x i1> {{.*}} to i8
94
95 // OGCG-LABEL: _kandn_mask8
96 // OGCG: bitcast i8 %{{.*}} to <8 x i1>
97 // OGCG: bitcast i8 %{{.*}} to <8 x i1>
98 // OGCG: xor <8 x i1>
99 // OGCG: and <8 x i1>
100 // OGCG: bitcast <8 x i1> {{.*}} to i8
101
102 return _kandn_mask8(A, B);
103}
104
105__mmask8 test_kor_mask8(__mmask8 A, __mmask8 B) {
106 // CIR-LABEL: _kor_mask8
107 // CIR: cir.cast bitcast {{.*}} : !u8i -> !cir.vector<8 x !cir.int<u, 1>>
108 // CIR: cir.cast bitcast {{.*}} : !u8i -> !cir.vector<8 x !cir.int<u, 1>>
109 // CIR: cir.binop(or, {{.*}}, {{.*}}) : !cir.vector<8 x !cir.int<u, 1>>
110 // CIR: cir.cast bitcast {{.*}} : !cir.vector<8 x !cir.int<u, 1>> -> !u8i
111
112 // LLVM-LABEL: _kor_mask8
113 // LLVM: [[L:%.*]] = bitcast i8 %{{.*}} to <8 x i1>
114 // LLVM: [[R:%.*]] = bitcast i8 %{{.*}} to <8 x i1>
115 // LLVM: or <8 x i1> [[L]], [[R]]
116 // LLVM: bitcast <8 x i1> {{.*}} to i8
117
118 // OGCG-LABEL: _kor_mask8
119 // OGCG: bitcast i8 %{{.*}} to <8 x i1>
120 // OGCG: bitcast i8 %{{.*}} to <8 x i1>
121 // OGCG: or <8 x i1>
122 // OGCG: bitcast <8 x i1> {{.*}} to i8
123 return _kor_mask8(A, B);
124}
125
126__mmask8 test_kxor_mask8(__mmask8 A, __mmask8 B) {
127 // CIR-LABEL: _kxor_mask8
128 // CIR: cir.cast bitcast {{.*}} : !u8i -> !cir.vector<8 x !cir.int<u, 1>>
129 // CIR: cir.cast bitcast {{.*}} : !u8i -> !cir.vector<8 x !cir.int<u, 1>>
130 // CIR: cir.binop(xor, {{.*}}, {{.*}}) : !cir.vector<8 x !cir.int<u, 1>>
131 // CIR: cir.cast bitcast {{.*}} : !cir.vector<8 x !cir.int<u, 1>> -> !u8i
132
133 // LLVM-LABEL: _kxor_mask8
134 // LLVM: [[L:%.*]] = bitcast i8 %{{.*}} to <8 x i1>
135 // LLVM: [[R:%.*]] = bitcast i8 %{{.*}} to <8 x i1>
136 // LLVM: xor <8 x i1> [[L]], [[R]]
137 // LLVM: bitcast <8 x i1> {{.*}} to i8
138
139 // OGCG-LABEL: _kxor_mask8
140 // OGCG: bitcast i8 %{{.*}} to <8 x i1>
141 // OGCG: bitcast i8 %{{.*}} to <8 x i1>
142 // OGCG: xor <8 x i1>
143 // OGCG: bitcast <8 x i1> {{.*}} to i8
144 return _kxor_mask8(A, B);
145}
146
147__mmask8 test_kxnor_mask8(__mmask8 A, __mmask8 B) {
148 // CIR-LABEL: _kxnor_mask8
149 // CIR: cir.cast bitcast {{.*}} : !u8i -> !cir.vector<8 x !cir.int<u, 1>>
150 // CIR: cir.cast bitcast {{.*}} : !u8i -> !cir.vector<8 x !cir.int<u, 1>>
151 // CIR: cir.unary(not, {{.*}}) : !cir.vector<8 x !cir.int<u, 1>>
152 // CIR: cir.binop(xor, {{.*}}, {{.*}}) : !cir.vector<8 x !cir.int<u, 1>>
153 // CIR: cir.cast bitcast {{.*}} : !cir.vector<8 x !cir.int<u, 1>> -> !u8i
154
155 // LLVM-LABEL: _kxnor_mask8
156 // LLVM: [[L:%.*]] = bitcast i8 %{{.*}} to <8 x i1>
157 // LLVM: [[R:%.*]] = bitcast i8 %{{.*}} to <8 x i1>
158 // LLVM: [[NOT:%.*]] = xor <8 x i1> [[L]], splat (i1 true)
159 // LLVM: [[RES:%.*]] = xor <8 x i1> [[NOT]], [[R]]
160 // LLVM: bitcast <8 x i1> [[RES]] to i8
161
162 // OGCG-LABEL: _kxnor_mask8
163 // OGCG: bitcast i8 %{{.*}} to <8 x i1>
164 // OGCG: bitcast i8 %{{.*}} to <8 x i1>
165 // OGCG: xor <8 x i1>
166 // OGCG: xor <8 x i1>
167 // OGCG: bitcast <8 x i1> {{.*}} to i8
168 return _kxnor_mask8(A, B);
169}
170
171
172__mmask8 test_knot_mask8(__mmask8 A) {
173 // CIR-LABEL: _knot_mask8
174 // CIR: cir.cast bitcast {{.*}} : !u8i -> !cir.vector<8 x !cir.int<u, 1>>
175 // CIR: cir.unary(not, {{.*}}) : !cir.vector<8 x !cir.int<u, 1>>
176 // CIR: cir.cast bitcast {{.*}} : !cir.vector<8 x !cir.int<u, 1>> -> !u8i
177
178 // LLVM-LABEL: _knot_mask8
179 // LLVM: [[L:%.*]] = bitcast i8 %{{.*}} to <8 x i1>
180 // LLVM: xor <8 x i1> [[L]], {{.*}}
181 // LLVM: bitcast <8 x i1> {{.*}} to i8
182
183 // OGCG-LABEL: _knot_mask8
184 // OGCG: bitcast i8 %{{.*}} to <8 x i1>
185 // OGCG: xor <8 x i1>
186 // OGCG: bitcast <8 x i1> {{.*}} to i8
187 return _knot_mask8(A);
188}
189
190// Multiple user-level mask helpers inline to this same kmov builtin.
191// CIR does not implement any special lowering for those helpers.
192//
193// Therefore, testing the builtin (__builtin_ia32_kmov*) directly is
194// sufficient to cover the CIR lowering behavior. Testing each helper
195// individually would add no new CIR paths.
196
197__mmask8 test_kmov_b(__mmask8 A) {
198 // CIR-LABEL: test_kmov_b
199 // CIR: cir.cast bitcast {{.*}} : !u8i -> !cir.vector<8 x !cir.int<u, 1>>
200 // CIR: cir.cast bitcast {{.*}} : !cir.vector<8 x !cir.int<u, 1>> -> !u8i
201
202 // LLVM-LABEL: test_kmov_b
203 // LLVM: bitcast i8 %{{.*}} to <8 x i1>
204 // LLVM: bitcast <8 x i1> {{.*}} to i8
205
206 // OGCG-LABEL: test_kmov_b
207 // OGCG: bitcast i8 %{{.*}} to <8 x i1>
208 // OGCG: bitcast <8 x i1> {{.*}} to i8
209 return __builtin_ia32_kmovb(A);
210}
211