diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -2886,11 +2886,15 @@ 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(NewCond)) { CmpInst *CI = cast(NewCond); CI->setPredicate(CI->getInversePredicate()); @@ -2941,8 +2945,9 @@ // 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); diff --git a/llvm/test/Transforms/SimplifyCFG/annotations.ll b/llvm/test/Transforms/SimplifyCFG/annotations.ll --- a/llvm/test/Transforms/SimplifyCFG/annotations.ll +++ b/llvm/test/Transforms/SimplifyCFG/annotations.ll @@ -6,8 +6,8 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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