diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h --- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h +++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h @@ -1135,6 +1135,11 @@ if (BaseT::getIntrinsicInstrCost(ICA, CostKind) == 0) return 0; + // Assume that target intrinsics are cheap. + Intrinsic::ID IID = ICA.getID(); + if (Function::isTargetIntrinsic(IID)) + return TargetTransformInfo::TCC_Basic; + if (ICA.isTypeBasedOnly()) return getTypeBasedIntrinsicInstrCost(ICA, CostKind); @@ -1151,7 +1156,6 @@ const IntrinsicInst *I = ICA.getInst(); const SmallVectorImpl &Args = ICA.getArgs(); FastMathFlags FMF = ICA.getFlags(); - Intrinsic::ID IID = ICA.getID(); switch (IID) { default: // FIXME: all cost kinds should default to the same thing? diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -199,6 +199,10 @@ /// returns Intrinsic::not_intrinsic! bool isIntrinsic() const { return HasLLVMReservedName; } + /// isTargetIntrinsic - Returns true if IID is an intrinsic specific to a + /// certain target. If it is a generic intrinsic false is returned. + static bool isTargetIntrinsic(Intrinsic::ID IID); + /// isTargetIntrinsic - Returns true if this function is an intrinsic and the /// intrinsic is specific to a certain target. If this is not an intrinsic /// or a generic intrinsic, false is returned. diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -640,8 +640,12 @@ #include "llvm/IR/IntrinsicImpl.inc" #undef GET_INTRINSIC_TARGET_DATA +bool Function::isTargetIntrinsic(Intrinsic::ID IID) { + return IID > TargetInfos[0].Count; +} + bool Function::isTargetIntrinsic() const { - return IntID > TargetInfos[0].Count; + return isTargetIntrinsic(IntID); } /// Find the segment of \c IntrinsicNameTable for intrinsics with the same diff --git a/llvm/test/Analysis/CostModel/ARM/target-intrinsics.ll b/llvm/test/Analysis/CostModel/ARM/target-intrinsics.ll --- a/llvm/test/Analysis/CostModel/ARM/target-intrinsics.ll +++ b/llvm/test/Analysis/CostModel/ARM/target-intrinsics.ll @@ -9,7 +9,7 @@ ; CHECK-THUMB2-RECIP-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %t1 = call i32 @llvm.arm.ssat(i32 undef, i32 undef) ; CHECK-THUMB2-RECIP-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %t2 = tail call { <8 x half>, <8 x half> } @llvm.arm.mve.vld2q.v8f16.p0f16(half* undef) ; CHECK-THUMB2-RECIP-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %t3 = call { i32, i32 } @llvm.arm.mve.sqrshrl(i32 undef, i32 undef, i32 undef, i32 48) -; CHECK-THUMB2-RECIP-NEXT: Cost Model: Found an estimated cost of 135 for instruction: %t4 = tail call { i32, i32 } @llvm.arm.mve.vmlldava.v8i16(i32 0, i32 0, i32 0, i32 0, i32 0, <8 x i16> undef, <8 x i16> undef) +; CHECK-THUMB2-RECIP-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %t4 = tail call { i32, i32 } @llvm.arm.mve.vmlldava.v8i16(i32 0, i32 0, i32 0, i32 0, i32 0, <8 x i16> undef, <8 x i16> undef) ; CHECK-THUMB2-RECIP-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void ; ; CHECK-THUMB2-LAT-LABEL: 'intrinsics'