Skip to content

Commit 331fa2c

Browse files
author
git apple-llvm automerger
committed
Merge commit 'e2550b7aa072' from llvm.org/main into next
2 parents dcaa79f + e2550b7 commit 331fa2c

File tree

8 files changed

+792
-803
lines changed

8 files changed

+792
-803
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 72 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -9687,17 +9687,22 @@ Value *CodeGenFunction::EmitSVEStructStore(const SVETypeFlags &TypeFlags,
96879687
Value *BasePtr = Ops[1];
96889688

96899689
// Does the store have an offset?
9690-
if (Ops.size() > (2 + N))
9690+
if (Ops.size() > 3)
96919691
BasePtr = Builder.CreateGEP(VTy, BasePtr, Ops[2]);
96929692

9693+
Value *Val = Ops.back();
9694+
96939695
// The llvm.aarch64.sve.st2/3/4 intrinsics take legal part vectors, so we
96949696
// need to break up the tuple vector.
96959697
SmallVector<llvm::Value*, 5> Operands;
9696-
for (unsigned I = Ops.size() - N; I < Ops.size(); ++I)
9697-
Operands.push_back(Ops[I]);
9698+
unsigned MinElts = VTy->getElementCount().getKnownMinValue();
9699+
for (unsigned I = 0; I < N; ++I) {
9700+
Value *Idx = ConstantInt::get(CGM.Int64Ty, I * MinElts);
9701+
Operands.push_back(Builder.CreateExtractVector(VTy, Val, Idx));
9702+
}
96989703
Operands.append({Predicate, BasePtr});
9699-
Function *F = CGM.getIntrinsic(IntID, { VTy });
97009704

9705+
Function *F = CGM.getIntrinsic(IntID, { VTy });
97019706
return Builder.CreateCall(F, Operands);
97029707
}
97039708

@@ -10004,24 +10009,26 @@ Value *CodeGenFunction::FormSVEBuiltinResult(Value *Call) {
1000410009
return Call;
1000510010
}
1000610011

10007-
void CodeGenFunction::GetAArch64SVEProcessedOperands(
10008-
unsigned BuiltinID, const CallExpr *E, SmallVectorImpl<Value *> &Ops,
10009-
SVETypeFlags TypeFlags) {
10012+
Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID,
10013+
const CallExpr *E) {
1001010014
// Find out if any arguments are required to be integer constant expressions.
1001110015
unsigned ICEArguments = 0;
1001210016
ASTContext::GetBuiltinTypeError Error;
1001310017
getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
1001410018
assert(Error == ASTContext::GE_None && "Should not codegen an error");
1001510019

10016-
// Tuple set/get only requires one insert/extract vector, which is
10017-
// created by EmitSVETupleSetOrGet.
10018-
bool IsTupleGetOrSet = TypeFlags.isTupleSet() || TypeFlags.isTupleGet();
10020+
llvm::Type *Ty = ConvertType(E->getType());
10021+
if (BuiltinID >= SVE::BI__builtin_sve_reinterpret_s8_s8 &&
10022+
BuiltinID <= SVE::BI__builtin_sve_reinterpret_f64_f64) {
10023+
Value *Val = EmitScalarExpr(E->getArg(0));
10024+
return EmitSVEReinterpret(Val, Ty);
10025+
}
1001910026

10027+
llvm::SmallVector<Value *, 4> Ops;
1002010028
for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) {
10021-
bool IsICE = ICEArguments & (1 << i);
10022-
Value *Arg = EmitScalarExpr(E->getArg(i));
10023-
10024-
if (IsICE) {
10029+
if ((ICEArguments & (1 << i)) == 0)
10030+
Ops.push_back(EmitScalarExpr(E->getArg(i)));
10031+
else {
1002510032
// If this is required to be a constant, constant fold it so that we know
1002610033
// that the generated intrinsic gets a ConstantInt.
1002710034
std::optional<llvm::APSInt> Result =
@@ -10033,49 +10040,12 @@ void CodeGenFunction::GetAArch64SVEProcessedOperands(
1003310040
// immediate requires more than a handful of bits.
1003410041
*Result = Result->extOrTrunc(32);
1003510042
Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), *Result));
10036-
continue;
10037-
}
10038-
10039-
if (IsTupleGetOrSet || !isa<ScalableVectorType>(Arg->getType())) {
10040-
Ops.push_back(Arg);
10041-
continue;
10042-
}
10043-
10044-
auto *VTy = cast<ScalableVectorType>(Arg->getType());
10045-
unsigned MinElts = VTy->getMinNumElements();
10046-
bool IsPred = VTy->getElementType()->isIntegerTy(1);
10047-
unsigned N = (MinElts * VTy->getScalarSizeInBits()) / (IsPred ? 16 : 128);
10048-
10049-
if (N == 1) {
10050-
Ops.push_back(Arg);
10051-
continue;
10052-
}
10053-
10054-
for (unsigned I = 0; I < N; ++I) {
10055-
Value *Idx = ConstantInt::get(CGM.Int64Ty, (I * MinElts) / N);
10056-
auto *NewVTy =
10057-
ScalableVectorType::get(VTy->getElementType(), MinElts / N);
10058-
Ops.push_back(Builder.CreateExtractVector(NewVTy, Arg, Idx));
1005910043
}
1006010044
}
10061-
}
10062-
10063-
Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID,
10064-
const CallExpr *E) {
10065-
llvm::Type *Ty = ConvertType(E->getType());
10066-
if (BuiltinID >= SVE::BI__builtin_sve_reinterpret_s8_s8 &&
10067-
BuiltinID <= SVE::BI__builtin_sve_reinterpret_f64_f64) {
10068-
Value *Val = EmitScalarExpr(E->getArg(0));
10069-
return EmitSVEReinterpret(Val, Ty);
10070-
}
1007110045

1007210046
auto *Builtin = findARMVectorIntrinsicInMap(AArch64SVEIntrinsicMap, BuiltinID,
1007310047
AArch64SVEIntrinsicsProvenSorted);
10074-
10075-
llvm::SmallVector<Value *, 4> Ops;
1007610048
SVETypeFlags TypeFlags(Builtin->TypeModifier);
10077-
GetAArch64SVEProcessedOperands(BuiltinID, E, Ops, TypeFlags);
10078-
1007910049
if (TypeFlags.isLoad())
1008010050
return EmitSVEMaskedLoad(E, Ty, Ops, Builtin->LLVMIntrinsic,
1008110051
TypeFlags.isZExtReturn());
@@ -10089,14 +10059,14 @@ Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID,
1008910059
return EmitSVEPrefetchLoad(TypeFlags, Ops, Builtin->LLVMIntrinsic);
1009010060
else if (TypeFlags.isGatherPrefetch())
1009110061
return EmitSVEGatherPrefetch(TypeFlags, Ops, Builtin->LLVMIntrinsic);
10092-
else if (TypeFlags.isStructLoad())
10093-
return EmitSVEStructLoad(TypeFlags, Ops, Builtin->LLVMIntrinsic);
10094-
else if (TypeFlags.isStructStore())
10095-
return EmitSVEStructStore(TypeFlags, Ops, Builtin->LLVMIntrinsic);
10062+
else if (TypeFlags.isStructLoad())
10063+
return EmitSVEStructLoad(TypeFlags, Ops, Builtin->LLVMIntrinsic);
10064+
else if (TypeFlags.isStructStore())
10065+
return EmitSVEStructStore(TypeFlags, Ops, Builtin->LLVMIntrinsic);
1009610066
else if (TypeFlags.isTupleSet() || TypeFlags.isTupleGet())
10097-
return EmitSVETupleSetOrGet(TypeFlags, Ty, Ops);
10067+
return EmitSVETupleSetOrGet(TypeFlags, Ty, Ops);
1009810068
else if (TypeFlags.isTupleCreate())
10099-
return EmitSVETupleCreate(TypeFlags, Ty, Ops);
10069+
return EmitSVETupleCreate(TypeFlags, Ty, Ops);
1010010070
else if (TypeFlags.isUndef())
1010110071
return UndefValue::get(Ty);
1010210072
else if (Builtin->LLVMIntrinsic != 0) {
@@ -10348,8 +10318,13 @@ Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID,
1034810318
case SVE::BI__builtin_sve_svtbl2_f64: {
1034910319
SVETypeFlags TF(Builtin->TypeModifier);
1035010320
auto VTy = cast<llvm::ScalableVectorType>(getSVEType(TF));
10321+
Value *V0 = Builder.CreateExtractVector(VTy, Ops[0],
10322+
ConstantInt::get(CGM.Int64Ty, 0));
10323+
unsigned MinElts = VTy->getMinNumElements();
10324+
Value *V1 = Builder.CreateExtractVector(
10325+
VTy, Ops[0], ConstantInt::get(CGM.Int64Ty, MinElts));
1035110326
Function *F = CGM.getIntrinsic(Intrinsic::aarch64_sve_tbl2, VTy);
10352-
return Builder.CreateCall(F, Ops);
10327+
return Builder.CreateCall(F, {V0, V1, Ops[1]});
1035310328
}
1035410329

1035510330
case SVE::BI__builtin_sve_svset_neonq_s8:
@@ -10407,13 +10382,35 @@ Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID,
1040710382

1040810383
Value *CodeGenFunction::EmitAArch64SMEBuiltinExpr(unsigned BuiltinID,
1040910384
const CallExpr *E) {
10410-
auto *Builtin = findARMVectorIntrinsicInMap(AArch64SMEIntrinsicMap, BuiltinID,
10411-
AArch64SMEIntrinsicsProvenSorted);
10385+
// Find out if any arguments are required to be integer constant expressions.
10386+
unsigned ICEArguments = 0;
10387+
ASTContext::GetBuiltinTypeError Error;
10388+
getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
10389+
assert(Error == ASTContext::GE_None && "Should not codegen an error");
1041210390

10391+
llvm::Type *Ty = ConvertType(E->getType());
1041310392
llvm::SmallVector<Value *, 4> Ops;
10414-
SVETypeFlags TypeFlags(Builtin->TypeModifier);
10415-
GetAArch64SVEProcessedOperands(BuiltinID, E, Ops, TypeFlags);
10393+
for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) {
10394+
if ((ICEArguments & (1 << i)) == 0)
10395+
Ops.push_back(EmitScalarExpr(E->getArg(i)));
10396+
else {
10397+
// If this is required to be a constant, constant fold it so that we know
10398+
// that the generated intrinsic gets a ConstantInt.
10399+
std::optional<llvm::APSInt> Result =
10400+
E->getArg(i)->getIntegerConstantExpr(getContext());
10401+
assert(Result && "Expected argument to be a constant");
10402+
10403+
// Immediates for SVE llvm intrinsics are always 32bit. We can safely
10404+
// truncate because the immediate has been range checked and no valid
10405+
// immediate requires more than a handful of bits.
10406+
*Result = Result->extOrTrunc(32);
10407+
Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), *Result));
10408+
}
10409+
}
1041610410

10411+
auto *Builtin = findARMVectorIntrinsicInMap(AArch64SMEIntrinsicMap, BuiltinID,
10412+
AArch64SMEIntrinsicsProvenSorted);
10413+
SVETypeFlags TypeFlags(Builtin->TypeModifier);
1041710414
if (TypeFlags.isLoad() || TypeFlags.isStore())
1041810415
return EmitSMELd1St1(TypeFlags, Ops, Builtin->LLVMIntrinsic);
1041910416
else if (TypeFlags.isReadZA() || TypeFlags.isWriteZA())
@@ -10426,24 +10423,21 @@ Value *CodeGenFunction::EmitAArch64SMEBuiltinExpr(unsigned BuiltinID,
1042610423
BuiltinID == SME::BI__builtin_sme_svldr_za ||
1042710424
BuiltinID == SME::BI__builtin_sme_svstr_za)
1042810425
return EmitSMELdrStr(TypeFlags, Ops, Builtin->LLVMIntrinsic);
10426+
else if (Builtin->LLVMIntrinsic != 0) {
10427+
// Predicates must match the main datatype.
10428+
for (unsigned i = 0, e = Ops.size(); i != e; ++i)
10429+
if (auto PredTy = dyn_cast<llvm::VectorType>(Ops[i]->getType()))
10430+
if (PredTy->getElementType()->isIntegerTy(1))
10431+
Ops[i] = EmitSVEPredicateCast(Ops[i], getSVEType(TypeFlags));
1042910432

10430-
// Should not happen!
10431-
if (Builtin->LLVMIntrinsic == 0)
10432-
return nullptr;
10433-
10434-
// Predicates must match the main datatype.
10435-
for (unsigned i = 0, e = Ops.size(); i != e; ++i)
10436-
if (auto PredTy = dyn_cast<llvm::VectorType>(Ops[i]->getType()))
10437-
if (PredTy->getElementType()->isIntegerTy(1))
10438-
Ops[i] = EmitSVEPredicateCast(Ops[i], getSVEType(TypeFlags));
10439-
10440-
Function *F =
10441-
TypeFlags.isOverloadNone()
10442-
? CGM.getIntrinsic(Builtin->LLVMIntrinsic)
10443-
: CGM.getIntrinsic(Builtin->LLVMIntrinsic, {getSVEType(TypeFlags)});
10444-
Value *Call = Builder.CreateCall(F, Ops);
10433+
Function *F = CGM.getIntrinsic(Builtin->LLVMIntrinsic,
10434+
getSVEOverloadTypes(TypeFlags, Ty, Ops));
10435+
Value *Call = Builder.CreateCall(F, Ops);
10436+
return Call;
10437+
}
1044510438

10446-
return FormSVEBuiltinResult(Call);
10439+
/// Should not happen
10440+
return nullptr;
1044710441
}
1044810442

1044910443
Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4357,11 +4357,6 @@ class CodeGenFunction : public CodeGenTypeCache {
43574357
llvm::Value *EmitSMELdrStr(const SVETypeFlags &TypeFlags,
43584358
llvm::SmallVectorImpl<llvm::Value *> &Ops,
43594359
unsigned IntID);
4360-
4361-
void GetAArch64SVEProcessedOperands(unsigned BuiltinID, const CallExpr *E,
4362-
SmallVectorImpl<llvm::Value *> &Ops,
4363-
SVETypeFlags TypeFlags);
4364-
43654360
llvm::Value *EmitAArch64SMEBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
43664361

43674362
llvm::Value *EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E,

clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st2-bfloat.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,18 @@
1616
#endif
1717
// CHECK-LABEL: @test_svst2_bf16(
1818
// CHECK-NEXT: entry:
19-
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 8 x bfloat> @llvm.vector.extract.nxv8bf16.nxv16bf16(<vscale x 16 x bfloat> [[DATA:%.*]], i64 0)
20-
// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 8 x bfloat> @llvm.vector.extract.nxv8bf16.nxv16bf16(<vscale x 16 x bfloat> [[DATA]], i64 8)
21-
// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> [[PG:%.*]])
22-
// CHECK-NEXT: tail call void @llvm.aarch64.sve.st2.nxv8bf16(<vscale x 8 x bfloat> [[TMP0]], <vscale x 8 x bfloat> [[TMP1]], <vscale x 8 x i1> [[TMP2]], ptr [[BASE:%.*]])
19+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> [[PG:%.*]])
20+
// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 8 x bfloat> @llvm.vector.extract.nxv8bf16.nxv16bf16(<vscale x 16 x bfloat> [[DATA:%.*]], i64 0)
21+
// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x bfloat> @llvm.vector.extract.nxv8bf16.nxv16bf16(<vscale x 16 x bfloat> [[DATA]], i64 8)
22+
// CHECK-NEXT: tail call void @llvm.aarch64.sve.st2.nxv8bf16(<vscale x 8 x bfloat> [[TMP1]], <vscale x 8 x bfloat> [[TMP2]], <vscale x 8 x i1> [[TMP0]], ptr [[BASE:%.*]])
2323
// CHECK-NEXT: ret void
2424
//
2525
// CPP-CHECK-LABEL: @_Z15test_svst2_bf16u10__SVBool_tPu6__bf1614svbfloat16x2_t(
2626
// CPP-CHECK-NEXT: entry:
27-
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 8 x bfloat> @llvm.vector.extract.nxv8bf16.nxv16bf16(<vscale x 16 x bfloat> [[DATA:%.*]], i64 0)
28-
// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 8 x bfloat> @llvm.vector.extract.nxv8bf16.nxv16bf16(<vscale x 16 x bfloat> [[DATA]], i64 8)
29-
// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> [[PG:%.*]])
30-
// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st2.nxv8bf16(<vscale x 8 x bfloat> [[TMP0]], <vscale x 8 x bfloat> [[TMP1]], <vscale x 8 x i1> [[TMP2]], ptr [[BASE:%.*]])
27+
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> [[PG:%.*]])
28+
// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 8 x bfloat> @llvm.vector.extract.nxv8bf16.nxv16bf16(<vscale x 16 x bfloat> [[DATA:%.*]], i64 0)
29+
// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x bfloat> @llvm.vector.extract.nxv8bf16.nxv16bf16(<vscale x 16 x bfloat> [[DATA]], i64 8)
30+
// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st2.nxv8bf16(<vscale x 8 x bfloat> [[TMP1]], <vscale x 8 x bfloat> [[TMP2]], <vscale x 8 x i1> [[TMP0]], ptr [[BASE:%.*]])
3131
// CPP-CHECK-NEXT: ret void
3232
//
3333
void test_svst2_bf16(svbool_t pg, bfloat16_t *base, svbfloat16x2_t data)
@@ -37,20 +37,20 @@ void test_svst2_bf16(svbool_t pg, bfloat16_t *base, svbfloat16x2_t data)
3737

3838
// CHECK-LABEL: @test_svst2_vnum_bf16(
3939
// CHECK-NEXT: entry:
40-
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 8 x bfloat> @llvm.vector.extract.nxv8bf16.nxv16bf16(<vscale x 16 x bfloat> [[DATA:%.*]], i64 0)
41-
// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 8 x bfloat> @llvm.vector.extract.nxv8bf16.nxv16bf16(<vscale x 16 x bfloat> [[DATA]], i64 8)
42-
// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> [[PG:%.*]])
43-
// CHECK-NEXT: [[TMP3:%.*]] = getelementptr <vscale x 8 x bfloat>, ptr [[BASE:%.*]], i64 [[VNUM:%.*]]
44-
// CHECK-NEXT: tail call void @llvm.aarch64.sve.st2.nxv8bf16(<vscale x 8 x bfloat> [[TMP0]], <vscale x 8 x bfloat> [[TMP1]], <vscale x 8 x i1> [[TMP2]], ptr [[TMP3]])
40+
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> [[PG:%.*]])
41+
// CHECK-NEXT: [[TMP1:%.*]] = getelementptr <vscale x 8 x bfloat>, ptr [[BASE:%.*]], i64 [[VNUM:%.*]]
42+
// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x bfloat> @llvm.vector.extract.nxv8bf16.nxv16bf16(<vscale x 16 x bfloat> [[DATA:%.*]], i64 0)
43+
// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 8 x bfloat> @llvm.vector.extract.nxv8bf16.nxv16bf16(<vscale x 16 x bfloat> [[DATA]], i64 8)
44+
// CHECK-NEXT: tail call void @llvm.aarch64.sve.st2.nxv8bf16(<vscale x 8 x bfloat> [[TMP2]], <vscale x 8 x bfloat> [[TMP3]], <vscale x 8 x i1> [[TMP0]], ptr [[TMP1]])
4545
// CHECK-NEXT: ret void
4646
//
4747
// CPP-CHECK-LABEL: @_Z20test_svst2_vnum_bf16u10__SVBool_tPu6__bf16l14svbfloat16x2_t(
4848
// CPP-CHECK-NEXT: entry:
49-
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 8 x bfloat> @llvm.vector.extract.nxv8bf16.nxv16bf16(<vscale x 16 x bfloat> [[DATA:%.*]], i64 0)
50-
// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 8 x bfloat> @llvm.vector.extract.nxv8bf16.nxv16bf16(<vscale x 16 x bfloat> [[DATA]], i64 8)
51-
// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> [[PG:%.*]])
52-
// CPP-CHECK-NEXT: [[TMP3:%.*]] = getelementptr <vscale x 8 x bfloat>, ptr [[BASE:%.*]], i64 [[VNUM:%.*]]
53-
// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st2.nxv8bf16(<vscale x 8 x bfloat> [[TMP0]], <vscale x 8 x bfloat> [[TMP1]], <vscale x 8 x i1> [[TMP2]], ptr [[TMP3]])
49+
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> [[PG:%.*]])
50+
// CPP-CHECK-NEXT: [[TMP1:%.*]] = getelementptr <vscale x 8 x bfloat>, ptr [[BASE:%.*]], i64 [[VNUM:%.*]]
51+
// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x bfloat> @llvm.vector.extract.nxv8bf16.nxv16bf16(<vscale x 16 x bfloat> [[DATA:%.*]], i64 0)
52+
// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 8 x bfloat> @llvm.vector.extract.nxv8bf16.nxv16bf16(<vscale x 16 x bfloat> [[DATA]], i64 8)
53+
// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sve.st2.nxv8bf16(<vscale x 8 x bfloat> [[TMP2]], <vscale x 8 x bfloat> [[TMP3]], <vscale x 8 x i1> [[TMP0]], ptr [[TMP1]])
5454
// CPP-CHECK-NEXT: ret void
5555
//
5656
void test_svst2_vnum_bf16(svbool_t pg, bfloat16_t *base, int64_t vnum, svbfloat16x2_t data)

0 commit comments

Comments
 (0)