Index: lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- lib/Bitcode/Reader/BitcodeReader.cpp +++ lib/Bitcode/Reader/BitcodeReader.cpp @@ -2646,6 +2646,7 @@ // Look for intrinsic functions which need to be upgraded at some point for (Function &F : *TheModule) { + MDLoader->upgradeThumbMode(F); MDLoader->upgradeDebugIntrinsics(F); Function *NewFn; if (UpgradeIntrinsicFunction(&F, NewFn)) Index: lib/Bitcode/Reader/MetadataLoader.h =================================================================== --- lib/Bitcode/Reader/MetadataLoader.h +++ lib/Bitcode/Reader/MetadataLoader.h @@ -82,6 +82,9 @@ /// Perform bitcode upgrades on llvm.dbg.* calls. void upgradeDebugIntrinsics(Function &F); + + /// Add thumb-mode target-feature for arm and thumb triples. + void upgradeThumbMode(Function &F); }; } Index: lib/Bitcode/Reader/MetadataLoader.cpp =================================================================== --- lib/Bitcode/Reader/MetadataLoader.cpp +++ lib/Bitcode/Reader/MetadataLoader.cpp @@ -588,6 +588,31 @@ unsigned size() const { return MetadataList.size(); } void shrinkTo(unsigned N) { MetadataList.shrinkTo(N); } void upgradeDebugIntrinsics(Function &F) { upgradeDeclareExpressions(F); } + + void upgradeThumbMode(Function &F) { + const Triple TT(TheModule.getTargetTriple()); + if (TT.getArch() != Triple::thumb && TT.getArch() != Triple::thumbeb && + TT.getArch() != Triple::arm && TT.getArch() != Triple::armeb) + return; + + std::string TargetFeatures = + F.getFnAttribute("target-features").getValueAsString(); + + // Check that the target features do not already contain the thumb-mode + // feature. + auto Start = TargetFeatures.find("thumb-mode"); + auto End = Start + std::string("thumb-mode").size(); + if (Start != std::string::npos && + (TargetFeatures[Start-1] == '-' || TargetFeatures[Start-1] == '+') && + (End == TargetFeatures.size() || TargetFeatures[End] == ',')) + return; + + bool isArm = TT.getArch() == Triple::arm || TT.getArch() == Triple::armeb; + TargetFeatures += TargetFeatures.empty() ? "" : ","; + TargetFeatures += isArm ? "-" : "+"; + TargetFeatures += "thumb-mode"; + F.addFnAttr("target-features", TargetFeatures); + } }; static Error error(const Twine &Message) { @@ -1911,3 +1936,7 @@ void MetadataLoader::upgradeDebugIntrinsics(Function &F) { return Pimpl->upgradeDebugIntrinsics(F); } + +void MetadataLoader::upgradeThumbMode(Function &F) { + return Pimpl->upgradeThumbMode(F); +} Index: test/Bitcode/thumb-mode-upgrade-arm.ll =================================================================== --- /dev/null +++ test/Bitcode/thumb-mode-upgrade-arm.ll @@ -0,0 +1,24 @@ +; RUN: llvm-dis -o - %s.bc | FileCheck %s + +target triple = "arm-apple-ios" + +define void @foo() #0 { + ret void +} +define void @zar() #1 { + ret void +} +define void @bar() { + ret void +} + +attributes #0 = { "target-features"="+thumb-mode" } +attributes #1 = { "target-features"="+thumb-mode,+vfp3" } + +; CHECK: void @foo() [[ThumbModeAttr1:#[0-7]]] +; CHECK: void @zar() [[ThumbModeAttr2:#[0-7]]] +; CHECK: void @bar() [[NoThumbModeAttr:#[0-7]]] + +; CHECK: attributes [[ThumbModeAttr1]] = { "target-features"="+thumb-mode" } +; CHECK: attributes [[ThumbModeAttr2]] = { "target-features"="+thumb-mode,+vfp3" } +; CHECK: attributes [[NoThumbModeAttr]] = { "target-features"="-thumb-mode" } Index: test/Bitcode/thumb-mode-upgrade-thumb.ll =================================================================== --- /dev/null +++ test/Bitcode/thumb-mode-upgrade-thumb.ll @@ -0,0 +1,24 @@ +; RUN: llvm-dis -o - %s.bc | FileCheck %s + +target triple = "thumb-apple-ios" + +define void @foo() #0 { + ret void +} +define void @zar() #1 { + ret void +} +define void @bar() { + ret void +} + +attributes #0 = { "target-features"="-thumb-mode" } +attributes #1 = { "target-features"="-thumb-mode,+vfp3" } + +; CHECK: void @foo() [[NoThumbModeAttr1:#[0-7]]] +; CHECK: void @zar() [[NoThumbModeAttr2:#[0-7]]] +; CHECK: void @bar() [[ThumbModeAttr:#[0-7]]] + +; CHECK: attributes [[NoThumbModeAttr1]] = { "target-features"="-thumb-mode" } +; CHECK: attributes [[NoThumbModeAttr2]] = { "target-features"="-thumb-mode,+vfp3" } +; CHECK: attributes [[ThumbModeAttr]] = { "target-features"="+thumb-mode" }