diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -296,6 +296,10 @@ I->addAttribute(AttributeList::FunctionIndex, Attribute::StrictFP); } + void setDefaultOperandBundles(ArrayRef OpBundles) { + DefaultOperandBundles = OpBundles; + } + //===--------------------------------------------------------------------===// // RAII helpers. //===--------------------------------------------------------------------===// @@ -342,6 +346,25 @@ } }; + // RAII object that stores the current default operand bundles and restores + // them when the object is destroyed. + class OperandBundlesGuard { + IRBuilderBase &Builder; + ArrayRef DefaultOperandBundles; + + public: + OperandBundlesGuard(IRBuilderBase &B) + : Builder(B), DefaultOperandBundles(B.DefaultOperandBundles) {} + + OperandBundlesGuard(const OperandBundlesGuard &) = delete; + OperandBundlesGuard &operator=(const OperandBundlesGuard &) = delete; + + ~OperandBundlesGuard() { + Builder.DefaultOperandBundles = DefaultOperandBundles; + } + }; + + //===--------------------------------------------------------------------===// // Miscellaneous creation methods. //===--------------------------------------------------------------------===// diff --git a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h --- a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h +++ b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h @@ -50,7 +50,7 @@ /// optimal value to replace the instruction with or 0 if a more /// optimal form can't be found. /// The call must not be an indirect call. - Value *optimizeCall(CallInst *CI); + Value *optimizeCall(CallInst *CI, IRBuilderBase &B); private: Value *optimizeMemCpyChk(CallInst *CI, IRBuilderBase &B); @@ -151,7 +151,7 @@ /// other instructions that use the given instruction were modified /// and the given instruction is dead. /// The call must not be an indirect call. - Value *optimizeCall(CallInst *CI); + Value *optimizeCall(CallInst *CI, IRBuilderBase &B); private: // String and Memory Library Call Optimizations diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -2044,7 +2044,8 @@ // to fortified library functions (e.g. __memcpy_chk) that have the default // "don't know" as the objectsize. Anything else should be left alone. FortifiedLibCallSimplifier Simplifier(TLInfo, true); - if (Value *V = Simplifier.optimizeCall(CI)) { + IRBuilder<> Builder(CI); + if (Value *V = Simplifier.optimizeCall(CI, Builder)) { CI->replaceAllUsesWith(V); CI->eraseFromParent(); return true; diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -4273,7 +4273,7 @@ }; LibCallSimplifier Simplifier(DL, &TLI, ORE, BFI, PSI, InstCombineRAUW, InstCombineErase); - if (Value *With = Simplifier.optimizeCall(CI)) { + if (Value *With = Simplifier.optimizeCall(CI, Builder)) { ++NumSimplified; return CI->use_empty() ? CI : replaceInstUsesWith(*CI, With); } diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -3040,7 +3040,7 @@ } } -Value *LibCallSimplifier::optimizeCall(CallInst *CI) { +Value *LibCallSimplifier::optimizeCall(CallInst *CI, IRBuilderBase &Builder) { // TODO: Split out the code below that operates on FP calls so that // we can all non-FP calls with the StrictFP attribute to be // optimized. @@ -3049,11 +3049,13 @@ LibFunc Func; Function *Callee = CI->getCalledFunction(); + bool isCallingConvC = isCallingConvCCompatible(CI); SmallVector OpBundles; CI->getOperandBundlesAsDefs(OpBundles); - IRBuilder<> Builder(CI, /*FPMathTag=*/nullptr, OpBundles); - bool isCallingConvC = isCallingConvCCompatible(CI); + + IRBuilderBase::OperandBundlesGuard Guard(Builder); + Builder.setDefaultOperandBundles(OpBundles); // Command-line parameter overrides instruction attribute. // This can't be moved to optimizeFloatingPointLibCall() because it may be @@ -3093,7 +3095,8 @@ } // Also try to simplify calls to fortified library functions. - if (Value *SimplifiedFortifiedCI = FortifiedSimplifier.optimizeCall(CI)) { + if (Value *SimplifiedFortifiedCI = + FortifiedSimplifier.optimizeCall(CI, Builder)) { // Try to further simplify the result. CallInst *SimplifiedCI = dyn_cast(SimplifiedFortifiedCI); if (SimplifiedCI && SimplifiedCI->getCalledFunction()) { @@ -3101,10 +3104,11 @@ // their uses analyzed. replaceAllUsesWith(CI, SimplifiedCI); - // Use an IR Builder from SimplifiedCI if available instead of CI - // to guarantee we reach all uses we might replace later on. - IRBuilder<> TmpBuilder(SimplifiedCI); - if (Value *V = optimizeStringMemoryLibCall(SimplifiedCI, TmpBuilder)) { + // Set insertion point to SimplifiedCI to guarantee we reach all uses + // we might replace later on. + IRBuilderBase::InsertPointGuard Guard(Builder); + Builder.SetInsertPoint(SimplifiedCI); + if (Value *V = optimizeStringMemoryLibCall(SimplifiedCI, Builder)) { // If we were able to further simplify, remove the now redundant call. substituteInParent(SimplifiedCI, V); return V; @@ -3469,7 +3473,8 @@ return nullptr; } -Value *FortifiedLibCallSimplifier::optimizeCall(CallInst *CI) { +Value *FortifiedLibCallSimplifier::optimizeCall(CallInst *CI, + IRBuilderBase &Builder) { // FIXME: We shouldn't be changing "nobuiltin" or TLI unavailable calls here. // Some clang users checked for _chk libcall availability using: // __has_builtin(__builtin___memcpy_chk) @@ -3485,11 +3490,13 @@ LibFunc Func; Function *Callee = CI->getCalledFunction(); + bool isCallingConvC = isCallingConvCCompatible(CI); SmallVector OpBundles; CI->getOperandBundlesAsDefs(OpBundles); - IRBuilder<> Builder(CI, /*FPMathTag=*/nullptr, OpBundles); - bool isCallingConvC = isCallingConvCCompatible(CI); + + IRBuilderBase::OperandBundlesGuard Guard(Builder); + Builder.setDefaultOperandBundles(OpBundles); // First, check that this is a known library functions and that the prototype // is correct. diff --git a/llvm/test/Transforms/InstCombine/simplify-libcalls.ll b/llvm/test/Transforms/InstCombine/simplify-libcalls.ll --- a/llvm/test/Transforms/InstCombine/simplify-libcalls.ll +++ b/llvm/test/Transforms/InstCombine/simplify-libcalls.ll @@ -1,4 +1,4 @@ -; RUN: opt -S < %s -instcombine | FileCheck %s +; RUN: opt -S < %s -instcombine -instcombine-infinite-loop-threshold=2 | FileCheck %s target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32" @G = constant [3 x i8] c"%s\00" ; <[3 x i8]*> [#uses=1]