Index: include/llvm/Analysis/TargetTransformInfoImpl.h =================================================================== --- include/llvm/Analysis/TargetTransformInfoImpl.h +++ include/llvm/Analysis/TargetTransformInfoImpl.h @@ -197,7 +197,7 @@ // can take place in the future. if (F->isIntrinsic()) - return false; + return F->hasFnAttribute(Attribute::IntrinsicLoweredToCall); if (F->hasLocalLinkage() || !F->hasName()) return true; Index: include/llvm/Bitcode/LLVMBitCodes.h =================================================================== --- include/llvm/Bitcode/LLVMBitCodes.h +++ include/llvm/Bitcode/LLVMBitCodes.h @@ -589,6 +589,7 @@ ATTR_KIND_SANITIZE_HWADDRESS = 55, ATTR_KIND_NOCF_CHECK = 56, ATTR_KIND_OPT_FOR_FUZZING = 57, + ATTR_KIND_INTRINSIC_LOWERED_TO_CALL = 58, }; enum ComdatSelectionKindCodes { Index: include/llvm/IR/Attributes.td =================================================================== --- include/llvm/IR/Attributes.td +++ include/llvm/IR/Attributes.td @@ -61,6 +61,9 @@ /// Force argument to be passed in register. def InReg : EnumAttr<"inreg">; +/// Treat this function like an intrinsic that is lowered to a function call. +def IntrinsicLoweredToCall : EnumAttr<"intrinsic_lowered_to_call">; + /// Build jump-instruction tables and replace refs. def JumpTable : EnumAttr<"jumptable">; Index: include/llvm/IR/Intrinsics.td =================================================================== --- include/llvm/IR/Intrinsics.td +++ include/llvm/IR/Intrinsics.td @@ -111,6 +111,10 @@ // defined by the hasSideEffects property of the TableGen Instruction class. def IntrHasSideEffects : IntrinsicProperty; +// This property indicates that the associated intrinsic is lowered to a +// function call. +def IntrLoweredToCall : IntrinsicProperty; + //===----------------------------------------------------------------------===// // Types used by intrinsics. //===----------------------------------------------------------------------===// Index: lib/AsmParser/LLLexer.cpp =================================================================== --- lib/AsmParser/LLLexer.cpp +++ lib/AsmParser/LLLexer.cpp @@ -633,6 +633,7 @@ KEYWORD(inaccessiblemem_or_argmemonly); KEYWORD(inlinehint); KEYWORD(inreg); + KEYWORD(intrinsic_lowered_to_call); KEYWORD(jumptable); KEYWORD(minsize); KEYWORD(naked); Index: lib/AsmParser/LLParser.cpp =================================================================== --- lib/AsmParser/LLParser.cpp +++ lib/AsmParser/LLParser.cpp @@ -1120,6 +1120,9 @@ case lltok::kw_inaccessiblemem_or_argmemonly: B.addAttribute(Attribute::InaccessibleMemOrArgMemOnly); break; case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break; + case lltok::kw_intrinsic_lowered_to_call: + B.addAttribute(Attribute::IntrinsicLoweredToCall); + break; case lltok::kw_jumptable: B.addAttribute(Attribute::JumpTable); break; case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break; case lltok::kw_naked: B.addAttribute(Attribute::Naked); break; Index: lib/AsmParser/LLToken.h =================================================================== --- lib/AsmParser/LLToken.h +++ lib/AsmParser/LLToken.h @@ -184,6 +184,7 @@ kw_inaccessiblemem_or_argmemonly, kw_inlinehint, kw_inreg, + kw_intrinsic_lowered_to_call, kw_jumptable, kw_minsize, kw_naked, Index: lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- lib/Bitcode/Reader/BitcodeReader.cpp +++ lib/Bitcode/Reader/BitcodeReader.cpp @@ -1162,6 +1162,7 @@ case Attribute::SanitizeHWAddress: return 1ULL << 56; case Attribute::NoCfCheck: return 1ULL << 57; case Attribute::OptForFuzzing: return 1ULL << 58; + case Attribute::IntrinsicLoweredToCall: return 1ULL << 59; case Attribute::Dereferenceable: llvm_unreachable("dereferenceable attribute not supported in raw format"); break; @@ -1304,6 +1305,8 @@ return Attribute::InlineHint; case bitc::ATTR_KIND_IN_REG: return Attribute::InReg; + case bitc::ATTR_KIND_INTRINSIC_LOWERED_TO_CALL: + return Attribute::IntrinsicLoweredToCall; case bitc::ATTR_KIND_JUMP_TABLE: return Attribute::JumpTable; case bitc::ATTR_KIND_MIN_SIZE: Index: lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- lib/Bitcode/Writer/BitcodeWriter.cpp +++ lib/Bitcode/Writer/BitcodeWriter.cpp @@ -607,6 +607,8 @@ return bitc::ATTR_KIND_INLINE_HINT; case Attribute::InReg: return bitc::ATTR_KIND_IN_REG; + case Attribute::IntrinsicLoweredToCall: + return bitc::ATTR_KIND_INTRINSIC_LOWERED_TO_CALL; case Attribute::JumpTable: return bitc::ATTR_KIND_JUMP_TABLE; case Attribute::MinSize: Index: lib/IR/Attributes.cpp =================================================================== --- lib/IR/Attributes.cpp +++ lib/IR/Attributes.cpp @@ -270,6 +270,8 @@ return "inlinehint"; if (hasAttribute(Attribute::InReg)) return "inreg"; + if (hasAttribute(Attribute::IntrinsicLoweredToCall)) + return "intrinsic_lowered_to_call"; if (hasAttribute(Attribute::JumpTable)) return "jumptable"; if (hasAttribute(Attribute::MinSize)) Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -1438,6 +1438,7 @@ case Attribute::NoRecurse: case Attribute::InaccessibleMemOnly: case Attribute::InaccessibleMemOrArgMemOnly: + case Attribute::IntrinsicLoweredToCall: case Attribute::AllocSize: case Attribute::Speculatable: case Attribute::StrictFP: Index: lib/Transforms/Utils/CodeExtractor.cpp =================================================================== --- lib/Transforms/Utils/CodeExtractor.cpp +++ lib/Transforms/Utils/CodeExtractor.cpp @@ -649,6 +649,7 @@ case Attribute::InReg: case Attribute::InaccessibleMemOnly: case Attribute::InaccessibleMemOrArgMemOnly: + case Attribute::IntrinsicLoweredToCall: case Attribute::JumpTable: case Attribute::Naked: case Attribute::Nest: Index: test/Bitcode/attributes.ll =================================================================== --- test/Bitcode/attributes.ll +++ test/Bitcode/attributes.ll @@ -204,7 +204,7 @@ ; CHECK: define void @f34() { call void @nobuiltin() nobuiltin -; CHECK: call void @nobuiltin() #35 +; CHECK: call void @nobuiltin() #36 ret void; } @@ -345,6 +345,12 @@ ret void; } +; CHECK: define void @f59() #35 +define void @f59() intrinsic_lowered_to_call +{ + ret void; +} + ; CHECK: attributes #0 = { noreturn } ; CHECK: attributes #1 = { nounwind } ; CHECK: attributes #2 = { readnone } @@ -380,4 +386,5 @@ ; CHECK: attributes #32 = { writeonly } ; CHECK: attributes #33 = { speculatable } ; CHECK: attributes #34 = { sanitize_hwaddress } -; CHECK: attributes #35 = { nobuiltin } +; CHECK: attributes #35 = { intrinsic_lowered_to_call } +; CHECK: attributes #36 = { nobuiltin } Index: utils/TableGen/CodeGenIntrinsics.h =================================================================== --- utils/TableGen/CodeGenIntrinsics.h +++ utils/TableGen/CodeGenIntrinsics.h @@ -134,6 +134,9 @@ // True if the intrinsic is marked as speculatable. bool isSpeculatable; + /// True if the intrinsic is lowered to a function call. + bool isLoweredToCall; + enum ArgAttribute { NoCapture, Returned, ReadOnly, WriteOnly, ReadNone }; std::vector> ArgumentAttributes; Index: utils/TableGen/CodeGenTarget.cpp =================================================================== --- utils/TableGen/CodeGenTarget.cpp +++ utils/TableGen/CodeGenTarget.cpp @@ -534,6 +534,7 @@ isConvergent = false; isSpeculatable = false; hasSideEffects = false; + isLoweredToCall = false; if (DefName.size() <= 4 || std::string(DefName.begin(), DefName.begin() + 4) != "int_") @@ -680,6 +681,8 @@ isSpeculatable = true; else if (Property->getName() == "IntrHasSideEffects") hasSideEffects = true; + else if (Property->getName() == "IntrLoweredToCall") + isLoweredToCall = true; else if (Property->isSubClassOf("NoCapture")) { unsigned ArgNo = Property->getValueAsInt("ArgNo"); ArgumentAttributes.push_back(std::make_pair(ArgNo, NoCapture)); Index: utils/TableGen/IntrinsicEmitter.cpp =================================================================== --- utils/TableGen/IntrinsicEmitter.cpp +++ utils/TableGen/IntrinsicEmitter.cpp @@ -494,6 +494,9 @@ if (L->hasSideEffects != R->hasSideEffects) return R->hasSideEffects; + if (L->isLoweredToCall != R->isLoweredToCall) + return R->isLoweredToCall; + // Try to order by readonly/readnone attribute. CodeGenIntrinsic::ModRefBehavior LK = L->ModRef; CodeGenIntrinsic::ModRefBehavior RK = R->ModRef; @@ -650,6 +653,12 @@ OS << "Attribute::Speculatable"; addComma = true; } + if (intrinsic.isLoweredToCall) { + if (addComma) + OS << ","; + OS << "Attribute::IntrinsicLoweredToCall"; + addComma = true; + } switch (intrinsic.ModRef) { case CodeGenIntrinsic::NoMem: