diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h --- a/llvm/include/llvm/IR/BasicBlock.h +++ b/llvm/include/llvm/IR/BasicBlock.h @@ -372,7 +372,13 @@ /// Update PHI nodes in this BasicBlock before removal of predecessor \p Pred. /// Note that this function does not actually remove the predecessor. - void removePredecessor(BasicBlock *Pred, bool KeepOneInputPHIs = false); + /// + /// If \p MaybeDeadInstrs is not nullptr then whenever we drop a reference to + /// an instruction, append it to the vector. The caller should check whether + /// these instructions are now trivially dead, and if so delete them. + void + removePredecessor(BasicBlock *Pred, bool KeepOneInputPHIs = false, + SmallVectorImpl *MaybeDeadInstrs = nullptr); bool canSplitPredecessors() const; diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp --- a/llvm/lib/IR/BasicBlock.cpp +++ b/llvm/lib/IR/BasicBlock.cpp @@ -319,8 +319,13 @@ /// Update PHI nodes in this BasicBlock before removal of predecessor \p Pred. /// Note that this function does not actually remove the predecessor. -void BasicBlock::removePredecessor(BasicBlock *Pred, - bool KeepOneInputPHIs) { +/// +/// If \p MaybeDeadInstrs is not nullptr then whenever we drop a reference to +/// an instruction, append it to the vector. The caller should check whether +/// these instructions are now trivially dead, and if so delete them. +void BasicBlock::removePredecessor( + BasicBlock *Pred, bool KeepOneInputPHIs, + SmallVectorImpl *MaybeDeadInstrs) { // Use hasNUsesOrMore to bound the cost of this assertion for complex CFGs. assert((hasNUsesOrMore(16) || find(pred_begin(this), pred_end(this), Pred) != pred_end(this)) && @@ -334,15 +339,23 @@ // Update all PHI nodes. for (iterator II = begin(); isa(II);) { PHINode *PN = cast(II++); - PN->removeIncomingValue(Pred); - // If we have a single predecessor, removeIncomingValue erased the PHI node - // itself. + Value *V = PN->removeIncomingValue(Pred, false); + if (MaybeDeadInstrs) + if (auto *I = dyn_cast(V)) + MaybeDeadInstrs->push_back(I); // FIXME in practice "KeepOneInputPHIs" means "KeepConstantPHIs" and some // callers seem to rely on that. - if (NumPreds > 1 && !KeepOneInputPHIs) { - if (Value *PNV = PN->hasConstantValue()) { - // Replace the PHI node with its constant value. - PN->replaceAllUsesWith(PNV); + Value *C = NumPreds == 1 + ? UndefValue::get(PN->getType()) + : KeepOneInputPHIs ? nullptr : PN->hasConstantValue(); + if (C) { + // Replace the PHI node with its constant value. + PN->replaceAllUsesWith(C); + if (MaybeDeadInstrs) { + // Don't erase PN yet in case it has already been pushed into this + // vector, because it was an operand of some other PHI node. + MaybeDeadInstrs->push_back(PN); + } else { PN->eraseFromParent(); } } diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -126,8 +126,13 @@ BasicBlock *OldDest = Cond->getZExtValue() ? Dest2 : Dest1; // Let the basic block know that we are letting go of it. Based on this, - // it will adjust it's PHI nodes. - OldDest->removePredecessor(BB); + // it will adjust its PHI nodes. + SmallVector MaybeDeadInstrs; + OldDest->removePredecessor(BB, false, &MaybeDeadInstrs); + SmallVector MaybeDeadHandles(MaybeDeadInstrs.begin(), + MaybeDeadInstrs.end()); + RecursivelyDeleteTriviallyDeadInstructionsPermissive(MaybeDeadHandles, + TLI); // Replace the conditional branch with an unconditional one. Builder.CreateBr(Destination); diff --git a/llvm/test/Transforms/PGOProfile/chr.ll b/llvm/test/Transforms/PGOProfile/chr.ll --- a/llvm/test/Transforms/PGOProfile/chr.ll +++ b/llvm/test/Transforms/PGOProfile/chr.ll @@ -448,34 +448,33 @@ ; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[I:%.*]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[TMP0]], 15 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 15 -; CHECK-NEXT: br i1 [[TMP2]], label [[BB0:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof !15 -; CHECK: bb0: -; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[SUM0:%.*]], 85 -; CHECK-NEXT: [[TMP4:%.*]] = add i32 [[SUM0]], 173 +; CHECK-NEXT: br i1 [[TMP2]], label [[BB1:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof !15 +; CHECK: bb1: +; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[SUM0:%.*]], 173 ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: entry.split.nonchr: -; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP0]], 255 -; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0 -; CHECK-NEXT: br i1 [[TMP6]], label [[BB3]], label [[BB0_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP0]], 255 +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 0 +; CHECK-NEXT: br i1 [[TMP5]], label [[BB3]], label [[BB0_NONCHR:%.*]], !prof !16 ; CHECK: bb0.nonchr: -; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP0]], 1 -; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i32 [[TMP7]], 0 -; CHECK-NEXT: [[TMP9:%.*]] = add i32 [[SUM0]], 42 -; CHECK-NEXT: [[SUM1_NONCHR:%.*]] = select i1 [[TMP8]], i32 [[SUM0]], i32 [[TMP9]], !prof !16 -; CHECK-NEXT: [[TMP10:%.*]] = and i32 [[TMP0]], 2 -; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], 0 -; CHECK-NEXT: [[TMP12:%.*]] = add i32 [[SUM1_NONCHR]], 43 -; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP11]], i32 [[SUM1_NONCHR]], i32 [[TMP12]], !prof !16 -; CHECK-NEXT: [[TMP13:%.*]] = and i32 [[TMP0]], 4 -; CHECK-NEXT: [[TMP14:%.*]] = icmp eq i32 [[TMP13]], 0 -; CHECK-NEXT: [[TMP15:%.*]] = and i32 [[TMP0]], 8 -; CHECK-NEXT: [[TMP16:%.*]] = icmp eq i32 [[TMP15]], 0 -; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP16]], i32 44, i32 88 +; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP0]], 1 +; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 0 +; CHECK-NEXT: [[TMP8:%.*]] = add i32 [[SUM0]], 42 +; CHECK-NEXT: [[SUM1_NONCHR:%.*]] = select i1 [[TMP7]], i32 [[SUM0]], i32 [[TMP8]], !prof !16 +; CHECK-NEXT: [[TMP9:%.*]] = and i32 [[TMP0]], 2 +; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP9]], 0 +; CHECK-NEXT: [[TMP11:%.*]] = add i32 [[SUM1_NONCHR]], 43 +; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP10]], i32 [[SUM1_NONCHR]], i32 [[TMP11]], !prof !16 +; CHECK-NEXT: [[TMP12:%.*]] = and i32 [[TMP0]], 4 +; CHECK-NEXT: [[TMP13:%.*]] = icmp eq i32 [[TMP12]], 0 +; CHECK-NEXT: [[TMP14:%.*]] = and i32 [[TMP0]], 8 +; CHECK-NEXT: [[TMP15:%.*]] = icmp eq i32 [[TMP14]], 0 +; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP15]], i32 44, i32 88 ; CHECK-NEXT: [[SUM4_NONCHR:%.*]] = add i32 [[SUM2_NONCHR]], [[SUM4_NONCHR_V]] -; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP14]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof !16 +; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP13]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof !16 ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: -; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP4]], [[BB0]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ] +; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP3]], [[BB1]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ] ; CHECK-NEXT: ret i32 [[SUM6]] ; entry: @@ -548,34 +547,33 @@ ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP0]], 11 ; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 11 ; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP2]] -; CHECK-NEXT: br i1 [[TMP5]], label [[BB0:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof !15 -; CHECK: bb0: -; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[SUM0]], 85 -; CHECK-NEXT: [[TMP7:%.*]] = add i32 [[SUM0]], 173 +; CHECK-NEXT: br i1 [[TMP5]], label [[BB1:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof !15 +; CHECK: bb1: +; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[SUM0]], 173 ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: entry.split.nonchr: -; CHECK-NEXT: [[TMP8:%.*]] = and i32 [[TMP0]], 255 -; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0 -; CHECK-NEXT: br i1 [[TMP9]], label [[BB3]], label [[BB0_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP0]], 255 +; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i32 [[TMP7]], 0 +; CHECK-NEXT: br i1 [[TMP8]], label [[BB3]], label [[BB0_NONCHR:%.*]], !prof !16 ; CHECK: bb0.nonchr: -; CHECK-NEXT: [[TMP10:%.*]] = and i32 [[TMP0]], 1 -; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], 0 -; CHECK-NEXT: [[TMP12:%.*]] = add i32 [[SUM0]], 42 -; CHECK-NEXT: [[SUM1_NONCHR:%.*]] = select i1 [[TMP11]], i32 [[SUM0]], i32 [[TMP12]], !prof !16 -; CHECK-NEXT: [[TMP13:%.*]] = and i32 [[TMP0]], 2 -; CHECK-NEXT: [[TMP14:%.*]] = icmp eq i32 [[TMP13]], 0 -; CHECK-NEXT: [[TMP15:%.*]] = add i32 [[SUM1_NONCHR]], 43 -; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP14]], i32 [[SUM1_NONCHR]], i32 [[TMP15]], !prof !16 -; CHECK-NEXT: [[TMP16:%.*]] = and i32 [[SUM0]], 4 -; CHECK-NEXT: [[TMP17:%.*]] = icmp eq i32 [[TMP16]], 0 -; CHECK-NEXT: [[TMP18:%.*]] = and i32 [[TMP0]], 8 -; CHECK-NEXT: [[TMP19:%.*]] = icmp eq i32 [[TMP18]], 0 -; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP19]], i32 44, i32 88 +; CHECK-NEXT: [[TMP9:%.*]] = and i32 [[TMP0]], 1 +; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP9]], 0 +; CHECK-NEXT: [[TMP11:%.*]] = add i32 [[SUM0]], 42 +; CHECK-NEXT: [[SUM1_NONCHR:%.*]] = select i1 [[TMP10]], i32 [[SUM0]], i32 [[TMP11]], !prof !16 +; CHECK-NEXT: [[TMP12:%.*]] = and i32 [[TMP0]], 2 +; CHECK-NEXT: [[TMP13:%.*]] = icmp eq i32 [[TMP12]], 0 +; CHECK-NEXT: [[TMP14:%.*]] = add i32 [[SUM1_NONCHR]], 43 +; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP13]], i32 [[SUM1_NONCHR]], i32 [[TMP14]], !prof !16 +; CHECK-NEXT: [[TMP15:%.*]] = and i32 [[SUM0]], 4 +; CHECK-NEXT: [[TMP16:%.*]] = icmp eq i32 [[TMP15]], 0 +; CHECK-NEXT: [[TMP17:%.*]] = and i32 [[TMP0]], 8 +; CHECK-NEXT: [[TMP18:%.*]] = icmp eq i32 [[TMP17]], 0 +; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP18]], i32 44, i32 88 ; CHECK-NEXT: [[SUM4_NONCHR:%.*]] = add i32 [[SUM2_NONCHR]], [[SUM4_NONCHR_V]] -; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP17]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof !16 +; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP16]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof !16 ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: -; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP7]], [[BB0]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ] +; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP6]], [[BB1]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ] ; CHECK-NEXT: ret i32 [[SUM6]] ; entry: @@ -649,10 +647,9 @@ ; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[I0]], 10 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 10 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[V10]] -; CHECK-NEXT: br i1 [[TMP2]], label [[BB0:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof !15 -; CHECK: bb0: -; CHECK-NEXT: [[V8:%.*]] = add i32 [[SUM0:%.*]], 43 -; CHECK-NEXT: [[V13:%.*]] = add i32 [[SUM0]], 131 +; CHECK-NEXT: br i1 [[TMP2]], label [[BB1:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof !15 +; CHECK: bb1: +; CHECK-NEXT: [[V13:%.*]] = add i32 [[SUM0:%.*]], 131 ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: entry.split.nonchr: ; CHECK-NEXT: [[V1:%.*]] = and i32 [[I0]], 255 @@ -672,7 +669,7 @@ ; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[V10_NONCHR]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof !16 ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: -; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[V13]], [[BB0]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ] +; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[V13]], [[BB1]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ] ; CHECK-NEXT: ret i32 [[SUM6]] ; entry: @@ -1737,28 +1734,27 @@ ; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[I:%.*]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[TMP0]], 9 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 9 -; CHECK-NEXT: br i1 [[TMP2]], label [[BB0:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof !15 -; CHECK: bb0: -; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[SUM0:%.*]], 85 -; CHECK-NEXT: [[TMP4:%.*]] = add i32 [[SUM0]], 173 +; CHECK-NEXT: br i1 [[TMP2]], label [[BB1:%.*]], label [[ENTRY_SPLIT_NONCHR:%.*]], !prof !15 +; CHECK: bb1: +; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[SUM0:%.*]], 173 ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: entry.split.nonchr: -; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP0]], 255 -; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0 -; CHECK-NEXT: br i1 [[TMP6]], label [[BB3]], label [[BB0_NONCHR:%.*]], !prof !16 +; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP0]], 255 +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 0 +; CHECK-NEXT: br i1 [[TMP5]], label [[BB3]], label [[BB0_NONCHR:%.*]], !prof !16 ; CHECK: bb0.nonchr: -; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP0]], 1 -; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i32 [[TMP7]], 0 -; CHECK-NEXT: [[TMP9:%.*]] = add i32 [[SUM0]], 85 -; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP8]], i32 [[SUM0]], i32 [[TMP9]], !prof !16 -; CHECK-NEXT: [[TMP10:%.*]] = and i32 [[TMP0]], 8 -; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], 0 -; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP11]], i32 44, i32 88 +; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP0]], 1 +; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 0 +; CHECK-NEXT: [[TMP8:%.*]] = add i32 [[SUM0]], 85 +; CHECK-NEXT: [[SUM2_NONCHR:%.*]] = select i1 [[TMP7]], i32 [[SUM0]], i32 [[TMP8]], !prof !16 +; CHECK-NEXT: [[TMP9:%.*]] = and i32 [[TMP0]], 8 +; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP9]], 0 +; CHECK-NEXT: [[SUM4_NONCHR_V:%.*]] = select i1 [[TMP10]], i32 44, i32 88 ; CHECK-NEXT: [[SUM4_NONCHR:%.*]] = add i32 [[SUM2_NONCHR]], [[SUM4_NONCHR_V]] -; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP8]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof !16 +; CHECK-NEXT: [[SUM5_NONCHR:%.*]] = select i1 [[TMP7]], i32 [[SUM2_NONCHR]], i32 [[SUM4_NONCHR]], !prof !16 ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: -; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP4]], [[BB0]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ] +; CHECK-NEXT: [[SUM6:%.*]] = phi i32 [ [[TMP3]], [[BB1]] ], [ [[SUM0]], [[ENTRY_SPLIT_NONCHR]] ], [ [[SUM5_NONCHR]], [[BB0_NONCHR]] ] ; CHECK-NEXT: ret i32 [[SUM6]] ; entry: @@ -2004,6 +2000,27 @@ ; Test a case with a really long use-def chains. This test checks that it's not ; really slow and doesn't appear to be hanging. define i64 @test_chr_22(i1 %i, i64* %j, i64 %v0) !prof !14 { +; CHECK-LABEL: @test_chr_22( +; CHECK-NEXT: bb0: +; CHECK-NEXT: [[V1:%.*]] = add i64 [[V0:%.*]], 3 +; CHECK-NEXT: [[V2:%.*]] = add i64 [[V1]], [[V0]] +; CHECK-NEXT: [[C1:%.*]] = icmp slt i64 [[V2]], 100 +; CHECK-NEXT: [[V300:%.*]] = mul i64 [[V2]], -8647960034816487527 +; CHECK-NEXT: [[V301:%.*]] = icmp ne i64 [[V300]], 100 +; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[C1]], [[V301]] +; CHECK-NEXT: br i1 [[TMP0]], label [[BB0_SPLIT:%.*]], label [[BB0_SPLIT_NONCHR:%.*]], !prof !15 +; CHECK: bb0.split: +; CHECK-NEXT: [[V299:%.*]] = mul i64 [[V2]], 7860086430977039991 +; CHECK-NEXT: store i64 [[V299]], i64* [[J:%.*]], align 4 +; CHECK-NEXT: ret i64 99 +; CHECK: bb0.split.nonchr: +; CHECK-NEXT: [[V300_NONCHR:%.*]] = mul i64 [[V2]], -8647960034816487527 +; CHECK-NEXT: [[V301_NONCHR:%.*]] = icmp eq i64 [[V300_NONCHR]], 100 +; CHECK-NEXT: [[V302_NONCHR_V:%.*]] = select i1 [[V301_NONCHR]], i64 1938697607916024098, i64 7860086430977039991, !prof !16 +; CHECK-NEXT: [[V302_NONCHR:%.*]] = mul i64 [[V2]], [[V302_NONCHR_V]] +; CHECK-NEXT: store i64 [[V302_NONCHR]], i64* [[J]], align 4 +; CHECK-NEXT: ret i64 99 +; bb0: %v1 = add i64 %v0, 3 %v2 = add i64 %v1, %v0 @@ -2317,6 +2334,12 @@ ; test_chr_22 in that it has nested control structures (multiple scopes) and ; covers additional code. define i64 @test_chr_23(i64 %v0) !prof !14 { +; CHECK-LABEL: @test_chr_23( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = mul i64 [[V0:%.*]], 50 +; CHECK-NEXT: [[V10:%.*]] = icmp ne i64 [[TMP0]], -50 +; CHECK-NEXT: ret i64 99 +; entry: %v1 = add i64 %v0, 3 %v2 = add i64 %v1, %v1 @@ -2465,6 +2488,25 @@ ; Test to not crash upon a 0:0 branch_weight metadata. define void @test_chr_24(i32* %i) !prof !14 { +; CHECK-LABEL: @test_chr_24( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[I:%.*]], align 4 +; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[TMP0]], 1 +; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0 +; CHECK-NEXT: br i1 [[TMP2]], label [[BB1:%.*]], label [[BB0:%.*]], !prof !21 +; CHECK: bb0: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br label [[BB1]] +; CHECK: bb1: +; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP0]], 2 +; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0 +; CHECK-NEXT: br i1 [[TMP4]], label [[BB3:%.*]], label [[BB2:%.*]], !prof !21 +; CHECK: bb2: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br label [[BB3]] +; CHECK: bb3: +; CHECK-NEXT: ret void +; entry: %0 = load i32, i32* %i %1 = and i32 %0, 1