From: Evgeniy Stepanov Date: Thu, 19 Dec 2013 13:29:56 +0000 (+0000) Subject: Add an explicit insert point argument to SplitBlockAndInsertIfThen. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=a7eb2b83ba102aed25fd7d0d09ae90f2fff458a1;p=oota-llvm.git Add an explicit insert point argument to SplitBlockAndInsertIfThen. Currently SplitBlockAndInsertIfThen requires that branch condition is an Instruction itself, which is very inconvenient, because it is sometimes an Operator, or even a Constant. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197677 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h index 65cafe2ec28..6bdf53facb6 100644 --- a/include/llvm/Transforms/Utils/BasicBlockUtils.h +++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h @@ -183,27 +183,27 @@ ReturnInst *FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB, BasicBlock *Pred); /// SplitBlockAndInsertIfThen - Split the containing block at the -/// specified instruction - everything before and including Cmp stays -/// in the old basic block, and everything after Cmp is moved to a +/// specified instruction - everything before and including SplitBefore stays +/// in the old basic block, and everything after SplitBefore is moved to a /// new block. The two blocks are connected by a conditional branch /// (with value of Cmp being the condition). /// Before: /// Head -/// Cmp +/// SplitBefore /// Tail /// After: /// Head -/// Cmp -/// if (Cmp) +/// if (Cond) /// ThenBlock +/// SplitBefore /// Tail /// /// If Unreachable is true, then ThenBlock ends with /// UnreachableInst, otherwise it branches to Tail. /// Returns the NewBasicBlock's terminator. - -TerminatorInst *SplitBlockAndInsertIfThen(Instruction *Cmp, - bool Unreachable, MDNode *BranchWeights = 0); +TerminatorInst *SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, + bool Unreachable, + MDNode *BranchWeights = 0); /// /// GetIfCondition - Check whether BB is the merge point of a if-region. @@ -211,7 +211,6 @@ TerminatorInst *SplitBlockAndInsertIfThen(Instruction *Cmp, /// BB will be taken. Also, return by references the block that will be /// entered from if the condition is true, and the block that will be /// entered if the condition is false. - Value *GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue, BasicBlock *&IfFalse); } // End llvm namespace diff --git a/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/lib/Transforms/Instrumentation/AddressSanitizer.cpp index f683bfb16c7..b4c789c5f82 100644 --- a/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -617,7 +617,7 @@ bool AddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) { Value *Cmp = IRB.CreateICmpNE(Length, Constant::getNullValue(Length->getType())); - InsertBefore = SplitBlockAndInsertIfThen(cast(Cmp), false); + InsertBefore = SplitBlockAndInsertIfThen(Cmp, InsertBefore, false); } instrumentMemIntrinsicParam(MI, Dst, Length, InsertBefore, true); @@ -780,7 +780,7 @@ void AddressSanitizer::instrumentAddress(Instruction *OrigIns, if (ClAlwaysSlowPath || (TypeSize < 8 * Granularity)) { TerminatorInst *CheckTerm = - SplitBlockAndInsertIfThen(cast(Cmp), false); + SplitBlockAndInsertIfThen(Cmp, InsertBefore, false); assert(dyn_cast(CheckTerm)->isUnconditional()); BasicBlock *NextBB = CheckTerm->getSuccessor(0); IRB.SetInsertPoint(CheckTerm); @@ -791,7 +791,7 @@ void AddressSanitizer::instrumentAddress(Instruction *OrigIns, BranchInst *NewTerm = BranchInst::Create(CrashBlock, NextBB, Cmp2); ReplaceInstWithInst(CheckTerm, NewTerm); } else { - CrashTerm = SplitBlockAndInsertIfThen(cast(Cmp), true); + CrashTerm = SplitBlockAndInsertIfThen(Cmp, InsertBefore, true); } Instruction *Crash = generateCrashCode( @@ -1188,7 +1188,7 @@ bool AddressSanitizer::InjectCoverage(Function &F) { Load->setAtomic(Monotonic); Load->setAlignment(1); Value *Cmp = IRB.CreateICmpEQ(Constant::getNullValue(Int8Ty), Load); - Instruction *Ins = SplitBlockAndInsertIfThen(cast(Cmp), false); + Instruction *Ins = SplitBlockAndInsertIfThen(Cmp, IP, false); IRB.SetInsertPoint(Ins); // We pass &F to __sanitizer_cov. We could avoid this and rely on // GET_CALLER_PC, but having the PC of the first instruction is just nice. @@ -1448,8 +1448,7 @@ void FunctionStackPoisoner::poisonStack() { kAsanOptionDetectUAR, IRB.getInt32Ty()); Value *Cmp = IRB.CreateICmpNE(IRB.CreateLoad(OptionDetectUAR), Constant::getNullValue(IRB.getInt32Ty())); - Instruction *Term = - SplitBlockAndInsertIfThen(cast(Cmp), false); + Instruction *Term = SplitBlockAndInsertIfThen(Cmp, InsBefore, false); BasicBlock *CmpBlock = cast(Cmp)->getParent(); IRBuilder<> IRBIf(Term); LocalStackBase = IRBIf.CreateCall2( @@ -1529,8 +1528,7 @@ void FunctionStackPoisoner::poisonStack() { // **SavedFlagPtr(LocalStackBase) = 0 // FIXME: if LocalStackBase != OrigStackBase don't call poisonRedZones. Value *Cmp = IRBRet.CreateICmpNE(LocalStackBase, OrigStackBase); - TerminatorInst *PoisonTerm = - SplitBlockAndInsertIfThen(cast(Cmp), false); + TerminatorInst *PoisonTerm = SplitBlockAndInsertIfThen(Cmp, Ret, false); IRBuilder<> IRBPoison(PoisonTerm); int ClassSize = kMinStackMallocSize << StackMallocIdx; SetShadowToStackAfterReturnInlined(IRBPoison, ShadowBase, diff --git a/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp index c539be93a7a..653ad7ff845 100644 --- a/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ b/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -735,10 +735,9 @@ bool DataFlowSanitizer::runOnModule(Module &M) { while (isa(Pos) || isa(Pos)) Pos = Pos->getNextNode(); IRBuilder<> IRB(Pos); - Instruction *NeInst = cast( - IRB.CreateICmpNE(*i, DFSF.DFS.ZeroShadow)); + Value *Ne = IRB.CreateICmpNE(*i, DFSF.DFS.ZeroShadow); BranchInst *BI = cast(SplitBlockAndInsertIfThen( - NeInst, /*Unreachable=*/ false, ColdCallWeights)); + Ne, Pos, /*Unreachable=*/false, ColdCallWeights)); IRBuilder<> ThenIRB(BI); ThenIRB.CreateCall(DFSF.DFS.DFSanNonzeroLabelFn); } @@ -838,10 +837,9 @@ Value *DataFlowSanitizer::combineShadows(Value *V1, Value *V2, IRBuilder<> IRB(Pos); BasicBlock *Head = Pos->getParent(); Value *Ne = IRB.CreateICmpNE(V1, V2); - Instruction *NeInst = dyn_cast(Ne); - if (NeInst) { + if (Ne) { BranchInst *BI = cast(SplitBlockAndInsertIfThen( - NeInst, /*Unreachable=*/ false, ColdCallWeights)); + Ne, Pos, /*Unreachable=*/false, ColdCallWeights)); IRBuilder<> ThenIRB(BI); CallInst *Call = ThenIRB.CreateCall2(DFSanUnionFn, V1, V2); Call->addAttribute(AttributeSet::ReturnIndex, Attribute::ZExt); diff --git a/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/lib/Transforms/Instrumentation/MemorySanitizer.cpp index f2e1ab7513c..8a52a4444be 100644 --- a/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -565,8 +565,7 @@ struct MemorySanitizerVisitor : public InstVisitor { Value *Cmp = IRB.CreateICmpNE(ConvertedShadow, getCleanShadow(ConvertedShadow), "_mscmp"); Instruction *CheckTerm = - SplitBlockAndInsertIfThen(cast(Cmp), false, - MS.OriginStoreWeights); + SplitBlockAndInsertIfThen(Cmp, &I, false, MS.OriginStoreWeights); IRBuilder<> IRBNew(CheckTerm); IRBNew.CreateAlignedStore(getOrigin(Val), getOriginPtr(Addr, IRBNew), Alignment); @@ -588,10 +587,9 @@ struct MemorySanitizerVisitor : public InstVisitor { continue; Value *Cmp = IRB.CreateICmpNE(ConvertedShadow, getCleanShadow(ConvertedShadow), "_mscmp"); - Instruction *CheckTerm = - SplitBlockAndInsertIfThen(cast(Cmp), - /* Unreachable */ !ClKeepGoing, - MS.ColdCallWeights); + Instruction *CheckTerm = SplitBlockAndInsertIfThen( + Cmp, OrigIns, + /* Unreachable */ !ClKeepGoing, MS.ColdCallWeights); IRB.SetInsertPoint(CheckTerm); if (MS.TrackOrigins) { @@ -629,7 +627,7 @@ struct MemorySanitizerVisitor : public InstVisitor { IRB.CreatePHI(Fn0->getType(), 2, "msandr.indirect_target"); Instruction *CheckTerm = SplitBlockAndInsertIfThen( - cast(NotInThisModule), + NotInThisModule, NewFnPhi, /* Unreachable */ false, MS.ColdCallWeights); IRB.SetInsertPoint(CheckTerm); diff --git a/lib/Transforms/Utils/BasicBlockUtils.cpp b/lib/Transforms/Utils/BasicBlockUtils.cpp index 12de9eed4b8..17bd115ee95 100644 --- a/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -630,28 +630,29 @@ ReturnInst *llvm::FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB, } /// SplitBlockAndInsertIfThen - Split the containing block at the -/// specified instruction - everything before and including Cmp stays -/// in the old basic block, and everything after Cmp is moved to a +/// specified instruction - everything before and including SplitBefore stays +/// in the old basic block, and everything after SplitBefore is moved to a /// new block. The two blocks are connected by a conditional branch /// (with value of Cmp being the condition). /// Before: /// Head -/// Cmp +/// SplitBefore /// Tail /// After: /// Head -/// Cmp -/// if (Cmp) +/// if (Cond) /// ThenBlock +/// SplitBefore /// Tail /// /// If Unreachable is true, then ThenBlock ends with /// UnreachableInst, otherwise it branches to Tail. /// Returns the NewBasicBlock's terminator. -TerminatorInst *llvm::SplitBlockAndInsertIfThen(Instruction *Cmp, - bool Unreachable, MDNode *BranchWeights) { - Instruction *SplitBefore = Cmp->getNextNode(); +TerminatorInst *llvm::SplitBlockAndInsertIfThen(Value *Cond, + Instruction *SplitBefore, + bool Unreachable, + MDNode *BranchWeights) { BasicBlock *Head = SplitBefore->getParent(); BasicBlock *Tail = Head->splitBasicBlock(SplitBefore); TerminatorInst *HeadOldTerm = Head->getTerminator(); @@ -663,7 +664,7 @@ TerminatorInst *llvm::SplitBlockAndInsertIfThen(Instruction *Cmp, else CheckTerm = BranchInst::Create(Tail, ThenBlock); BranchInst *HeadNewTerm = - BranchInst::Create(/*ifTrue*/ThenBlock, /*ifFalse*/Tail, Cmp); + BranchInst::Create(/*ifTrue*/ThenBlock, /*ifFalse*/Tail, Cond); HeadNewTerm->setMetadata(LLVMContext::MD_prof, BranchWeights); ReplaceInstWithInst(HeadOldTerm, HeadNewTerm); return CheckTerm; diff --git a/test/Instrumentation/MemorySanitizer/wrap_indirect_calls.ll b/test/Instrumentation/MemorySanitizer/wrap_indirect_calls.ll index 555695d2584..65037cb4790 100644 --- a/test/Instrumentation/MemorySanitizer/wrap_indirect_calls.ll +++ b/test/Instrumentation/MemorySanitizer/wrap_indirect_calls.ll @@ -8,20 +8,20 @@ target triple = "x86_64-unknown-linux-gnu" ; wrapper function. ; This does not depend on the sanitize_memory attribute. -define i32 @func(i32 (i32, i32)* nocapture %f, i32 %x, i32 %y) { +define i32 @func1(i32 (i32, i32)* nocapture %f, i32 %x, i32 %y) { entry: %call = tail call i32 %f(i32 %x, i32 %y) ret i32 %call } -; CHECK: @func +; CHECK: @func1 ; CHECK: bitcast i32 (i32, i32)* %f to void ()* ; CHECK: call void ()* (void ()*)* @zzz(void ()* ; CHECK: [[A:%[01-9a-z_.]+]] = bitcast void ()* {{.*}} to i32 (i32, i32)* ; CHECK: call i32 {{.*}}[[A]](i32 {{.*}}, i32 {{.*}}) ; CHECK: ret i32 -; CHECK-FAST: @func +; CHECK-FAST: @func1 ; CHECK-FAST: bitcast i32 (i32, i32)* %f to void ()* ; CHECK-FAST-DAG: icmp ult void ()* {{.*}}, bitcast (i32* @__executable_start to void ()*) ; CHECK-FAST-DAG: icmp uge void ()* {{.*}}, bitcast (i32* @_end to void ()*) @@ -32,3 +32,29 @@ entry: ; CHECK-FAST: [[A:%[01-9a-z_.]+]] = phi i32 (i32, i32)* [ %f, %entry ], [ {{.*}} ] ; CHECK-FAST: call i32 {{.*}}[[A]](i32 {{.*}}, i32 {{.*}}) ; CHECK-FAST: ret i32 + + +; The same test, but with a complex expression as the call target. + +declare i8* @callee(i32) + +define i8* @func2(i64 %x) #1 { +entry: + %call = tail call i8* bitcast (i8* (i32)* @callee to i8* (i64)*)(i64 %x) + ret i8* %call +} + +; CHECK: @func2 +; CHECK: call {{.*}} @zzz +; CHECK: [[A:%[01-9a-z_.]+]] = bitcast void ()* {{.*}} to i8* (i64)* +; CHECK: call i8* {{.*}}[[A]](i64 {{.*}}) +; CHECK: ret i8* + +; CHECK-FAST: @func2 +; CHECK-FAST: {{br i1 or .* icmp ult .* bitcast .* @callee .* @__executable_start.* icmp uge .* bitcast .* @callee .* @_end}} +; CHECK-FAST: {{call .* @zzz.* bitcast .*@callee}} +; CHECK-FAST: bitcast void ()* {{.*}} to i8* (i64)* +; CHECK-FAST: br label +; CHECK-FAST: [[A:%[01-9a-z_.]+]] = phi i8* (i64)* [{{.*bitcast .* @callee.*, %entry.*}}], [ {{.*}} ] +; CHECK-FAST: call i8* {{.*}}[[A]](i64 {{.*}}) +; CHECK-FAST: ret i8*