diff options
| author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2018-11-12 18:27:54 +0000 |
|---|---|---|
| committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2018-11-12 18:27:54 +0000 |
| commit | 93c64e5c76ab9fc29bb949102d2660dd5f600999 (patch) | |
| tree | 16199ffa49de8f6be2ae0fd8cf95e96b8ce520c7 /llvm/lib/Target | |
| parent | 054dc28afa225a3a7304f6e5bc3115986cdc65a9 (diff) | |
| download | bcm5719-llvm-93c64e5c76ab9fc29bb949102d2660dd5f600999.tar.gz bcm5719-llvm-93c64e5c76ab9fc29bb949102d2660dd5f600999.zip | |
[CostModel][X86] Add funnel shift rotation special case costs
When we repeat the 2 shifting operands then this is a bit rotation - annoyingly this has to be done in the other getIntrinsicInstrCost than most intrinsics as we need to check the operands are the same.
llvm-svn: 346688
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/X86/X86TargetTransformInfo.cpp | 83 |
1 files changed, 82 insertions, 1 deletions
diff --git a/llvm/lib/Target/X86/X86TargetTransformInfo.cpp b/llvm/lib/Target/X86/X86TargetTransformInfo.cpp index 6e25e701f3f..05bfbe51f96 100644 --- a/llvm/lib/Target/X86/X86TargetTransformInfo.cpp +++ b/llvm/lib/Target/X86/X86TargetTransformInfo.cpp @@ -1953,7 +1953,88 @@ int X86TTIImpl::getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy, } int X86TTIImpl::getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy, - ArrayRef<Value *> Args, FastMathFlags FMF, unsigned VF) { + ArrayRef<Value *> Args, FastMathFlags FMF, + unsigned VF) { + static const CostTblEntry AVX512CostTbl[] = { + { ISD::ROTL, MVT::v8i64, 1 }, + { ISD::ROTL, MVT::v4i64, 1 }, + { ISD::ROTL, MVT::v2i64, 1 }, + { ISD::ROTL, MVT::v16i32, 1 }, + { ISD::ROTL, MVT::v8i32, 1 }, + { ISD::ROTL, MVT::v4i32, 1 }, + { ISD::ROTR, MVT::v8i64, 1 }, + { ISD::ROTR, MVT::v4i64, 1 }, + { ISD::ROTR, MVT::v2i64, 1 }, + { ISD::ROTR, MVT::v16i32, 1 }, + { ISD::ROTR, MVT::v8i32, 1 }, + { ISD::ROTR, MVT::v4i32, 1 } + }; + // XOP: ROTL = VPROT(X,Y), ROTR = VPROT(SUB(0,X),Y) + static const CostTblEntry XOPCostTbl[] = { + { ISD::ROTL, MVT::v4i64, 4 }, + { ISD::ROTL, MVT::v8i32, 4 }, + { ISD::ROTL, MVT::v16i16, 4 }, + { ISD::ROTL, MVT::v32i8, 4 }, + { ISD::ROTL, MVT::v2i64, 1 }, + { ISD::ROTL, MVT::v4i32, 1 }, + { ISD::ROTL, MVT::v8i16, 1 }, + { ISD::ROTL, MVT::v16i8, 1 }, + { ISD::ROTR, MVT::v4i64, 6 }, + { ISD::ROTR, MVT::v8i32, 6 }, + { ISD::ROTR, MVT::v16i16, 6 }, + { ISD::ROTR, MVT::v32i8, 6 }, + { ISD::ROTR, MVT::v2i64, 2 }, + { ISD::ROTR, MVT::v4i32, 2 }, + { ISD::ROTR, MVT::v8i16, 2 }, + { ISD::ROTR, MVT::v16i8, 2 } + }; + static const CostTblEntry X64CostTbl[] = { // 64-bit targets + { ISD::ROTL, MVT::i64, 1 }, + { ISD::ROTR, MVT::i64, 1 } + }; + static const CostTblEntry X86CostTbl[] = { // 32 or 64-bit targets + { ISD::ROTL, MVT::i32, 1 }, + { ISD::ROTL, MVT::i16, 1 }, + { ISD::ROTL, MVT::i8, 1 }, + { ISD::ROTR, MVT::i32, 1 }, + { ISD::ROTR, MVT::i16, 1 }, + { ISD::ROTR, MVT::i8, 1 } + }; + + unsigned ISD = ISD::DELETED_NODE; + switch (IID) { + default: + break; + case Intrinsic::fshl: + if (Args[0] == Args[1]) + ISD = ISD::ROTL; + break; + case Intrinsic::fshr: + if (Args[0] == Args[1]) + ISD = ISD::ROTR; + break; + } + + // Legalize the type. + std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, RetTy); + MVT MTy = LT.second; + + // Attempt to lookup cost. + if (ST->hasAVX512()) + if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy)) + return LT.first * Entry->Cost; + + if (ST->hasXOP()) + if (const auto *Entry = CostTableLookup(XOPCostTbl, ISD, MTy)) + return LT.first * Entry->Cost; + + if (ST->is64Bit()) + if (const auto *Entry = CostTableLookup(X64CostTbl, ISD, MTy)) + return LT.first * Entry->Cost; + + if (const auto *Entry = CostTableLookup(X86CostTbl, ISD, MTy)) + return LT.first * Entry->Cost; + return BaseT::getIntrinsicInstrCost(IID, RetTy, Args, FMF, VF); } |

