Skip to content

Commit c4ff1f3

Browse files
authored
[CIR] Implement builtin extractf (llvm#170427)
Implement builtin extractf, tests are from clang/test/CodeGen/X86/avx512f-builtins.c. Added a new type constraint "element or vector of element" since LLVMIR also has said constraint. The new getBoolMaskValue is because the existing SelectOp already accepts only a boolean condition; it'd make more sense for it to accept a vector of boolean instead of a vector of i32.
1 parent 835aa48 commit c4ff1f3

File tree

6 files changed

+325
-11
lines changed

6 files changed

+325
-11
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,28 @@ def CIR_ConstantOp : CIR_Op<"const", [
425425
return boolAttr.getValue();
426426
llvm_unreachable("Expected a BoolAttr in ConstantOp");
427427
}
428+
429+
bool isAllOnesValue() {
430+
// Check for -1 integers
431+
if (auto intAttr = getValueAttr<cir::IntAttr>())
432+
return intAttr.getValue().isAllOnes();
433+
434+
// Check for FP which are bitcasted from -1 integers
435+
if (auto fpAttr = getValueAttr<cir::FPAttr>())
436+
return fpAttr.getValue().bitcastToAPInt().isAllOnes();
437+
438+
// Check for constant vectors with splat values
439+
if (cir::VectorType v = mlir::dyn_cast<cir::VectorType>(getType()))
440+
if (auto vecAttr = getValueAttr<mlir::DenseElementsAttr>())
441+
if (vecAttr.isSplat()) {
442+
auto splatAttr = vecAttr.getSplatValue<mlir::Attribute>();
443+
if (auto splatInt = mlir::dyn_cast<cir::IntAttr>(splatAttr)) {
444+
return splatInt.getValue().isAllOnes();
445+
}
446+
}
447+
448+
return false;
449+
}
428450
}];
429451

430452
let hasFolder = 1;
@@ -1960,10 +1982,16 @@ def CIR_SelectOp : CIR_Op<"select", [
19601982
let summary = "Yield one of two values based on a boolean value";
19611983
let description = [{
19621984
The `cir.select` operation takes three operands. The first operand
1963-
`condition` is a boolean value of type `!cir.bool`. The second and the third
1964-
operand can be of any CIR types, but their types must be the same. If the
1965-
first operand is `true`, the operation yields its second operand. Otherwise,
1966-
the operation yields its third operand.
1985+
`condition` is either a boolean value of type `!cir.bool` or a boolean
1986+
vector of type `!cir.bool`. The second and the third operand can be of
1987+
any CIR types, but their types must be the same. If the first operand
1988+
is `true`, the operation yields its second operand. Otherwise, the
1989+
operation yields its third operand.
1990+
1991+
In the case where the first operand is a boolean vector, then the second
1992+
and third operand needs to also be of some vectors of the same type to
1993+
each other and that the number of elements of all three operands needs to
1994+
be the same as well.
19671995

19681996
Example:
19691997

@@ -1975,8 +2003,12 @@ def CIR_SelectOp : CIR_Op<"select", [
19752003
```
19762004
}];
19772005

1978-
let arguments = (ins CIR_BoolType:$condition, CIR_AnyType:$true_value,
1979-
CIR_AnyType:$false_value);
2006+
let arguments = (ins
2007+
CIR_ScalarOrVectorOf<CIR_BoolType>:$condition,
2008+
CIR_AnyType:$true_value,
2009+
CIR_AnyType:$false_value
2010+
);
2011+
19802012
let results = (outs CIR_AnyType:$result);
19812013

19822014
let assemblyFormat = [{
@@ -1989,6 +2021,7 @@ def CIR_SelectOp : CIR_Op<"select", [
19892021
}];
19902022

19912023
let hasFolder = 1;
2024+
let hasVerifier = 1;
19922025
}
19932026

19942027
//===----------------------------------------------------------------------===//

clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -250,10 +250,10 @@ def CIR_PtrToArray : CIR_PtrToType<CIR_AnyArrayType>;
250250

251251
def CIR_AnyVectorType : CIR_TypeBase<"::cir::VectorType", "vector type">;
252252

253-
def CIR_VectorElementType : AnyTypeOf<[CIR_AnyIntOrFloatType, CIR_AnyPtrType],
254-
"any cir integer, floating point or pointer type"
255-
> {
256-
let cppFunctionName = "isValidVectorTypeElementType";
253+
def CIR_VectorElementType
254+
: AnyTypeOf<[CIR_AnyBoolType, CIR_AnyIntOrFloatType, CIR_AnyPtrType],
255+
"any cir boolean, integer, floating point or pointer type"> {
256+
let cppFunctionName = "isValidVectorTypeElementType";
257257
}
258258

259259
class CIR_ElementTypePred<Pred pred> : SubstLeaves<"$_self",
@@ -266,6 +266,9 @@ class CIR_VectorTypeOf<list<Type> types, string summary = "">
266266
"vector of " # CIR_TypeSummaries<types>.value,
267267
summary)>;
268268

269+
// Type constraint accepting a either a type T or a vector of type T
270+
class CIR_ScalarOrVectorOf<Type T> : AnyTypeOf<[T, CIR_VectorTypeOf<[T]>]>;
271+
269272
// Vector of integral type
270273
def IntegerVector : Type<
271274
And<[

clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "clang/Basic/TargetBuiltins.h"
2121
#include "clang/CIR/Dialect/IR/CIRTypes.h"
2222
#include "clang/CIR/MissingFeatures.h"
23+
#include "llvm/Support/ErrorHandling.h"
2324

2425
using namespace clang;
2526
using namespace clang::CIRGen;
@@ -163,6 +164,41 @@ static mlir::Value emitX86CompressExpand(CIRGenBuilderTy &builder,
163164
mlir::ValueRange{source, mask, maskValue});
164165
}
165166

167+
static mlir::Value getBoolMaskVecValue(CIRGenBuilderTy &builder,
168+
mlir::Location loc, mlir::Value mask,
169+
unsigned numElems) {
170+
171+
cir::BoolType boolTy = builder.getBoolTy();
172+
auto maskTy = cir::VectorType::get(
173+
boolTy, cast<cir::IntType>(mask.getType()).getWidth());
174+
mlir::Value maskVec = builder.createBitcast(mask, maskTy);
175+
176+
if (numElems < 8) {
177+
SmallVector<mlir::Attribute> indices;
178+
indices.reserve(numElems);
179+
mlir::Type i32Ty = builder.getSInt32Ty();
180+
for (auto i : llvm::seq<unsigned>(0, numElems))
181+
indices.push_back(cir::IntAttr::get(i32Ty, i));
182+
183+
maskVec = builder.createVecShuffle(loc, maskVec, maskVec, indices);
184+
}
185+
return maskVec;
186+
}
187+
188+
static mlir::Value emitX86Select(CIRGenBuilderTy &builder, mlir::Location loc,
189+
mlir::Value mask, mlir::Value op0,
190+
mlir::Value op1) {
191+
auto constOp = mlir::dyn_cast_or_null<cir::ConstantOp>(mask.getDefiningOp());
192+
// If the mask is all ones just return first argument.
193+
if (constOp && constOp.isAllOnesValue())
194+
return op0;
195+
196+
mask = getBoolMaskVecValue(builder, loc, mask,
197+
cast<cir::VectorType>(op0.getType()).getSize());
198+
199+
return builder.createSelect(loc, mask, op0, op1);
200+
}
201+
166202
static mlir::Value emitX86MaskAddLogic(CIRGenBuilderTy &builder,
167203
mlir::Location loc,
168204
const std::string &intrinsicName,
@@ -1076,7 +1112,31 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID,
10761112
case X86::BI__builtin_ia32_extractf64x2_256_mask:
10771113
case X86::BI__builtin_ia32_extracti64x2_256_mask:
10781114
case X86::BI__builtin_ia32_extractf64x2_512_mask:
1079-
case X86::BI__builtin_ia32_extracti64x2_512_mask:
1115+
case X86::BI__builtin_ia32_extracti64x2_512_mask: {
1116+
mlir::Location loc = getLoc(expr->getExprLoc());
1117+
cir::VectorType dstTy = cast<cir::VectorType>(convertType(expr->getType()));
1118+
unsigned numElts = dstTy.getSize();
1119+
unsigned srcNumElts = cast<cir::VectorType>(ops[0].getType()).getSize();
1120+
unsigned subVectors = srcNumElts / numElts;
1121+
assert(llvm::isPowerOf2_32(subVectors) && "Expected power of 2 subvectors");
1122+
unsigned index =
1123+
ops[1].getDefiningOp<cir::ConstantOp>().getIntValue().getZExtValue();
1124+
1125+
index &= subVectors - 1; // Remove any extra bits.
1126+
index *= numElts;
1127+
1128+
int64_t indices[16];
1129+
std::iota(indices, indices + numElts, index);
1130+
1131+
mlir::Value poison =
1132+
builder.getConstant(loc, cir::PoisonAttr::get(ops[0].getType()));
1133+
mlir::Value res = builder.createVecShuffle(loc, ops[0], poison,
1134+
ArrayRef(indices, numElts));
1135+
if (ops.size() == 4)
1136+
res = emitX86Select(builder, loc, ops[3], res, ops[2]);
1137+
1138+
return res;
1139+
}
10801140
case X86::BI__builtin_ia32_vinsertf128_pd256:
10811141
case X86::BI__builtin_ia32_vinsertf128_ps256:
10821142
case X86::BI__builtin_ia32_vinsertf128_si256:

clang/lib/CIR/Dialect/IR/CIRDialect.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2340,6 +2340,25 @@ OpFoldResult cir::SelectOp::fold(FoldAdaptor adaptor) {
23402340
return {};
23412341
}
23422342

2343+
LogicalResult cir::SelectOp::verify() {
2344+
// AllTypesMatch already guarantees trueVal and falseVal have matching types.
2345+
auto condTy = dyn_cast<cir::VectorType>(getCondition().getType());
2346+
2347+
// If condition is not a vector, no further checks are needed.
2348+
if (!condTy)
2349+
return success();
2350+
2351+
// When condition is a vector, both other operands must also be vectors.
2352+
if (!isa<cir::VectorType>(getTrueValue().getType()) ||
2353+
!isa<cir::VectorType>(getFalseValue().getType())) {
2354+
return emitOpError()
2355+
<< "expected both true and false operands to be vector types "
2356+
"when the condition is a vector boolean type";
2357+
}
2358+
2359+
return success();
2360+
}
2361+
23432362
//===----------------------------------------------------------------------===//
23442363
// ShiftOp
23452364
//===----------------------------------------------------------------------===//

clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,184 @@ void test_mm512_mask_i64scatter_epi32(void *__addr, __mmask8 __mask, __m512i __i
696696
return _mm512_mask_i64scatter_epi32(__addr, __mask, __index, __v1, 2);
697697
}
698698

699+
__m256d test_mm512_extractf64x4_pd(__m512d a)
700+
{
701+
// CIR-LABEL: test_mm512_extractf64x4_pd
702+
// CIR: [[POISON:%.*]] = cir.const #cir.poison : !cir.vector<8 x !cir.double>
703+
// CIR: cir.vec.shuffle(%{{.*}}, [[POISON]] : !cir.vector<8 x !cir.double>) [#cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i, #cir.int<7> : !s32i] : !cir.vector<4 x !cir.double>
704+
705+
// LLVM-LABEL: test_mm512_extractf64x4_pd
706+
// LLVM: shufflevector <8 x double> %{{.*}}, <8 x double> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
707+
708+
// OGCG-LABEL: test_mm512_extractf64x4_pd
709+
// OGCG: shufflevector <8 x double> %{{.*}}, <8 x double> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
710+
return _mm512_extractf64x4_pd(a, 1);
711+
}
712+
713+
__m256d test_mm512_mask_extractf64x4_pd(__m256d __W,__mmask8 __U,__m512d __A){
714+
// CIR-LABEL: test_mm512_mask_extractf64x4_pd
715+
// CIR: [[POISON:%.*]] = cir.const #cir.poison : !cir.vector<8 x !cir.double>
716+
// CIR: cir.vec.shuffle(%{{.*}}, [[POISON]] : !cir.vector<8 x !cir.double>) [#cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i, #cir.int<7> : !s32i] : !cir.vector<4 x !cir.double>
717+
// CIR: cir.select if %{{.*}} then %{{.*}} else %{{.*}} : (!cir.vector<4 x !cir.bool>, !cir.vector<4 x !cir.double>, !cir.vector<4 x !cir.double>) -> !cir.vector<4 x !cir.double>
718+
719+
// LLVM-LABEL: test_mm512_mask_extractf64x4_pd
720+
// LLVM: shufflevector <8 x double> %{{.*}}, <8 x double> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
721+
// LLVM: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
722+
723+
// OGCG-LABEL: test_mm512_mask_extractf64x4_pd
724+
// OGCG: shufflevector <8 x double> %{{.*}}, <8 x double> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
725+
// OGCG: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
726+
return _mm512_mask_extractf64x4_pd( __W, __U, __A, 1);
727+
}
728+
729+
__m256d test_mm512_maskz_extractf64x4_pd(__mmask8 __U,__m512d __A){
730+
// CIR-LABEL: test_mm512_maskz_extractf64x4_pd
731+
// CIR: [[POISON:%.*]] = cir.const #cir.poison : !cir.vector<8 x !cir.double>
732+
// CIR: cir.vec.shuffle(%{{.*}}, [[POISON]] : !cir.vector<8 x !cir.double>) [#cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i, #cir.int<7> : !s32i] : !cir.vector<4 x !cir.double>
733+
// CIR: cir.select if %{{.*}} then %{{.*}} else %{{.*}} : (!cir.vector<4 x !cir.bool>, !cir.vector<4 x !cir.double>, !cir.vector<4 x !cir.double>) -> !cir.vector<4 x !cir.double>
734+
735+
// LLVM-LABEL: test_mm512_maskz_extractf64x4_pd
736+
// LLVM: shufflevector <8 x double> %{{.*}}, <8 x double> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
737+
// LLVM: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
738+
739+
// OGCG-LABEL: test_mm512_maskz_extractf64x4_pd
740+
// OGCG: shufflevector <8 x double> %{{.*}}, <8 x double> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
741+
// OGCG: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
742+
return _mm512_maskz_extractf64x4_pd( __U, __A, 1);
743+
}
744+
745+
__m128 test_mm512_extractf32x4_ps(__m512 a)
746+
{
747+
// CIR-LABEL: test_mm512_extractf32x4_ps
748+
// CIR: [[POISON:%.*]] = cir.const #cir.poison : !cir.vector<16 x !cir.float>
749+
// CIR: cir.vec.shuffle(%{{.*}}, [[POISON]] : !cir.vector<16 x !cir.float>) [#cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i, #cir.int<7> : !s32i] : !cir.vector<4 x !cir.float>
750+
751+
// LLVM-LABEL: test_mm512_extractf32x4_ps
752+
// LLVM: shufflevector <16 x float> %{{.*}}, <16 x float> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
753+
754+
// OGCG-LABEL: test_mm512_extractf32x4_ps
755+
// OGCG: shufflevector <16 x float> %{{.*}}, <16 x float> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
756+
return _mm512_extractf32x4_ps(a, 1);
757+
}
758+
759+
__m128 test_mm512_mask_extractf32x4_ps(__m128 __W, __mmask8 __U,__m512 __A){
760+
// CIR-LABEL: test_mm512_mask_extractf32x4_ps
761+
// CIR: [[POISON:%.*]] = cir.const #cir.poison : !cir.vector<16 x !cir.float>
762+
// CIR: cir.vec.shuffle(%{{.*}}, [[POISON]] : !cir.vector<16 x !cir.float>) [#cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i, #cir.int<7> : !s32i] : !cir.vector<4 x !cir.float>
763+
764+
// LLVM-LABEL: test_mm512_mask_extractf32x4_ps
765+
// LLVM: shufflevector <16 x float> %{{.*}}, <16 x float> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
766+
// LLVM: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
767+
768+
// OGCG-LABEL: test_mm512_mask_extractf32x4_ps
769+
// OGCG: shufflevector <16 x float> %{{.*}}, <16 x float> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
770+
// OGCG: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
771+
return _mm512_mask_extractf32x4_ps( __W, __U, __A, 1);
772+
}
773+
774+
__m128 test_mm512_maskz_extractf32x4_ps( __mmask8 __U,__m512 __A){
775+
// CIR-LABEL: test_mm512_maskz_extractf32x4_ps
776+
// CIR: [[POISON:%.*]] = cir.const #cir.poison : !cir.vector<16 x !cir.float>
777+
// CIR: cir.vec.shuffle(%{{.*}}, [[POISON]] : !cir.vector<16 x !cir.float>) [#cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i, #cir.int<7> : !s32i] : !cir.vector<4 x !cir.float>
778+
779+
// LLVM-LABEL: test_mm512_maskz_extractf32x4_ps
780+
// LLVM: shufflevector <16 x float> %{{.*}}, <16 x float> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
781+
// LLVM: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
782+
783+
// OGCG-LABEL: test_mm512_maskz_extractf32x4_ps
784+
// OGCG: shufflevector <16 x float> %{{.*}}, <16 x float> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
785+
// OGCG: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
786+
return _mm512_maskz_extractf32x4_ps(__U, __A, 1);
787+
}
788+
789+
__m128i test_mm512_extracti32x4_epi32(__m512i __A) {
790+
// CIR-LABEL: test_mm512_extracti32x4_epi32
791+
// CIR: [[POISON:%.*]] = cir.const #cir.poison : !cir.vector<16 x !s32i>
792+
// CIR: cir.vec.shuffle(%{{.*}}, [[POISON]] : !cir.vector<16 x !s32i>) [#cir.int<12> : !s32i, #cir.int<13> : !s32i, #cir.int<14> : !s32i, #cir.int<15> : !s32i] : !cir.vector<4 x !s32i>
793+
794+
// LLVM-LABEL: test_mm512_extracti32x4_epi32
795+
// LLVM: shufflevector <16 x i32> %{{.*}}, <16 x i32> poison, <4 x i32> <i32 12, i32 13, i32 14, i32 15>
796+
797+
// OGCG-LABEL: test_mm512_extracti32x4_epi32
798+
// OGCG: shufflevector <16 x i32> %{{.*}}, <16 x i32> poison, <4 x i32> <i32 12, i32 13, i32 14, i32 15>
799+
return _mm512_extracti32x4_epi32(__A, 3);
800+
}
801+
802+
__m128i test_mm512_mask_extracti32x4_epi32(__m128i __W, __mmask8 __U, __m512i __A) {
803+
// CIR-LABEL: test_mm512_mask_extracti32x4_epi32
804+
// CIR: [[POISON:%.*]] = cir.const #cir.poison : !cir.vector<16 x !s32i>
805+
// CIR: cir.vec.shuffle(%{{.*}}, [[POISON]] : !cir.vector<16 x !s32i>) [#cir.int<12> : !s32i, #cir.int<13> : !s32i, #cir.int<14> : !s32i, #cir.int<15> : !s32i] : !cir.vector<4 x !s32i>
806+
// CIR: cir.select if %{{.*}} then %{{.*}} else %{{.*}} : (!cir.vector<4 x !cir.bool>, !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i>) -> !cir.vector<4 x !s32i>
807+
808+
// LLVM-LABEL: test_mm512_mask_extracti32x4_epi32
809+
// LLVM: shufflevector <16 x i32> %{{.*}}, <16 x i32> poison, <4 x i32> <i32 12, i32 13, i32 14, i32 15>
810+
// LLVM: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
811+
812+
// OGCG-LABEL: test_mm512_mask_extracti32x4_epi32
813+
// OGCG: shufflevector <16 x i32> %{{.*}}, <16 x i32> poison, <4 x i32> <i32 12, i32 13, i32 14, i32 15>
814+
// OGCG: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
815+
return _mm512_mask_extracti32x4_epi32(__W, __U, __A, 3);
816+
}
817+
818+
__m128i test_mm512_maskz_extracti32x4_epi32(__mmask8 __U, __m512i __A) {
819+
// CIR-LABEL: test_mm512_maskz_extracti32x4_epi32
820+
// CIR: [[POISON:%.*]] = cir.const #cir.poison : !cir.vector<16 x !s32i>
821+
// CIR: cir.vec.shuffle(%{{.*}}, [[POISON]] : !cir.vector<16 x !s32i>) [#cir.int<12> : !s32i, #cir.int<13> : !s32i, #cir.int<14> : !s32i, #cir.int<15> : !s32i] : !cir.vector<4 x !s32i>
822+
// CIR: cir.select if %{{.*}} then %{{.*}} else %{{.*}} : (!cir.vector<4 x !cir.bool>, !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i>) -> !cir.vector<4 x !s32i>
823+
824+
// LLVM-LABEL: test_mm512_maskz_extracti32x4_epi32
825+
// LLVM: shufflevector <16 x i32> %{{.*}}, <16 x i32> poison, <4 x i32> <i32 12, i32 13, i32 14, i32 15>
826+
// LLVM: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
827+
828+
// OGCG-LABEL: test_mm512_maskz_extracti32x4_epi32
829+
// OGCG: shufflevector <16 x i32> %{{.*}}, <16 x i32> poison, <4 x i32> <i32 12, i32 13, i32 14, i32 15>
830+
// OGCG: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
831+
return _mm512_maskz_extracti32x4_epi32(__U, __A, 3);
832+
}
833+
834+
__m256i test_mm512_extracti64x4_epi64(__m512i __A) {
835+
// CIR-LABEL: test_mm512_extracti64x4_epi64
836+
// CIR: [[POISON:%.*]] = cir.const #cir.poison : !cir.vector<8 x !s64i>
837+
// CIR: cir.vec.shuffle(%{{.*}}, [[POISON]] : !cir.vector<8 x !s64i>) [#cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i, #cir.int<7> : !s32i] : !cir.vector<4 x !s64i>
838+
839+
// LLVM-LABEL: test_mm512_extracti64x4_epi64
840+
// LLVM: shufflevector <8 x i64> %{{.*}}, <8 x i64> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
841+
842+
// OGCG-LABEL: test_mm512_extracti64x4_epi64
843+
// OGCG: shufflevector <8 x i64> %{{.*}}, <8 x i64> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
844+
return _mm512_extracti64x4_epi64(__A, 1);
845+
}
846+
847+
__m256i test_mm512_mask_extracti64x4_epi64(__m256i __W, __mmask8 __U, __m512i __A) {
848+
// CIR-LABEL: test_mm512_mask_extracti64x4_epi64
849+
// CIR: [[POISON:%.*]] = cir.const #cir.poison : !cir.vector<8 x !s64i>
850+
// CIR: cir.vec.shuffle(%{{.*}}, [[POISON]] : !cir.vector<8 x !s64i>) [#cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i, #cir.int<7> : !s32i] : !cir.vector<4 x !s64i>
851+
852+
// LLVM-LABEL: test_mm512_mask_extracti64x4_epi64
853+
// LLVM: shufflevector <8 x i64> %{{.*}}, <8 x i64> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
854+
// LLVM: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
855+
856+
// OGCG-LABEL: test_mm512_mask_extracti64x4_epi64
857+
// OGCG: shufflevector <8 x i64> %{{.*}}, <8 x i64> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
858+
// OGCG: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
859+
return _mm512_mask_extracti64x4_epi64(__W, __U, __A, 1);
860+
}
861+
862+
__m256i test_mm512_maskz_extracti64x4_epi64(__mmask8 __U, __m512i __A) {
863+
// CIR-LABEL: test_mm512_maskz_extracti64x4_epi64
864+
// CIR: [[POISON:%.*]] = cir.const #cir.poison : !cir.vector<8 x !s64i>
865+
// CIR: cir.vec.shuffle(%{{.*}}, [[POISON]] : !cir.vector<8 x !s64i>) [#cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i, #cir.int<7> : !s32i] : !cir.vector<4 x !s64i>
866+
867+
// LLVM-LABEL: test_mm512_maskz_extracti64x4_epi64
868+
// LLVM: shufflevector <8 x i64> %{{.*}}, <8 x i64> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
869+
// LLVM: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
870+
871+
// OGCG-LABEL: test_mm512_maskz_extracti64x4_epi64
872+
// OGCG: shufflevector <8 x i64> %{{.*}}, <8 x i64> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
873+
// OGCG: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
874+
return _mm512_maskz_extracti64x4_epi64(__U, __A, 1);
875+
}
876+
699877
__m512i test_mm512_mul_epi32(__m512i __A, __m512i __B) {
700878
// CIR-LABEL: _mm512_mul_epi32
701879
// CIR: [[A64:%.*]] = cir.cast bitcast %{{.*}} : !cir.vector<16 x !s32i> -> !cir.vector<8 x !s64i>

0 commit comments

Comments
 (0)