22
22
#include " llvm/ADT/SmallVector.h"
23
23
#include " llvm/Analysis/LoopInfo.h"
24
24
#include " llvm/Analysis/OptimizationRemarkEmitter.h"
25
+ #include " llvm/Analysis/TargetLibraryInfo.h"
25
26
#include " llvm/Analysis/TargetTransformInfo.h"
26
27
#include " llvm/Analysis/TargetTransformInfoImpl.h"
27
28
#include " llvm/Analysis/ValueTracking.h"
@@ -1725,9 +1726,9 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
1725
1726
1726
1727
Type *RetTy = ICA.getReturnType ();
1727
1728
1728
- ElementCount RetVF =
1729
- (RetTy-> isVectorTy () ? cast<VectorType>(RetTy)-> getElementCount ()
1730
- : ElementCount::getFixed ( 1 ));
1729
+ ElementCount RetVF = isVectorizedTy (RetTy) ? getVectorizedTypeVF (RetTy)
1730
+ : ElementCount::getFixed ( 1 );
1731
+
1731
1732
const IntrinsicInst *I = ICA.getInst ();
1732
1733
const SmallVectorImpl<const Value *> &Args = ICA.getArgs ();
1733
1734
FastMathFlags FMF = ICA.getFlags ();
@@ -1995,6 +1996,49 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
1995
1996
}
1996
1997
case Intrinsic::experimental_vector_match:
1997
1998
return thisT ()->getTypeBasedIntrinsicInstrCost (ICA, CostKind);
1999
+ case Intrinsic::sincos: {
2000
+ // Vector variants of llvm.sincos can be mapped to a vector library call.
2001
+ auto const *LibInfo = ICA.getLibInfo ();
2002
+ if (!LibInfo || !isVectorizedTy (RetTy))
2003
+ break ;
2004
+
2005
+ // Find associated libcall.
2006
+ VectorType *VectorTy = cast<VectorType>(getContainedTypes (RetTy).front ());
2007
+ EVT VT = getTLI ()->getValueType (DL, VectorTy);
2008
+ RTLIB::Libcall LC = RTLIB::getFSINCOS (VT.getVectorElementType ());
2009
+ const char *LCName = getTLI ()->getLibcallName (LC);
2010
+ if (!LC || !LCName)
2011
+ break ;
2012
+
2013
+ // Search for a corresponding vector variant.
2014
+ LLVMContext &Ctx = RetTy->getContext ();
2015
+ auto VF = getVectorizedTypeVF (RetTy);
2016
+ VecDesc const *VD = nullptr ;
2017
+ for (bool Masked : {false , true }) {
2018
+ if ((VD = LibInfo->getVectorMappingInfo (LCName, VF, Masked)))
2019
+ break ;
2020
+ }
2021
+ if (!VD)
2022
+ break ;
2023
+
2024
+ // Cost the call + mask.
2025
+ auto Cost = thisT ()->getCallInstrCost (nullptr , RetTy, ICA.getArgTypes (),
2026
+ CostKind);
2027
+ if (VD->isMasked ())
2028
+ Cost += thisT ()->getShuffleCost (
2029
+ TargetTransformInfo::SK_Broadcast,
2030
+ VectorType::get (IntegerType::getInt1Ty (Ctx), VF), {}, CostKind, 0 ,
2031
+ nullptr , {});
2032
+
2033
+ // Lowering to a sincos library call (with output pointers) may require us
2034
+ // to emit reloads for the results.
2035
+ Cost +=
2036
+ thisT ()->getMemoryOpCost (
2037
+ Instruction::Load, VectorTy,
2038
+ thisT ()->getDataLayout ().getABITypeAlign (VectorTy), 0 , CostKind) *
2039
+ 2 ;
2040
+ return Cost;
2041
+ }
1998
2042
}
1999
2043
2000
2044
// Assume that we need to scalarize this intrinsic.)
@@ -2003,10 +2047,13 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
2003
2047
InstructionCost ScalarizationCost = InstructionCost::getInvalid ();
2004
2048
if (RetVF.isVector () && !RetVF.isScalable ()) {
2005
2049
ScalarizationCost = 0 ;
2006
- if (!RetTy->isVoidTy ())
2007
- ScalarizationCost += getScalarizationOverhead (
2008
- cast<VectorType>(RetTy),
2009
- /* Insert*/ true , /* Extract*/ false , CostKind);
2050
+ if (!RetTy->isVoidTy ()) {
2051
+ for (Type *VectorTy : getContainedTypes (RetTy)) {
2052
+ ScalarizationCost += getScalarizationOverhead (
2053
+ cast<VectorType>(VectorTy),
2054
+ /* Insert*/ true , /* Extract*/ false , CostKind);
2055
+ }
2056
+ }
2010
2057
ScalarizationCost +=
2011
2058
getOperandsScalarizationOverhead (Args, ICA.getArgTypes (), CostKind);
2012
2059
}
@@ -2678,27 +2725,32 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
2678
2725
// Else, assume that we need to scalarize this intrinsic. For math builtins
2679
2726
// this will emit a costly libcall, adding call overhead and spills. Make it
2680
2727
// very expensive.
2681
- if (auto *RetVTy = dyn_cast<VectorType>(RetTy)) {
2728
+ if (isVectorizedTy (RetTy)) {
2729
+ ArrayRef<Type *> RetVTys = getContainedTypes (RetTy);
2730
+
2682
2731
// Scalable vectors cannot be scalarized, so return Invalid.
2683
- if (isa<ScalableVectorType>(RetTy) || any_of (Tys, [](const Type *Ty) {
2684
- return isa<ScalableVectorType>(Ty);
2685
- }))
2732
+ if (any_of (concat<Type *const >(RetVTys, Tys),
2733
+ [](Type *Ty) { return isa<ScalableVectorType>(Ty); }))
2686
2734
return InstructionCost::getInvalid ();
2687
2735
2688
- InstructionCost ScalarizationCost =
2689
- SkipScalarizationCost
2690
- ? ScalarizationCostPassed
2691
- : getScalarizationOverhead (RetVTy, /* Insert*/ true ,
2692
- /* Extract*/ false , CostKind);
2736
+ InstructionCost ScalarizationCost = ScalarizationCostPassed;
2737
+ if (!SkipScalarizationCost) {
2738
+ ScalarizationCost = 0 ;
2739
+ for (Type *RetVTy : RetVTys) {
2740
+ ScalarizationCost += getScalarizationOverhead (
2741
+ cast<VectorType>(RetVTy), /* Insert*/ true ,
2742
+ /* Extract*/ false , CostKind);
2743
+ }
2744
+ }
2693
2745
2694
- unsigned ScalarCalls = cast<FixedVectorType>(RetVTy)-> getNumElements ();
2746
+ unsigned ScalarCalls = getVectorizedTypeVF (RetTy). getFixedValue ();
2695
2747
SmallVector<Type *, 4 > ScalarTys;
2696
2748
for (Type *Ty : Tys) {
2697
2749
if (Ty->isVectorTy ())
2698
2750
Ty = Ty->getScalarType ();
2699
2751
ScalarTys.push_back (Ty);
2700
2752
}
2701
- IntrinsicCostAttributes Attrs (IID, RetTy-> getScalarType ( ), ScalarTys, FMF);
2753
+ IntrinsicCostAttributes Attrs (IID, toScalarizedTy (RetTy ), ScalarTys, FMF);
2702
2754
InstructionCost ScalarCost =
2703
2755
thisT ()->getIntrinsicInstrCost (Attrs, CostKind);
2704
2756
for (Type *Ty : Tys) {
0 commit comments