diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2016-10-31 12:10:53 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2016-10-31 12:10:53 +0000 |
commit | d07c731d86d15d52bc3b8be028393cb11a76374a (patch) | |
tree | a936a1236238864eb539320e27ae5c2fc5381d7a /llvm/lib/Target/X86/X86TargetTransformInfo.cpp | |
parent | 0d26eea60965d5c061f386567d2af26c5b386210 (diff) | |
download | bcm5719-llvm-d07c731d86d15d52bc3b8be028393cb11a76374a.tar.gz bcm5719-llvm-d07c731d86d15d52bc3b8be028393cb11a76374a.zip |
Improved cost model for FDIV and FSQRT, by Andrew Tischenko
There is a bug describing poor cost model for floating point operations:
Bug 29083 - [X86][SSE] Improve costs for floating point operations. This
patch is the second one in series of patches dealing with cost model.
Differential Revision: https://reviews.llvm.org/D25722
llvm-svn: 285564
Diffstat (limited to 'llvm/lib/Target/X86/X86TargetTransformInfo.cpp')
-rw-r--r-- | llvm/lib/Target/X86/X86TargetTransformInfo.cpp | 76 |
1 files changed, 74 insertions, 2 deletions
diff --git a/llvm/lib/Target/X86/X86TargetTransformInfo.cpp b/llvm/lib/Target/X86/X86TargetTransformInfo.cpp index d115eb29745..afa8e00b2f7 100644 --- a/llvm/lib/Target/X86/X86TargetTransformInfo.cpp +++ b/llvm/lib/Target/X86/X86TargetTransformInfo.cpp @@ -324,6 +324,12 @@ int X86TTIImpl::getArithmeticInstrCost( { ISD::SRA, MVT::v16i16, 10 }, // extend/vpsravd/pack sequence. { ISD::SRA, MVT::v2i64, 4 }, // srl/xor/sub sequence. { ISD::SRA, MVT::v4i64, 4 }, // srl/xor/sub sequence. + { ISD::FDIV, MVT::f32, 7 }, // Haswell from http://www.agner.org/ + { ISD::FDIV, MVT::v4f32, 7 }, // Haswell from http://www.agner.org/ + { ISD::FDIV, MVT::v8f32, 14 }, // Haswell from http://www.agner.org/ + { ISD::FDIV, MVT::f64, 14 }, // Haswell from http://www.agner.org/ + { ISD::FDIV, MVT::v2f64, 14 }, // Haswell from http://www.agner.org/ + { ISD::FDIV, MVT::v4f64, 28 }, // Haswell from http://www.agner.org/ }; // Look for AVX2 lowering tricks for custom cases. @@ -334,6 +340,12 @@ int X86TTIImpl::getArithmeticInstrCost( } static const CostTblEntry AVXCustomCostTable[] = { + { ISD::FDIV, MVT::f32, 14 }, // SNB from http://www.agner.org/ + { ISD::FDIV, MVT::v4f32, 14 }, // SNB from http://www.agner.org/ + { ISD::FDIV, MVT::v8f32, 28 }, // SNB from http://www.agner.org/ + { ISD::FDIV, MVT::f64, 22 }, // SNB from http://www.agner.org/ + { ISD::FDIV, MVT::v2f64, 22 }, // SNB from http://www.agner.org/ + { ISD::FDIV, MVT::v4f64, 44 }, // SNB from http://www.agner.org/ // Vectorizing division is a bad idea. See the SSE2 table for more comments. { ISD::SDIV, MVT::v32i8, 32*20 }, { ISD::SDIV, MVT::v16i16, 16*20 }, @@ -352,6 +364,19 @@ int X86TTIImpl::getArithmeticInstrCost( return LT.first * Entry->Cost; } + static const CostTblEntry SSE42FloatCostTable[] = { + { ISD::FDIV, MVT::f32, 14 }, // Nehalem from http://www.agner.org/ + { ISD::FDIV, MVT::v4f32, 14 }, // Nehalem from http://www.agner.org/ + { ISD::FDIV, MVT::f64, 22 }, // Nehalem from http://www.agner.org/ + { ISD::FDIV, MVT::v2f64, 22 }, // Nehalem from http://www.agner.org/ + }; + + if (ST->hasSSE42()) { + if (const auto *Entry = CostTableLookup(SSE42FloatCostTable, ISD, + LT.second)) + return LT.first * Entry->Cost; + } + static const CostTblEntry SSE2UniformCostTable[] = { // Uniform splats are cheaper for the following instructions. @@ -469,6 +494,11 @@ int X86TTIImpl::getArithmeticInstrCost( { ISD::SRA, MVT::v2i64, 12 }, // srl/xor/sub sequence. { ISD::SRA, MVT::v4i64, 2*12 }, // srl/xor/sub sequence. + { ISD::FDIV, MVT::f32, 23 }, // Pentium IV from http://www.agner.org/ + { ISD::FDIV, MVT::v4f32, 39 }, // Pentium IV from http://www.agner.org/ + { ISD::FDIV, MVT::f64, 38 }, // Pentium IV from http://www.agner.org/ + { ISD::FDIV, MVT::v2f64, 69 }, // Pentium IV from http://www.agner.org/ + // It is not a good idea to vectorize division. We have to scalarize it and // in the process we will often end up having to spilling regular // registers. The overhead of division is going to dominate most kernels @@ -533,6 +563,15 @@ int X86TTIImpl::getArithmeticInstrCost( !ST->hasSSE41()) return LT.first * 6; + static const CostTblEntry SSE1FloatCostTable[] = { + { ISD::FDIV, MVT::f32, 17 }, // Pentium III from http://www.agner.org/ + { ISD::FDIV, MVT::v4f32, 34 }, // Pentium III from http://www.agner.org/ + }; + + if (ST->hasSSE1()) + if (const auto *Entry = CostTableLookup(SSE1FloatCostTable, ISD, + LT.second)) + return LT.first * Entry->Cost; // Fallback to the default implementation. return BaseT::getArithmeticInstrCost(Opcode, Ty, Op1Info, Op2Info); } @@ -1111,7 +1150,13 @@ int X86TTIImpl::getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy, { ISD::CTTZ, MVT::v4i64, 10 }, { ISD::CTTZ, MVT::v8i32, 14 }, { ISD::CTTZ, MVT::v16i16, 12 }, - { ISD::CTTZ, MVT::v32i8, 9 } + { ISD::CTTZ, MVT::v32i8, 9 }, + { ISD::FSQRT, MVT::f32, 7 }, // Haswell from http://www.agner.org/ + { ISD::FSQRT, MVT::v4f32, 7 }, // Haswell from http://www.agner.org/ + { ISD::FSQRT, MVT::v8f32, 14 }, // Haswell from http://www.agner.org/ + { ISD::FSQRT, MVT::f64, 14 }, // Haswell from http://www.agner.org/ + { ISD::FSQRT, MVT::v2f64, 14 }, // Haswell from http://www.agner.org/ + { ISD::FSQRT, MVT::v4f64, 28 }, // Haswell from http://www.agner.org/ }; static const CostTblEntry AVX1CostTbl[] = { { ISD::BITREVERSE, MVT::v4i64, 10 }, @@ -1133,6 +1178,16 @@ int X86TTIImpl::getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy, { ISD::CTTZ, MVT::v8i32, 28 }, { ISD::CTTZ, MVT::v16i16, 24 }, { ISD::CTTZ, MVT::v32i8, 18 }, + { ISD::FSQRT, MVT::f32, 14 }, // SNB from http://www.agner.org/ + { ISD::FSQRT, MVT::v4f32, 14 }, // SNB from http://www.agner.org/ + { ISD::FSQRT, MVT::v8f32, 28 }, // SNB from http://www.agner.org/ + { ISD::FSQRT, MVT::f64, 21 }, // SNB from http://www.agner.org/ + { ISD::FSQRT, MVT::v2f64, 21 }, // SNB from http://www.agner.org/ + { ISD::FSQRT, MVT::v4f64, 43 }, // SNB from http://www.agner.org/ + }; + static const CostTblEntry SSE42CostTbl[] = { + { ISD::FSQRT, MVT::f32, 18 }, // Nehalem from http://www.agner.org/ + { ISD::FSQRT, MVT::v4f32, 18 }, // Nehalem from http://www.agner.org/ }; static const CostTblEntry SSSE3CostTbl[] = { { ISD::BITREVERSE, MVT::v2i64, 5 }, @@ -1167,7 +1222,13 @@ int X86TTIImpl::getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy, { ISD::CTTZ, MVT::v2i64, 14 }, { ISD::CTTZ, MVT::v4i32, 18 }, { ISD::CTTZ, MVT::v8i16, 16 }, - { ISD::CTTZ, MVT::v16i8, 13 } + { ISD::CTTZ, MVT::v16i8, 13 }, + { ISD::FSQRT, MVT::f64, 32 }, // Nehalem from http://www.agner.org/ + { ISD::FSQRT, MVT::v2f64, 32 }, // Nehalem from http://www.agner.org/ + }; + static const CostTblEntry SSE1CostTbl[] = { + { ISD::FSQRT, MVT::f32, 28 }, // Pentium III from http://www.agner.org/ + { ISD::FSQRT, MVT::v4f32, 56 }, // Pentium III from http://www.agner.org/ }; unsigned ISD = ISD::DELETED_NODE; @@ -1189,6 +1250,9 @@ int X86TTIImpl::getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy, case Intrinsic::cttz: ISD = ISD::CTTZ; break; + case Intrinsic::sqrt: + ISD = ISD::FSQRT; + break; } // Legalize the type. @@ -1208,6 +1272,10 @@ int X86TTIImpl::getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy, if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy)) return LT.first * Entry->Cost; + if (ST->hasSSE42()) + if (const auto *Entry = CostTableLookup(SSE42CostTbl, ISD, MTy)) + return LT.first * Entry->Cost; + if (ST->hasSSSE3()) if (const auto *Entry = CostTableLookup(SSSE3CostTbl, ISD, MTy)) return LT.first * Entry->Cost; @@ -1216,6 +1284,10 @@ int X86TTIImpl::getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy, if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy)) return LT.first * Entry->Cost; + if (ST->hasSSE1()) + if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy)) + return LT.first * Entry->Cost; + return BaseT::getIntrinsicInstrCost(IID, RetTy, Tys, FMF); } |