Skip to content

Commit f9c211a

Browse files
jdenny-ornlmahesh-attarde
authored andcommitted
[LoopPeel] Fix branch weights' effect on block frequencies (llvm#128785)
[LoopPeel] Fix branch weights' effect on block frequencies This patch implements the LoopPeel changes discussed in [[RFC] Fix Loop Transformations to Preserve Block Frequencies](https://discourse.llvm.org/t/rfc-fix-loop-transformations-to-preserve-block-frequencies/85785). In summary, a loop's latch block can have branch weight metadata that encodes an estimated trip count that is derived from application profile data. Initially, the loop body's block frequencies agree with the estimated trip count, as expected. However, sometimes loop transformations adjust those branch weights in a way that correctly maintains the estimated trip count but that corrupts the block frequencies. This patch addresses that problem in LoopPeel, which it changes to: - Maintain branch weights consistently with the original loop for the sake of preserving the total frequency of the original loop body. - Store the new estimated trip count in the `llvm.loop.estimated_trip_count` metadata, introduced by PR llvm#148758.
1 parent 1e20d80 commit f9c211a

File tree

6 files changed

+151
-137
lines changed

6 files changed

+151
-137
lines changed

llvm/lib/Transforms/Utils/LoopPeel.cpp

Lines changed: 28 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -883,84 +883,6 @@ void llvm::computePeelCount(Loop *L, unsigned LoopSize,
883883
}
884884
}
885885

886-
struct WeightInfo {
887-
// Weights for current iteration.
888-
SmallVector<uint32_t> Weights;
889-
// Weights to subtract after each iteration.
890-
const SmallVector<uint32_t> SubWeights;
891-
};
892-
893-
/// Update the branch weights of an exiting block of a peeled-off loop
894-
/// iteration.
895-
/// Let F is a weight of the edge to continue (fallthrough) into the loop.
896-
/// Let E is a weight of the edge to an exit.
897-
/// F/(F+E) is a probability to go to loop and E/(F+E) is a probability to
898-
/// go to exit.
899-
/// Then, Estimated ExitCount = F / E.
900-
/// For I-th (counting from 0) peeled off iteration we set the weights for
901-
/// the peeled exit as (EC - I, 1). It gives us reasonable distribution,
902-
/// The probability to go to exit 1/(EC-I) increases. At the same time
903-
/// the estimated exit count in the remainder loop reduces by I.
904-
/// To avoid dealing with division rounding we can just multiple both part
905-
/// of weights to E and use weight as (F - I * E, E).
906-
static void updateBranchWeights(Instruction *Term, WeightInfo &Info) {
907-
setBranchWeights(*Term, Info.Weights, /*IsExpected=*/false);
908-
for (auto [Idx, SubWeight] : enumerate(Info.SubWeights))
909-
if (SubWeight != 0)
910-
// Don't set the probability of taking the edge from latch to loop header
911-
// to less than 1:1 ratio (meaning Weight should not be lower than
912-
// SubWeight), as this could significantly reduce the loop's hotness,
913-
// which would be incorrect in the case of underestimating the trip count.
914-
Info.Weights[Idx] =
915-
Info.Weights[Idx] > SubWeight
916-
? std::max(Info.Weights[Idx] - SubWeight, SubWeight)
917-
: SubWeight;
918-
}
919-
920-
/// Initialize the weights for all exiting blocks.
921-
static void initBranchWeights(DenseMap<Instruction *, WeightInfo> &WeightInfos,
922-
Loop *L) {
923-
SmallVector<BasicBlock *> ExitingBlocks;
924-
L->getExitingBlocks(ExitingBlocks);
925-
for (BasicBlock *ExitingBlock : ExitingBlocks) {
926-
Instruction *Term = ExitingBlock->getTerminator();
927-
SmallVector<uint32_t> Weights;
928-
if (!extractBranchWeights(*Term, Weights))
929-
continue;
930-
931-
// See the comment on updateBranchWeights() for an explanation of what we
932-
// do here.
933-
uint32_t FallThroughWeights = 0;
934-
uint32_t ExitWeights = 0;
935-
for (auto [Succ, Weight] : zip(successors(Term), Weights)) {
936-
if (L->contains(Succ))
937-
FallThroughWeights += Weight;
938-
else
939-
ExitWeights += Weight;
940-
}
941-
942-
// Don't try to update weights for degenerate case.
943-
if (FallThroughWeights == 0)
944-
continue;
945-
946-
SmallVector<uint32_t> SubWeights;
947-
for (auto [Succ, Weight] : zip(successors(Term), Weights)) {
948-
if (!L->contains(Succ)) {
949-
// Exit weights stay the same.
950-
SubWeights.push_back(0);
951-
continue;
952-
}
953-
954-
// Subtract exit weights on each iteration, distributed across all
955-
// fallthrough edges.
956-
double W = (double)Weight / (double)FallThroughWeights;
957-
SubWeights.push_back((uint32_t)(ExitWeights * W));
958-
}
959-
960-
WeightInfos.insert({Term, {std::move(Weights), std::move(SubWeights)}});
961-
}
962-
}
963-
964886
/// Clones the body of the loop L, putting it between \p InsertTop and \p
965887
/// InsertBot.
966888
/// \param IterNumber The serial number of the iteration currently being
@@ -1332,11 +1254,6 @@ bool llvm::peelLoop(Loop *L, unsigned PeelCount, bool PeelLast, LoopInfo *LI,
13321254
Instruction *LatchTerm =
13331255
cast<Instruction>(cast<BasicBlock>(Latch)->getTerminator());
13341256

1335-
// If we have branch weight information, we'll want to update it for the
1336-
// newly created branches.
1337-
DenseMap<Instruction *, WeightInfo> Weights;
1338-
initBranchWeights(Weights, L);
1339-
13401257
// Identify what noalias metadata is inside the loop: if it is inside the
13411258
// loop, the associated metadata must be cloned for each iteration.
13421259
SmallVector<MDNode *, 6> LoopLocalNoAliasDeclScopes;
@@ -1382,11 +1299,6 @@ bool llvm::peelLoop(Loop *L, unsigned PeelCount, bool PeelLast, LoopInfo *LI,
13821299
assert(DT.verify(DominatorTree::VerificationLevel::Fast));
13831300
#endif
13841301

1385-
for (auto &[Term, Info] : Weights) {
1386-
auto *TermCopy = cast<Instruction>(VMap[Term]);
1387-
updateBranchWeights(TermCopy, Info);
1388-
}
1389-
13901302
// Remove Loop metadata from the latch branch instruction
13911303
// because it is not the Loop's latch branch anymore.
13921304
auto *LatchTermCopy = cast<Instruction>(VMap[LatchTerm]);
@@ -1426,15 +1338,38 @@ bool llvm::peelLoop(Loop *L, unsigned PeelCount, bool PeelLast, LoopInfo *LI,
14261338
}
14271339
}
14281340

1429-
for (const auto &[Term, Info] : Weights) {
1430-
setBranchWeights(*Term, Info.Weights, /*IsExpected=*/false);
1431-
}
1432-
14331341
// Update Metadata for count of peeled off iterations.
14341342
unsigned AlreadyPeeled = 0;
14351343
if (auto Peeled = getOptionalIntLoopAttribute(L, PeeledCountMetaData))
14361344
AlreadyPeeled = *Peeled;
1437-
addStringMetadataToLoop(L, PeeledCountMetaData, AlreadyPeeled + PeelCount);
1345+
unsigned TotalPeeled = AlreadyPeeled + PeelCount;
1346+
addStringMetadataToLoop(L, PeeledCountMetaData, TotalPeeled);
1347+
1348+
// Update metadata for the estimated trip count. The original branch weight
1349+
// metadata is already correct for both the remaining loop and the peeled loop
1350+
// iterations, so do not adjust it.
1351+
//
1352+
// For example, consider what happens when peeling 2 iterations from a loop
1353+
// with an estimated trip count of 10 and inserting them before the remaining
1354+
// loop. Each of the peeled iterations and each iteration in the remaining
1355+
// loop still has the same probability of exiting the *entire original* loop
1356+
// as it did when in the original loop, and thus it should still have the same
1357+
// branch weights. The peeled iterations' non-zero probabilities of exiting
1358+
// already appropriately reduce the probability of reaching the remaining
1359+
// iterations just as they did in the original loop. Trying to also adjust
1360+
// the remaining loop's branch weights to reflect its new trip count of 8 will
1361+
// erroneously further reduce its block frequencies. However, in case an
1362+
// analysis later needs to determine the trip count of the remaining loop
1363+
// while examining it in isolation without considering the probability of
1364+
// actually reaching it, we store the new trip count as separate metadata.
1365+
if (auto EstimatedTripCount = getLoopEstimatedTripCount(L)) {
1366+
unsigned EstimatedTripCountNew = *EstimatedTripCount;
1367+
if (EstimatedTripCountNew < TotalPeeled)
1368+
EstimatedTripCountNew = 0;
1369+
else
1370+
EstimatedTripCountNew -= TotalPeeled;
1371+
setLoopEstimatedTripCount(L, EstimatedTripCountNew);
1372+
}
14381373

14391374
if (Loop *ParentLoop = L->getParentLoop())
14401375
L = ParentLoop;
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
; Test branch weight metadata, estimated trip count metadata, and block
2+
; frequencies after loop peeling.
3+
4+
; RUN: opt < %s -S -passes='print<block-freq>' 2>&1 | \
5+
; RUN: FileCheck -check-prefix=CHECK %s
6+
7+
; The -implicit-check-not options make sure that no additional labels or calls
8+
; to @f show up.
9+
; RUN: opt < %s -S -passes='loop-unroll,print<block-freq>' \
10+
; RUN: -unroll-force-peel-count=2 2>&1 | \
11+
; RUN: FileCheck %s -check-prefix=CHECK-UR \
12+
; RUN: -implicit-check-not='{{^[^ ;]*:}}' \
13+
; RUN: -implicit-check-not='call void @f'
14+
15+
; CHECK: block-frequency-info: test
16+
; CHECK: do.body: float = 10.0,
17+
18+
; The sum should still be ~10.
19+
;
20+
; CHECK-UR: block-frequency-info: test
21+
; CHECK-UR: - [[DO_BODY_PEEL:.*]]: float = 1.0,
22+
; CHECK-UR: - [[DO_BODY_PEEL2:.*]]: float = 0.9,
23+
; CHECK-UR: - [[DO_BODY:.*]]: float = 8.1,
24+
25+
declare void @f(i32)
26+
27+
define void @test(i32 %n) {
28+
; CHECK-UR-LABEL: define void @test(
29+
; CHECK-UR: [[ENTRY:.*]]:
30+
; CHECK-UR: br label %[[DO_BODY_PEEL_BEGIN:.*]]
31+
; CHECK-UR: [[DO_BODY_PEEL_BEGIN]]:
32+
; CHECK-UR: br label %[[DO_BODY_PEEL:.*]]
33+
; CHECK-UR: [[DO_BODY_PEEL]]:
34+
; CHECK-UR: call void @f
35+
; CHECK-UR: br i1 %{{.*}}, label %[[DO_END:.*]], label %[[DO_BODY_PEEL_NEXT:.*]], !prof ![[#PROF:]]
36+
; CHECK-UR: [[DO_BODY_PEEL_NEXT]]:
37+
; CHECK-UR: br label %[[DO_BODY_PEEL2:.*]]
38+
; CHECK-UR: [[DO_BODY_PEEL2]]:
39+
; CHECK-UR: call void @f
40+
; CHECK-UR: br i1 %{{.*}}, label %[[DO_END]], label %[[DO_BODY_PEEL_NEXT1:.*]], !prof ![[#PROF]]
41+
; CHECK-UR: [[DO_BODY_PEEL_NEXT1]]:
42+
; CHECK-UR: br label %[[DO_BODY_PEEL_NEXT5:.*]]
43+
; CHECK-UR: [[DO_BODY_PEEL_NEXT5]]:
44+
; CHECK-UR: br label %[[ENTRY_PEEL_NEWPH:.*]]
45+
; CHECK-UR: [[ENTRY_PEEL_NEWPH]]:
46+
; CHECK-UR: br label %[[DO_BODY]]
47+
; CHECK-UR: [[DO_BODY]]:
48+
; CHECK-UR: call void @f
49+
; CHECK-UR: br i1 %{{.*}}, label %[[DO_END_LOOPEXIT:.*]], label %[[DO_BODY]], !prof ![[#PROF]], !llvm.loop ![[#LOOP_UR_LATCH:]]
50+
; CHECK-UR: [[DO_END_LOOPEXIT]]:
51+
; CHECK-UR: br label %[[DO_END]]
52+
; CHECK-UR: [[DO_END]]:
53+
; CHECK-UR: ret void
54+
55+
entry:
56+
br label %do.body
57+
58+
do.body:
59+
%i = phi i32 [ 0, %entry ], [ %inc, %do.body ]
60+
%inc = add i32 %i, 1
61+
call void @f(i32 %i)
62+
%c = icmp sge i32 %inc, %n
63+
br i1 %c, label %do.end, label %do.body, !prof !0
64+
65+
do.end:
66+
ret void
67+
}
68+
69+
!0 = !{!"branch_weights", i32 1, i32 9}
70+
71+
; CHECK-UR: ![[#PROF]] = !{!"branch_weights", i32 1, i32 9}
72+
; CHECK-UR: ![[#LOOP_UR_LATCH]] = distinct !{![[#LOOP_UR_LATCH]], ![[#LOOP_UR_PC:]], ![[#LOOP_UR_TC:]], ![[#DISABLE:]]}
73+
; CHECK-UR: ![[#LOOP_UR_PC]] = !{!"llvm.loop.peeled.count", i32 2}
74+
; CHECK-UR: ![[#LOOP_UR_TC]] = !{!"llvm.loop.estimated_trip_count", i32 8}
75+
; CHECK-UR: ![[#DISABLE]] = !{!"llvm.loop.unroll.disable"}

llvm/test/Transforms/LoopUnroll/peel-branch-weights.ll

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ define void @test() {
1515
; CHECK: loop.peel:
1616
; CHECK-NEXT: [[X_PEEL:%.*]] = call i32 @get.x()
1717
; CHECK-NEXT: switch i32 [[X_PEEL]], label [[LOOP_LATCH_PEEL:%.*]] [
18-
; CHECK-NEXT: i32 0, label [[LOOP_LATCH_PEEL]]
19-
; CHECK-NEXT: i32 1, label [[LOOP_EXIT:%.*]]
20-
; CHECK-NEXT: i32 2, label [[LOOP_EXIT]]
18+
; CHECK-NEXT: i32 0, label [[LOOP_LATCH_PEEL]]
19+
; CHECK-NEXT: i32 1, label [[LOOP_EXIT:%.*]]
20+
; CHECK-NEXT: i32 2, label [[LOOP_EXIT]]
2121
; CHECK-NEXT: ], !prof [[PROF0:![0-9]+]]
2222
; CHECK: loop.latch.peel:
2323
; CHECK-NEXT: br label [[LOOP_PEEL_NEXT:%.*]]
@@ -26,10 +26,10 @@ define void @test() {
2626
; CHECK: loop.peel2:
2727
; CHECK-NEXT: [[X_PEEL3:%.*]] = call i32 @get.x()
2828
; CHECK-NEXT: switch i32 [[X_PEEL3]], label [[LOOP_LATCH_PEEL4:%.*]] [
29-
; CHECK-NEXT: i32 0, label [[LOOP_LATCH_PEEL4]]
30-
; CHECK-NEXT: i32 1, label [[LOOP_EXIT]]
31-
; CHECK-NEXT: i32 2, label [[LOOP_EXIT]]
32-
; CHECK-NEXT: ], !prof [[PROF1:![0-9]+]]
29+
; CHECK-NEXT: i32 0, label [[LOOP_LATCH_PEEL4]]
30+
; CHECK-NEXT: i32 1, label [[LOOP_EXIT]]
31+
; CHECK-NEXT: i32 2, label [[LOOP_EXIT]]
32+
; CHECK-NEXT: ], !prof [[PROF0]]
3333
; CHECK: loop.latch.peel4:
3434
; CHECK-NEXT: br label [[LOOP_PEEL_NEXT1:%.*]]
3535
; CHECK: loop.peel.next1:
@@ -41,31 +41,33 @@ define void @test() {
4141
; CHECK: loop:
4242
; CHECK-NEXT: [[X:%.*]] = call i32 @get.x()
4343
; CHECK-NEXT: switch i32 [[X]], label [[LOOP_LATCH:%.*]] [
44-
; CHECK-NEXT: i32 0, label [[LOOP_LATCH]]
45-
; CHECK-NEXT: i32 1, label [[LOOP_EXIT_LOOPEXIT:%.*]]
46-
; CHECK-NEXT: i32 2, label [[LOOP_EXIT_LOOPEXIT]]
47-
; CHECK-NEXT: ], !prof [[PROF2:![0-9]+]]
44+
; CHECK-NEXT: i32 0, label [[LOOP_LATCH]]
45+
; CHECK-NEXT: i32 1, label [[LOOP_EXIT_LOOPEXIT:%.*]]
46+
; CHECK-NEXT: i32 2, label [[LOOP_EXIT_LOOPEXIT]]
47+
; CHECK-NEXT: ], !prof [[PROF0]]
4848
; CHECK: loop.latch:
49-
; CHECK-NEXT: br label [[LOOP]], !llvm.loop [[LOOP3:![0-9]+]]
49+
; CHECK-NEXT: br label [[LOOP]], !llvm.loop [[LOOP1:![0-9]+]]
5050
; CHECK: loop.exit.loopexit:
5151
; CHECK-NEXT: br label [[LOOP_EXIT]]
5252
; CHECK: loop.exit:
5353
; CHECK-NEXT: ret void
54+
;
55+
; DISABLEADV-LABEL: @test(
56+
; DISABLEADV-NEXT: entry:
57+
; DISABLEADV-NEXT: br label [[LOOP:%.*]]
58+
; DISABLEADV: loop:
59+
; DISABLEADV-NEXT: [[X:%.*]] = call i32 @get.x()
60+
; DISABLEADV-NEXT: switch i32 [[X]], label [[LOOP_LATCH:%.*]] [
61+
; DISABLEADV-NEXT: i32 0, label [[LOOP_LATCH]]
62+
; DISABLEADV-NEXT: i32 1, label [[LOOP_EXIT:%.*]]
63+
; DISABLEADV-NEXT: i32 2, label [[LOOP_EXIT]]
64+
; DISABLEADV-NEXT: ], !prof [[PROF0:![0-9]+]]
65+
; DISABLEADV: loop.latch:
66+
; DISABLEADV-NEXT: br label [[LOOP]]
67+
; DISABLEADV: loop.exit:
68+
; DISABLEADV-NEXT: ret void
69+
;
5470

55-
; DISABLEADV-LABEL: @test()
56-
; DISABLEADV-NEXT: entry:
57-
; DISABLEADV-NEXT: br label %loop
58-
; DISABLEADV: loop
59-
; DISABLEADV-NEXT: %x = call i32 @get.x()
60-
; DISABLEADV-NEXT: switch i32 %x, label %loop.latch [
61-
; DISABLEADV-NEXT: i32 0, label %loop.latch
62-
; DISABLEADV-NEXT: i32 1, label %loop.exit
63-
; DISABLEADV-NEXT: i32 2, label %loop.exit
64-
; DISABLEADV-NEXT: ], !prof !0
65-
; DISABLEADV: loop.latch:
66-
; DISABLEADV-NEXT: br label %loop
67-
; DISABLEADV: loop.exit:
68-
; DISABLEADV-NEXT: ret void
6971

7072
entry:
7173
br label %loop
@@ -89,9 +91,9 @@ loop.exit:
8991

9092
;.
9193
; CHECK: [[PROF0]] = !{!"branch_weights", i32 100, i32 200, i32 20, i32 10}
92-
; CHECK: [[PROF1]] = !{!"branch_weights", i32 90, i32 180, i32 20, i32 10}
93-
; CHECK: [[PROF2]] = !{!"branch_weights", i32 80, i32 160, i32 20, i32 10}
94-
; CHECK: [[LOOP3]] = distinct !{!3, !4, !5}
95-
; CHECK: [[META4:![0-9]+]] = !{!"llvm.loop.peeled.count", i32 2}
96-
; CHECK: [[META5:![0-9]+]] = !{!"llvm.loop.unroll.disable"}
94+
; CHECK: [[LOOP1]] = distinct !{[[LOOP1]], [[META2:![0-9]+]], [[META3:![0-9]+]]}
95+
; CHECK: [[META2]] = !{!"llvm.loop.peeled.count", i32 2}
96+
; CHECK: [[META3]] = !{!"llvm.loop.unroll.disable"}
97+
;.
98+
; DISABLEADV: [[PROF0]] = !{!"branch_weights", i32 100, i32 200, i32 20, i32 10}
9799
;.

llvm/test/Transforms/LoopUnroll/peel-loop-pgo-deopt.ll

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@
1515
; CHECK: br i1 %{{.*}}, label %[[NEXT0:.*]], label %for.cond.for.end_crit_edge, !prof !16
1616
; CHECK: [[NEXT0]]:
1717
; CHECK: br i1 %c, label %{{.*}}, label %side_exit, !prof !15
18-
; CHECK: br i1 %{{.*}}, label %[[NEXT1:.*]], label %for.cond.for.end_crit_edge, !prof !17
18+
; CHECK: br i1 %{{.*}}, label %[[NEXT1:.*]], label %for.cond.for.end_crit_edge, !prof !16
1919
; CHECK: [[NEXT1]]:
2020
; CHECK: br i1 %c, label %{{.*}}, label %side_exit, !prof !15
21-
; CHECK: br i1 %{{.*}}, label %[[NEXT2:.*]], label %for.cond.for.end_crit_edge, !prof !18
21+
; CHECK: br i1 %{{.*}}, label %[[NEXT2:.*]], label %for.cond.for.end_crit_edge, !prof !16
2222
; CHECK: [[NEXT2]]:
2323
; CHECK: br i1 %c, label %{{.*}}, label %side_exit.loopexit, !prof !15
24-
; CHECK: br i1 %{{.*}}, label %for.body, label %{{.*}}, !prof !18
24+
; CHECK: br i1 %{{.*}}, label %for.body, label %{{.*}}, !prof !16, !llvm.loop !17
2525

2626
define i32 @basic(ptr %p, i32 %k, i1 %c) #0 !prof !15 {
2727
entry:
@@ -84,6 +84,7 @@ attributes #1 = { nounwind optsize }
8484
;CHECK: !15 = !{!"branch_weights", i32 1, i32 0}
8585
; This is a weights of latch and its copies.
8686
;CHECK: !16 = !{!"branch_weights", i32 3001, i32 1001}
87-
;CHECK: !17 = !{!"branch_weights", i32 2000, i32 1001}
88-
;CHECK: !18 = !{!"branch_weights", i32 1001, i32 1001}
87+
;CHECK: !17 = distinct !{!17, !18, !19, {{.*}}}
88+
;CHECK: !18 = !{!"llvm.loop.peeled.count", i32 4}
89+
;CHECK: !19 = !{!"llvm.loop.estimated_trip_count", i32 0}
8990

llvm/test/Transforms/LoopUnroll/peel-loop-pgo.ll

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
; RUN: opt < %s -S -profile-summary-huge-working-set-size-threshold=9 -debug-only=loop-unroll -passes='require<profile-summary>,function(require<opt-remark-emit>,loop-unroll)' 2>&1 | FileCheck %s --check-prefix=NOPEEL
66
; REQUIRES: asserts
77

8-
; Make sure we use the profile information correctly to peel-off 3 iterations
8+
; Make sure we use the profile information correctly to peel-off 4 iterations
99
; from the loop, and update the branch weights for the peeled loop properly.
1010

1111
; CHECK: Loop Unroll: F[basic]
@@ -20,11 +20,11 @@
2020
; CHECK-LABEL: @basic
2121
; CHECK: br i1 %{{.*}}, label %[[NEXT0:.*]], label %for.cond.for.end_crit_edge, !prof !15
2222
; CHECK: [[NEXT0]]:
23-
; CHECK: br i1 %{{.*}}, label %[[NEXT1:.*]], label %for.cond.for.end_crit_edge, !prof !16
23+
; CHECK: br i1 %{{.*}}, label %[[NEXT1:.*]], label %for.cond.for.end_crit_edge, !prof !15
2424
; CHECK: [[NEXT1]]:
25-
; CHECK: br i1 %{{.*}}, label %[[NEXT2:.*]], label %for.cond.for.end_crit_edge, !prof !17
25+
; CHECK: br i1 %{{.*}}, label %[[NEXT2:.*]], label %for.cond.for.end_crit_edge, !prof !15
2626
; CHECK: [[NEXT2]]:
27-
; CHECK: br i1 %{{.*}}, label %for.body, label %{{.*}}, !prof !17
27+
; CHECK: br i1 %{{.*}}, label %for.body, label %{{.*}}, !prof !15, !llvm.loop !16
2828

2929
define void @basic(ptr %p, i32 %k) #0 !prof !15 {
3030
entry:
@@ -104,6 +104,7 @@ attributes #1 = { nounwind optsize }
104104
!16 = !{!"branch_weights", i32 3001, i32 1001}
105105

106106
;CHECK: !15 = !{!"branch_weights", i32 3001, i32 1001}
107-
;CHECK: !16 = !{!"branch_weights", i32 2000, i32 1001}
108-
;CHECK: !17 = !{!"branch_weights", i32 1001, i32 1001}
107+
;CHECK: !16 = distinct !{!16, !17, !18, {{.*}}}
108+
;CHECK: !17 = !{!"llvm.loop.peeled.count", i32 4}
109+
;CHECK: !18 = !{!"llvm.loop.estimated_trip_count", i32 0}
109110

0 commit comments

Comments
 (0)