@@ -1963,7 +1963,7 @@ ARMTTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
19631963 LT.second .getScalarSizeInBits () == MTy.getScalarSizeInBits ())
19641964 return LT.first * ST->getMVEVectorCostFactor (CostKind);
19651965
1966- // Otherwise we use a legal convert followed by a min+max
1966+ // If we can we use a legal convert followed by a min+max
19671967 if (((ST->hasVFP2Base () && LT.second == MVT::f32 ) ||
19681968 (ST->hasFP64 () && LT.second == MVT::f64 ) ||
19691969 (ST->hasFullFP16 () && LT.second == MVT::f16 ) ||
@@ -1984,7 +1984,25 @@ ARMTTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
19841984 Cost += getIntrinsicInstrCost (Attrs2, CostKind);
19851985 return LT.first * Cost;
19861986 }
1987- break ;
1987+ // Otherwise we need to follow the default expansion that clamps the value
1988+ // using a float min/max with a fcmp+sel for nan handling when signed.
1989+ Type *FPTy = ICA.getArgTypes ()[0 ];
1990+ Type *RetTy = ICA.getReturnType ();
1991+ IntrinsicCostAttributes Attrs1 (Intrinsic::minnum, FPTy, {FPTy, FPTy});
1992+ InstructionCost Cost = getIntrinsicInstrCost (Attrs1, CostKind);
1993+ IntrinsicCostAttributes Attrs2 (Intrinsic::maxnum, FPTy, {FPTy, FPTy});
1994+ Cost += getIntrinsicInstrCost (Attrs2, CostKind);
1995+ Cost +=
1996+ getCastInstrCost (IsSigned ? Instruction::FPToSI : Instruction::FPToUI,
1997+ RetTy, FPTy, TTI::CastContextHint::None, CostKind);
1998+ if (IsSigned) {
1999+ Type *CondTy = RetTy->getWithNewBitWidth (1 );
2000+ Cost += getCmpSelInstrCost (BinaryOperator::FCmp, FPTy, CondTy,
2001+ CmpInst::FCMP_UNO, CostKind);
2002+ Cost += getCmpSelInstrCost (BinaryOperator::Select, RetTy, CondTy,
2003+ CmpInst::FCMP_UNO, CostKind);
2004+ }
2005+ return Cost;
19882006 }
19892007 }
19902008
0 commit comments