@@ -589,6 +589,21 @@ static constexpr IntrinsicHandler ppcHandlers[]{
589
589
&PI::genVecLdCallGrp<VecOp::Ldl>),
590
590
{{{" arg1" , asValue}, {" arg2" , asAddr}}},
591
591
/* 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 },
592
607
{" __ppc_vec_lxvp" ,
593
608
static_cast <IntrinsicLibrary::ExtendedGenerator>(
594
609
&PI::genVecLdCallGrp<VecOp::Lxvp>),
@@ -713,11 +728,24 @@ static constexpr IntrinsicHandler ppcHandlers[]{
713
728
&PI::genVecAddAndMulSubXor<VecOp::Sub>),
714
729
{{{" arg1" , asValue}, {" arg2" , asValue}}},
715
730
/* 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 },
716
740
{" __ppc_vec_xld2_" ,
717
741
static_cast <IntrinsicLibrary::ExtendedGenerator>(
718
742
&PI::genVecLdCallGrp<VecOp::Xld2>),
719
743
{{{" arg1" , asValue}, {" arg2" , asAddr}}},
720
744
/* isElemental=*/ false },
745
+ {" __ppc_vec_xlds" ,
746
+ static_cast <IntrinsicLibrary::ExtendedGenerator>(&PI::genVecXlds),
747
+ {{{" arg1" , asValue}, {" arg2" , asAddr}}},
748
+ /* isElemental=*/ false },
721
749
{" __ppc_vec_xlw4_" ,
722
750
static_cast <IntrinsicLibrary::ExtendedGenerator>(
723
751
&PI::genVecLdCallGrp<VecOp::Xlw4>),
@@ -1797,6 +1825,62 @@ static mlir::Value reverseVectorElements(fir::FirOpBuilder &builder,
1797
1825
return builder.create <mlir::vector::ShuffleOp>(loc, v, undefVec, mask);
1798
1826
}
1799
1827
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
+
1800
1884
// VEC_LD, VEC_LDE, VEC_LDL, VEC_LXVP, VEC_XLD2, VEC_XLW4
1801
1885
template <VecOp vop>
1802
1886
fir::ExtendedValue
@@ -1897,6 +1981,58 @@ PPCIntrinsicLibrary::genVecLdCallGrp(mlir::Type resultType,
1897
1981
return builder.createConvert (loc, firTy, result);
1898
1982
}
1899
1983
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
+
1900
2036
// VEC_NMADD, VEC_MSUB
1901
2037
template <VecOp vop>
1902
2038
fir::ExtendedValue
@@ -2281,6 +2417,38 @@ PPCIntrinsicLibrary::genVecSplat(mlir::Type resultType,
2281
2417
return builder.createConvert (loc, retTy, splatOp);
2282
2418
}
2283
2419
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
+
2284
2452
const char *getMmaIrIntrName (MMAOp mmaOp) {
2285
2453
switch (mmaOp) {
2286
2454
case MMAOp::AssembleAcc:
@@ -2755,13 +2923,6 @@ void PPCIntrinsicLibrary::genVecStore(llvm::ArrayRef<fir::ExtendedValue> args) {
2755
2923
builder.create <fir::CallOp>(loc, funcOp, biArgs);
2756
2924
}
2757
2925
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
-
2765
2926
// VEC_XST, VEC_XST_BE, VEC_STXV, VEC_XSTD2, VEC_XSTW4
2766
2927
template <VecOp vop>
2767
2928
void PPCIntrinsicLibrary::genVecXStore (
0 commit comments