@@ -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
18011885template <VecOp vop>
18021886fir::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
19012037template <VecOp vop>
19022038fir::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+
22842452const 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
27662927template <VecOp vop>
27672928void PPCIntrinsicLibrary::genVecXStore (
0 commit comments