Skip to content

Commit 2de024e

Browse files
committed
[flang] Add PowerPC vec_lxv, vec_lvsl, vec_lvsr, vec_xl, vec_xl_be and vec_xlds intrinsic
Differential Revision: https://reviews.llvm.org/D157920
1 parent f0221fb commit 2de024e

File tree

5 files changed

+1629
-7
lines changed

5 files changed

+1629
-7
lines changed

flang/include/flang/Optimizer/Builder/PPCIntrinsicCall.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ enum class VecOp {
3232
Ld,
3333
Lde,
3434
Ldl,
35+
Lvsl,
36+
Lvsr,
37+
Lxv,
3538
Lxvp,
3639
Mergeh,
3740
Mergel,
@@ -57,6 +60,8 @@ enum class VecOp {
5760
Stxv,
5861
Stxvp,
5962
Sub,
63+
Xl,
64+
Xlbe,
6065
Xld2,
6166
Xlw4,
6267
Xor,
@@ -275,10 +280,21 @@ struct PPCIntrinsicLibrary : IntrinsicLibrary {
275280
fir::ExtendedValue genVecPerm(mlir::Type resultType,
276281
llvm::ArrayRef<fir::ExtendedValue> args);
277282

283+
fir::ExtendedValue genVecXlGrp(mlir::Type resultType,
284+
llvm::ArrayRef<fir::ExtendedValue> args);
285+
278286
template <VecOp>
279287
fir::ExtendedValue genVecLdCallGrp(mlir::Type resultType,
280288
llvm::ArrayRef<fir::ExtendedValue> args);
281289

290+
template <VecOp>
291+
fir::ExtendedValue genVecLdNoCallGrp(mlir::Type resultType,
292+
llvm::ArrayRef<fir::ExtendedValue> args);
293+
294+
template <VecOp>
295+
fir::ExtendedValue genVecLvsGrp(mlir::Type resultType,
296+
llvm::ArrayRef<fir::ExtendedValue> args);
297+
282298
template <VecOp>
283299
fir::ExtendedValue genVecNmaddMsub(mlir::Type resultType,
284300
llvm::ArrayRef<fir::ExtendedValue> args);
@@ -299,6 +315,9 @@ struct PPCIntrinsicLibrary : IntrinsicLibrary {
299315
template <VecOp vop>
300316
fir::ExtendedValue genVecSplat(mlir::Type resultType,
301317
llvm::ArrayRef<fir::ExtendedValue> args);
318+
319+
fir::ExtendedValue genVecXlds(mlir::Type resultType,
320+
llvm::ArrayRef<fir::ExtendedValue> args);
302321
};
303322

304323
const IntrinsicHandler *findPPCIntrinsicHandler(llvm::StringRef name);

flang/lib/Optimizer/Builder/PPCIntrinsicCall.cpp

Lines changed: 168 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,21 @@ static constexpr IntrinsicHandler ppcHandlers[]{
589589
&PI::genVecLdCallGrp<VecOp::Ldl>),
590590
{{{"arg1", asValue}, {"arg2", asAddr}}},
591591
/*isElemental=*/false},
592+
{"__ppc_vec_lvsl",
593+
static_cast<IntrinsicLibrary::ExtendedGenerator>(
594+
&PI::genVecLvsGrp<VecOp::Lvsl>),
595+
{{{"arg1", asValue}, {"arg2", asAddr}}},
596+
/*isElemental=*/false},
597+
{"__ppc_vec_lvsr",
598+
static_cast<IntrinsicLibrary::ExtendedGenerator>(
599+
&PI::genVecLvsGrp<VecOp::Lvsr>),
600+
{{{"arg1", asValue}, {"arg2", asAddr}}},
601+
/*isElemental=*/false},
602+
{"__ppc_vec_lxv",
603+
static_cast<IntrinsicLibrary::ExtendedGenerator>(
604+
&PI::genVecLdNoCallGrp<VecOp::Lxv>),
605+
{{{"arg1", asValue}, {"arg2", asAddr}}},
606+
/*isElemental=*/false},
592607
{"__ppc_vec_lxvp",
593608
static_cast<IntrinsicLibrary::ExtendedGenerator>(
594609
&PI::genVecLdCallGrp<VecOp::Lxvp>),
@@ -713,11 +728,24 @@ static constexpr IntrinsicHandler ppcHandlers[]{
713728
&PI::genVecAddAndMulSubXor<VecOp::Sub>),
714729
{{{"arg1", asValue}, {"arg2", asValue}}},
715730
/*isElemental=*/true},
731+
{"__ppc_vec_xl",
732+
static_cast<IntrinsicLibrary::ExtendedGenerator>(&PI::genVecXlGrp),
733+
{{{"arg1", asValue}, {"arg2", asAddr}}},
734+
/*isElemental=*/false},
735+
{"__ppc_vec_xl_be",
736+
static_cast<IntrinsicLibrary::ExtendedGenerator>(
737+
&PI::genVecLdNoCallGrp<VecOp::Xlbe>),
738+
{{{"arg1", asValue}, {"arg2", asAddr}}},
739+
/*isElemental=*/false},
716740
{"__ppc_vec_xld2_",
717741
static_cast<IntrinsicLibrary::ExtendedGenerator>(
718742
&PI::genVecLdCallGrp<VecOp::Xld2>),
719743
{{{"arg1", asValue}, {"arg2", asAddr}}},
720744
/*isElemental=*/false},
745+
{"__ppc_vec_xlds",
746+
static_cast<IntrinsicLibrary::ExtendedGenerator>(&PI::genVecXlds),
747+
{{{"arg1", asValue}, {"arg2", asAddr}}},
748+
/*isElemental=*/false},
721749
{"__ppc_vec_xlw4_",
722750
static_cast<IntrinsicLibrary::ExtendedGenerator>(
723751
&PI::genVecLdCallGrp<VecOp::Xlw4>),
@@ -1797,6 +1825,62 @@ static mlir::Value reverseVectorElements(fir::FirOpBuilder &builder,
17971825
return builder.create<mlir::vector::ShuffleOp>(loc, v, undefVec, mask);
17981826
}
17991827

1828+
static mlir::NamedAttribute getAlignmentAttr(fir::FirOpBuilder &builder,
1829+
const int val) {
1830+
auto i64ty{mlir::IntegerType::get(builder.getContext(), 64)};
1831+
auto alignAttr{mlir::IntegerAttr::get(i64ty, val)};
1832+
return builder.getNamedAttr("alignment", alignAttr);
1833+
}
1834+
1835+
fir::ExtendedValue
1836+
PPCIntrinsicLibrary::genVecXlGrp(mlir::Type resultType,
1837+
llvm::ArrayRef<fir::ExtendedValue> args) {
1838+
VecTypeInfo vecTyInfo{getVecTypeFromFirType(resultType)};
1839+
switch (vecTyInfo.eleTy.getIntOrFloatBitWidth()) {
1840+
case 8:
1841+
// vec_xlb1
1842+
return genVecLdNoCallGrp<VecOp::Xl>(resultType, args);
1843+
case 16:
1844+
// vec_xlh8
1845+
return genVecLdNoCallGrp<VecOp::Xl>(resultType, args);
1846+
case 32:
1847+
// vec_xlw4
1848+
return genVecLdCallGrp<VecOp::Xlw4>(resultType, args);
1849+
case 64:
1850+
// vec_xld2
1851+
return genVecLdCallGrp<VecOp::Xld2>(resultType, args);
1852+
default:
1853+
llvm_unreachable("invalid kind");
1854+
}
1855+
llvm_unreachable("invalid vector operation for generator");
1856+
}
1857+
1858+
template <VecOp vop>
1859+
fir::ExtendedValue PPCIntrinsicLibrary::genVecLdNoCallGrp(
1860+
mlir::Type resultType, llvm::ArrayRef<fir::ExtendedValue> args) {
1861+
assert(args.size() == 2);
1862+
auto arg0{getBase(args[0])};
1863+
auto arg1{getBase(args[1])};
1864+
1865+
auto vecTyInfo{getVecTypeFromFirType(resultType)};
1866+
auto mlirTy{vecTyInfo.toMlirVectorType(builder.getContext())};
1867+
auto firTy{vecTyInfo.toFirVectorType()};
1868+
1869+
// Add the %val of arg0 to %addr of arg1
1870+
auto addr{addOffsetToAddress(builder, loc, arg1, arg0)};
1871+
1872+
const auto triple{fir::getTargetTriple(builder.getModule())};
1873+
// Need to get align 1.
1874+
auto result{builder.create<fir::LoadOp>(loc, mlirTy, addr,
1875+
getAlignmentAttr(builder, 1))};
1876+
if ((vop == VecOp::Xl && isBEVecElemOrderOnLE()) ||
1877+
(vop == VecOp::Xlbe && triple.isLittleEndian()))
1878+
return builder.createConvert(
1879+
loc, firTy, reverseVectorElements(builder, loc, result, vecTyInfo.len));
1880+
1881+
return builder.createConvert(loc, firTy, result);
1882+
}
1883+
18001884
// VEC_LD, VEC_LDE, VEC_LDL, VEC_LXVP, VEC_XLD2, VEC_XLW4
18011885
template <VecOp vop>
18021886
fir::ExtendedValue
@@ -1897,6 +1981,58 @@ PPCIntrinsicLibrary::genVecLdCallGrp(mlir::Type resultType,
18971981
return builder.createConvert(loc, firTy, result);
18981982
}
18991983

1984+
// VEC_LVSL, VEC_LVSR
1985+
template <VecOp vop>
1986+
fir::ExtendedValue
1987+
PPCIntrinsicLibrary::genVecLvsGrp(mlir::Type resultType,
1988+
llvm::ArrayRef<fir::ExtendedValue> args) {
1989+
assert(args.size() == 2);
1990+
auto context{builder.getContext()};
1991+
auto arg0{getBase(args[0])};
1992+
auto arg1{getBase(args[1])};
1993+
1994+
auto vecTyInfo{getVecTypeFromFirType(resultType)};
1995+
auto mlirTy{vecTyInfo.toMlirVectorType(context)};
1996+
auto firTy{vecTyInfo.toFirVectorType()};
1997+
1998+
// Convert arg0 to i64 type if needed
1999+
auto i64ty{mlir::IntegerType::get(context, 64)};
2000+
if (arg0.getType() != i64ty)
2001+
arg0 = builder.create<fir::ConvertOp>(loc, i64ty, arg0);
2002+
2003+
// offset is modulo 16, so shift left 56 bits and then right 56 bits to clear
2004+
// upper 56 bit while preserving sign
2005+
auto shiftVal{builder.createIntegerConstant(loc, i64ty, 56)};
2006+
auto offset{builder.create<mlir::arith::ShLIOp>(loc, arg0, shiftVal)};
2007+
auto offset2{builder.create<mlir::arith::ShRSIOp>(loc, offset, shiftVal)};
2008+
2009+
// Add the offsetArg to %addr of arg1
2010+
auto addr{addOffsetToAddress(builder, loc, arg1, offset2)};
2011+
llvm::SmallVector<mlir::Value, 4> parsedArgs{addr};
2012+
2013+
llvm::StringRef fname{};
2014+
switch (vop) {
2015+
case VecOp::Lvsl:
2016+
fname = "llvm.ppc.altivec.lvsl";
2017+
break;
2018+
case VecOp::Lvsr:
2019+
fname = "llvm.ppc.altivec.lvsr";
2020+
break;
2021+
default:
2022+
llvm_unreachable("invalid vector operation for generator");
2023+
}
2024+
auto funcType{mlir::FunctionType::get(context, {addr.getType()}, {mlirTy})};
2025+
auto funcOp{builder.addNamedFunction(loc, fname, funcType)};
2026+
auto result{
2027+
builder.create<fir::CallOp>(loc, funcOp, parsedArgs).getResult(0)};
2028+
2029+
if (isNativeVecElemOrderOnLE())
2030+
return builder.createConvert(
2031+
loc, firTy, reverseVectorElements(builder, loc, result, vecTyInfo.len));
2032+
2033+
return builder.createConvert(loc, firTy, result);
2034+
}
2035+
19002036
// VEC_NMADD, VEC_MSUB
19012037
template <VecOp vop>
19022038
fir::ExtendedValue
@@ -2281,6 +2417,38 @@ PPCIntrinsicLibrary::genVecSplat(mlir::Type resultType,
22812417
return builder.createConvert(loc, retTy, splatOp);
22822418
}
22832419

2420+
fir::ExtendedValue
2421+
PPCIntrinsicLibrary::genVecXlds(mlir::Type resultType,
2422+
llvm::ArrayRef<fir::ExtendedValue> args) {
2423+
assert(args.size() == 2);
2424+
auto arg0{getBase(args[0])};
2425+
auto arg1{getBase(args[1])};
2426+
2427+
// Prepare the return type in FIR.
2428+
auto vecTyInfo{getVecTypeFromFirType(resultType)};
2429+
auto mlirTy{vecTyInfo.toMlirVectorType(builder.getContext())};
2430+
auto firTy{vecTyInfo.toFirVectorType()};
2431+
2432+
// Add the %val of arg0 to %addr of arg1
2433+
auto addr{addOffsetToAddress(builder, loc, arg1, arg0)};
2434+
2435+
auto i64Ty{mlir::IntegerType::get(builder.getContext(), 64)};
2436+
auto i64VecTy{mlir::VectorType::get(2, i64Ty)};
2437+
auto i64RefTy{builder.getRefType(i64Ty)};
2438+
auto addrConv{builder.create<fir::ConvertOp>(loc, i64RefTy, addr)};
2439+
2440+
auto addrVal{builder.create<fir::LoadOp>(loc, addrConv)};
2441+
auto splatRes{builder.create<mlir::vector::SplatOp>(loc, addrVal, i64VecTy)};
2442+
2443+
mlir::Value result{nullptr};
2444+
if (mlirTy != splatRes.getType()) {
2445+
result = builder.create<mlir::vector::BitCastOp>(loc, mlirTy, splatRes);
2446+
} else
2447+
result = splatRes;
2448+
2449+
return builder.createConvert(loc, firTy, result);
2450+
}
2451+
22842452
const char *getMmaIrIntrName(MMAOp mmaOp) {
22852453
switch (mmaOp) {
22862454
case MMAOp::AssembleAcc:
@@ -2755,13 +2923,6 @@ void PPCIntrinsicLibrary::genVecStore(llvm::ArrayRef<fir::ExtendedValue> args) {
27552923
builder.create<fir::CallOp>(loc, funcOp, biArgs);
27562924
}
27572925

2758-
static mlir::NamedAttribute getAlignmentAttr(fir::FirOpBuilder &builder,
2759-
const int val) {
2760-
auto i64ty{mlir::IntegerType::get(builder.getContext(), 64)};
2761-
auto alignAttr{mlir::IntegerAttr::get(i64ty, val)};
2762-
return builder.getNamedAttr("alignment", alignAttr);
2763-
}
2764-
27652926
// VEC_XST, VEC_XST_BE, VEC_STXV, VEC_XSTD2, VEC_XSTW4
27662927
template <VecOp vop>
27672928
void PPCIntrinsicLibrary::genVecXStore(

0 commit comments

Comments
 (0)