mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-28 06:32:09 +00:00
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
This commit is contained in:
parent
e493a9976c
commit
a7eb2b83ba
@ -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
|
||||
|
@ -617,7 +617,7 @@ bool AddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) {
|
||||
|
||||
Value *Cmp = IRB.CreateICmpNE(Length,
|
||||
Constant::getNullValue(Length->getType()));
|
||||
InsertBefore = SplitBlockAndInsertIfThen(cast<Instruction>(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<Instruction>(Cmp), false);
|
||||
SplitBlockAndInsertIfThen(Cmp, InsertBefore, false);
|
||||
assert(dyn_cast<BranchInst>(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<Instruction>(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<Instruction>(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<Instruction>(Cmp), false);
|
||||
Instruction *Term = SplitBlockAndInsertIfThen(Cmp, InsBefore, false);
|
||||
BasicBlock *CmpBlock = cast<Instruction>(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<Instruction>(Cmp), false);
|
||||
TerminatorInst *PoisonTerm = SplitBlockAndInsertIfThen(Cmp, Ret, false);
|
||||
IRBuilder<> IRBPoison(PoisonTerm);
|
||||
int ClassSize = kMinStackMallocSize << StackMallocIdx;
|
||||
SetShadowToStackAfterReturnInlined(IRBPoison, ShadowBase,
|
||||
|
@ -735,10 +735,9 @@ bool DataFlowSanitizer::runOnModule(Module &M) {
|
||||
while (isa<PHINode>(Pos) || isa<AllocaInst>(Pos))
|
||||
Pos = Pos->getNextNode();
|
||||
IRBuilder<> IRB(Pos);
|
||||
Instruction *NeInst = cast<Instruction>(
|
||||
IRB.CreateICmpNE(*i, DFSF.DFS.ZeroShadow));
|
||||
Value *Ne = IRB.CreateICmpNE(*i, DFSF.DFS.ZeroShadow);
|
||||
BranchInst *BI = cast<BranchInst>(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<Instruction>(Ne);
|
||||
if (NeInst) {
|
||||
if (Ne) {
|
||||
BranchInst *BI = cast<BranchInst>(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);
|
||||
|
@ -565,8 +565,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
|
||||
Value *Cmp = IRB.CreateICmpNE(ConvertedShadow,
|
||||
getCleanShadow(ConvertedShadow), "_mscmp");
|
||||
Instruction *CheckTerm =
|
||||
SplitBlockAndInsertIfThen(cast<Instruction>(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<MemorySanitizerVisitor> {
|
||||
continue;
|
||||
Value *Cmp = IRB.CreateICmpNE(ConvertedShadow,
|
||||
getCleanShadow(ConvertedShadow), "_mscmp");
|
||||
Instruction *CheckTerm =
|
||||
SplitBlockAndInsertIfThen(cast<Instruction>(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<MemorySanitizerVisitor> {
|
||||
IRB.CreatePHI(Fn0->getType(), 2, "msandr.indirect_target");
|
||||
|
||||
Instruction *CheckTerm = SplitBlockAndInsertIfThen(
|
||||
cast<Instruction>(NotInThisModule),
|
||||
NotInThisModule, NewFnPhi,
|
||||
/* Unreachable */ false, MS.ColdCallWeights);
|
||||
|
||||
IRB.SetInsertPoint(CheckTerm);
|
||||
|
@ -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;
|
||||
|
@ -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*
|
||||
|
Loading…
x
Reference in New Issue
Block a user