1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[SimplifyCFG] Preserve !annotation in FoldBranchToCommonDest.

When folding a branch to a common destination, preserve !annotation on
the created instruction, if the terminator of the BB that is going to be
removed has !annotation. This should ensure that !annotation is attached
to the instructions that 'replace' the original terminator.

Reviewed By: jdoerfert, lebedev.ri

Differential Revision: https://reviews.llvm.org/D93410
This commit is contained in:
Florian Hahn 2020-12-17 13:42:29 +00:00
parent 2d3aa79604
commit b86291bb4f
2 changed files with 16 additions and 11 deletions

View File

@ -2886,11 +2886,15 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI, MemorySSAUpdater *MSSAU,
Changed = true;
IRBuilder<> Builder(PBI);
// The builder is used to create instructions to eliminate the branch in BB.
// If BB's terminator has !annotation metadata, add it to the new
// instructions.
Builder.CollectMetadataToCopy(BB->getTerminator(),
{LLVMContext::MD_annotation});
// If we need to invert the condition in the pred block to match, do so now.
if (InvertPredCond) {
Value *NewCond = PBI->getCondition();
if (NewCond->hasOneUse() && isa<CmpInst>(NewCond)) {
CmpInst *CI = cast<CmpInst>(NewCond);
CI->setPredicate(CI->getInversePredicate());
@ -2941,8 +2945,9 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI, MemorySSAUpdater *MSSAU,
// its potential value. The previous information might have been valid
// only given the branch precondition.
// For an analogous reason, we must also drop all the metadata whose
// semantics we don't understand.
NewBonusInst->dropUnknownNonDebugMetadata();
// semantics we don't understand. We *can* preserve !annotation, because
// it is tied to the instruction itself, not the value or position.
NewBonusInst->dropUnknownNonDebugMetadata(LLVMContext::MD_annotation);
PredBlock->getInstList().insert(PBI->getIterator(), NewBonusInst);
NewBonusInst->takeName(&BonusInst);

View File

@ -6,8 +6,8 @@ define i32 @test_preserve_and(i8* %a, i8* %b, i8* %c, i8* %d) {
; CHECK-LABEL: define {{.*}} @test_preserve_and({{.*}}
; CHECK-NEXT: entry:
; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8* [[A:%.*]], [[B:%.*]], !annotation !0
; CHECK-NEXT: [[C_2:%.*]] = icmp uge i8* [[C:%.*]], [[D:%.*]]
; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C_1]], [[C_2]]
; CHECK-NEXT: [[C_2:%.*]] = icmp uge i8* [[C:%.*]], [[D:%.*]], !annotation !0
; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C_1]], [[C_2]], !annotation !0
; CHECK-NEXT: br i1 [[OR_COND]], label [[CONT1:%.*]], label [[TRAP:%.*]], !annotation !0
; CHECK: trap: ; preds = %entry
; CHECK-NEXT: call void @fn1()
@ -39,8 +39,8 @@ define i32 @test_preserve_or(i8* %a, i8* %b, i8* %c, i8* %d) {
; CHECK-LABEL: define {{.*}} @test_preserve_or({{.*}}
; CHECK-NEXT: entry:
; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8* [[A:%.*]], [[B:%.*]], !annotation !0
; CHECK-NEXT: [[C_2:%.*]] = icmp uge i8* [[C:%.*]], [[D:%.*]]
; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[C_1]], [[C_2]]
; CHECK-NEXT: [[C_2:%.*]] = icmp uge i8* [[C:%.*]], [[D:%.*]], !annotation !0
; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[C_1]], [[C_2]], !annotation !0
; CHECK-NEXT: br i1 [[OR_COND]], label [[TRAP:%.*]], label [[CONT1:%.*]], !annotation !0
; CHECK: trap: ; preds = %entry
; CHECK-NEXT: call void @fn1()
@ -73,9 +73,9 @@ define i32 @test_preserve_or_not(i8* %a, i8* %b, i8* %c, i8* %d) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8* [[A:%.*]], [[B:%.*]], !annotation !0
; CHECK-NEXT: [[C_2:%.*]] = xor i1 [[C_1]], true
; CHECK-NEXT: [[C_2_NOT:%.*]] = xor i1 [[C_2]], true
; CHECK-NEXT: [[C_3:%.*]] = icmp uge i8* [[C:%.*]], [[D:%.*]]
; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[C_2_NOT]], [[C_3]]
; CHECK-NEXT: [[C_2_NOT:%.*]] = xor i1 [[C_2]], true, !annotation !0
; CHECK-NEXT: [[C_3:%.*]] = icmp uge i8* [[C:%.*]], [[D:%.*]], !annotation !0
; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[C_2_NOT]], [[C_3]], !annotation !0
; CHECK-NEXT: br i1 [[OR_COND]], label [[TRAP:%.*]], label [[CONT1:%.*]], !annotation !0
; CHECK: trap: ; preds = %entry
; CHECK-NEXT: call void @fn1()
@ -111,7 +111,7 @@ define i32 @test_or_not_no_annotation(i8* %a, i8* %b, i8* %c, i8* %d) {
; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8* [[A:%.*]], [[B:%.*]], !annotation !0
; CHECK-NEXT: [[C_2:%.*]] = xor i1 [[C_1]], true
; CHECK-NEXT: [[C_2_NOT:%.*]] = xor i1 [[C_2]], true
; CHECK-NEXT: [[C_3:%.*]] = icmp uge i8* [[C:%.*]], [[D:%.*]]
; CHECK-NEXT: [[C_3:%.*]] = icmp uge i8* [[C:%.*]], [[D:%.*]], !annotation !0
; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[C_2_NOT]], [[C_3]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[TRAP:%.*]], label [[CONT1:%.*]], !annotation !0
; CHECK: trap: ; preds = %entry