Skip to content

Commit 9b7e1ba

Browse files
committed
[LoopPredication] Fix division by zero in case of zero branch weights
Treat the case where all branch weights are zero as if there was no profile. Fixes #66382
1 parent c464896 commit 9b7e1ba

File tree

3 files changed

+282
-1
lines changed

3 files changed

+282
-1
lines changed

llvm/lib/Transforms/Scalar/LoopPredication.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,9 @@ bool LoopPredication::isLoopProfitableToPredicate() {
967967
Numerator += Weight;
968968
Denominator += Weight;
969969
}
970+
// If all weights are zero act as if there was no profile data
971+
if (Denominator == 0)
972+
return BranchProbability::getBranchProbability(1, NumSucc);
970973
return BranchProbability::getBranchProbability(Numerator, Denominator);
971974
} else {
972975
assert(LatchBlock != ExitingBlock &&

llvm/test/Transforms/LoopPredication/pr66382.ll

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,31 @@
1-
; XFAIL: *
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
22
; RUN: opt -S -loop-predication-skip-profitability-checks=false -passes='require<scalar-evolution>,loop-mssa(loop-predication)' %s | FileCheck %s
33

44
target triple = "x86_64-unknown-linux-gnu"
55

66
; Function Attrs: nocallback nofree nosync willreturn
77
declare void @llvm.experimental.guard(i1, ...) #0
88

9+
; Check that LoopPredication doesn't crash on all-zero branch weights
910
define void @foo() {
11+
; CHECK-LABEL: define void @foo() {
12+
; CHECK-NEXT: entry:
13+
; CHECK-NEXT: br label [[HEADER:%.*]]
14+
; CHECK: Header:
15+
; CHECK-NEXT: [[J2:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[J_NEXT:%.*]], [[LATCH:%.*]] ]
16+
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 false, i32 0) [ "deopt"() ]
17+
; CHECK-NEXT: [[J_NEXT]] = add i64 [[J2]], 1
18+
; CHECK-NEXT: br i1 false, label [[LATCH]], label [[EXIT:%.*]]
19+
; CHECK: Latch:
20+
; CHECK-NEXT: [[SPECULATE_TRIP_COUNT:%.*]] = icmp ult i64 [[J2]], 0
21+
; CHECK-NEXT: br i1 [[SPECULATE_TRIP_COUNT]], label [[HEADER]], label [[COMMON_RET_LOOPEXIT:%.*]], !prof [[PROF0:![0-9]+]]
22+
; CHECK: common.ret.loopexit:
23+
; CHECK-NEXT: br label [[COMMON_RET:%.*]]
24+
; CHECK: common.ret:
25+
; CHECK-NEXT: ret void
26+
; CHECK: exit:
27+
; CHECK-NEXT: br label [[COMMON_RET]]
28+
;
1029
entry:
1130
br label %Header
1231

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
2+
; RUN: opt -S -loop-predication-skip-profitability-checks=false -passes='require<scalar-evolution>,loop-mssa(loop-predication)' -verify-memoryssa -loop-predication-latch-probability-scale=2 %s 2>&1 | FileCheck %s --check-prefixes=CHECK-PROF
3+
; RUN: opt -S -loop-predication-skip-profitability-checks=false -passes='require<scalar-evolution>,loop-mssa(loop-predication)' -verify-memoryssa -loop-predication-latch-probability-scale=1.9 %s 2>&1 | FileCheck %s --check-prefixes=CHECK-NOTPROF
4+
5+
; LatchExitProbability: 0x20000000 / 0x80000000 = 25.00%
6+
; ExitingBlockProbability: 0x40000000 / 0x80000000 = 50.00%
7+
; Predicate is profitable when the scale factor is 2 and not profitable if it's less than 2.
8+
define i64 @predicate_eq_ones(ptr nocapture readonly %arg, i32 %length, ptr nocapture readonly %arg2, ptr nocapture readonly %n_addr, i64 %i) !prof !21 {
9+
; CHECK-PROF-LABEL: define i64 @predicate_eq_ones(
10+
; CHECK-PROF-SAME: ptr nocapture readonly [[ARG:%.*]], i32 [[LENGTH:%.*]], ptr nocapture readonly [[ARG2:%.*]], ptr nocapture readonly [[N_ADDR:%.*]], i64 [[I:%.*]]) !prof [[PROF0:![0-9]+]] {
11+
; CHECK-PROF-NEXT: entry:
12+
; CHECK-PROF-NEXT: [[LENGTH_EXT:%.*]] = zext i32 [[LENGTH]] to i64
13+
; CHECK-PROF-NEXT: [[N_PRE:%.*]] = load i64, ptr [[N_ADDR]], align 4
14+
; CHECK-PROF-NEXT: [[TMP0:%.*]] = icmp ule i64 1048576, [[LENGTH_EXT]]
15+
; CHECK-PROF-NEXT: [[TMP1:%.*]] = icmp ult i64 0, [[LENGTH_EXT]]
16+
; CHECK-PROF-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
17+
; CHECK-PROF-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]]
18+
; CHECK-PROF-NEXT: br label [[HEADER:%.*]]
19+
; CHECK-PROF: Header:
20+
; CHECK-PROF-NEXT: [[RESULT_IN3:%.*]] = phi ptr [ [[ARG2]], [[ENTRY:%.*]] ], [ [[ARG]], [[LATCH:%.*]] ]
21+
; CHECK-PROF-NEXT: [[J2:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[J_NEXT:%.*]], [[LATCH]] ]
22+
; CHECK-PROF-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i64 [[J2]], [[LENGTH_EXT]]
23+
; CHECK-PROF-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
24+
; CHECK-PROF-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
25+
; CHECK-PROF-NEXT: [[INNERCMP:%.*]] = icmp eq i64 [[J2]], [[N_PRE]]
26+
; CHECK-PROF-NEXT: [[J_NEXT]] = add nuw nsw i64 [[J2]], 1
27+
; CHECK-PROF-NEXT: br i1 [[INNERCMP]], label [[LATCH]], label [[EXIT:%.*]], !prof [[PROF1:![0-9]+]]
28+
; CHECK-PROF: Latch:
29+
; CHECK-PROF-NEXT: [[SPECULATE_TRIP_COUNT:%.*]] = icmp ult i64 [[J_NEXT]], 1048576
30+
; CHECK-PROF-NEXT: br i1 [[SPECULATE_TRIP_COUNT]], label [[HEADER]], label [[EXITLATCH:%.*]], !prof [[PROF2:![0-9]+]]
31+
; CHECK-PROF: exitLatch:
32+
; CHECK-PROF-NEXT: ret i64 1
33+
; CHECK-PROF: exit:
34+
; CHECK-PROF-NEXT: [[RESULT_IN3_LCSSA:%.*]] = phi ptr [ [[RESULT_IN3]], [[HEADER]] ]
35+
; CHECK-PROF-NEXT: [[RESULT_LE:%.*]] = load i64, ptr [[RESULT_IN3_LCSSA]], align 8
36+
; CHECK-PROF-NEXT: ret i64 [[RESULT_LE]]
37+
;
38+
; CHECK-NOTPROF-LABEL: define i64 @predicate_eq_ones(
39+
; CHECK-NOTPROF-SAME: ptr nocapture readonly [[ARG:%.*]], i32 [[LENGTH:%.*]], ptr nocapture readonly [[ARG2:%.*]], ptr nocapture readonly [[N_ADDR:%.*]], i64 [[I:%.*]]) !prof [[PROF0:![0-9]+]] {
40+
; CHECK-NOTPROF-NEXT: entry:
41+
; CHECK-NOTPROF-NEXT: [[LENGTH_EXT:%.*]] = zext i32 [[LENGTH]] to i64
42+
; CHECK-NOTPROF-NEXT: [[N_PRE:%.*]] = load i64, ptr [[N_ADDR]], align 4
43+
; CHECK-NOTPROF-NEXT: br label [[HEADER:%.*]]
44+
; CHECK-NOTPROF: Header:
45+
; CHECK-NOTPROF-NEXT: [[RESULT_IN3:%.*]] = phi ptr [ [[ARG2]], [[ENTRY:%.*]] ], [ [[ARG]], [[LATCH:%.*]] ]
46+
; CHECK-NOTPROF-NEXT: [[J2:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[J_NEXT:%.*]], [[LATCH]] ]
47+
; CHECK-NOTPROF-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i64 [[J2]], [[LENGTH_EXT]]
48+
; CHECK-NOTPROF-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
49+
; CHECK-NOTPROF-NEXT: [[INNERCMP:%.*]] = icmp eq i64 [[J2]], [[N_PRE]]
50+
; CHECK-NOTPROF-NEXT: [[J_NEXT]] = add nuw nsw i64 [[J2]], 1
51+
; CHECK-NOTPROF-NEXT: br i1 [[INNERCMP]], label [[LATCH]], label [[EXIT:%.*]], !prof [[PROF1:![0-9]+]]
52+
; CHECK-NOTPROF: Latch:
53+
; CHECK-NOTPROF-NEXT: [[SPECULATE_TRIP_COUNT:%.*]] = icmp ult i64 [[J_NEXT]], 1048576
54+
; CHECK-NOTPROF-NEXT: br i1 [[SPECULATE_TRIP_COUNT]], label [[HEADER]], label [[EXITLATCH:%.*]], !prof [[PROF2:![0-9]+]]
55+
; CHECK-NOTPROF: exitLatch:
56+
; CHECK-NOTPROF-NEXT: ret i64 1
57+
; CHECK-NOTPROF: exit:
58+
; CHECK-NOTPROF-NEXT: [[RESULT_IN3_LCSSA:%.*]] = phi ptr [ [[RESULT_IN3]], [[HEADER]] ]
59+
; CHECK-NOTPROF-NEXT: [[RESULT_LE:%.*]] = load i64, ptr [[RESULT_IN3_LCSSA]], align 8
60+
; CHECK-NOTPROF-NEXT: ret i64 [[RESULT_LE]]
61+
;
62+
entry:
63+
%length.ext = zext i32 %length to i64
64+
%n.pre = load i64, ptr %n_addr, align 4
65+
br label %Header
66+
67+
Header: ; preds = %entry, %Latch
68+
%result.in3 = phi ptr [ %arg2, %entry ], [ %arg, %Latch ]
69+
%j2 = phi i64 [ 0, %entry ], [ %j.next, %Latch ]
70+
%within.bounds = icmp ult i64 %j2, %length.ext
71+
call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
72+
%innercmp = icmp eq i64 %j2, %n.pre
73+
%j.next = add nuw nsw i64 %j2, 1
74+
br i1 %innercmp, label %Latch, label %exit, !prof !0
75+
76+
Latch: ; preds = %Header
77+
%speculate_trip_count = icmp ult i64 %j.next, 1048576
78+
br i1 %speculate_trip_count, label %Header, label %exitLatch, !prof !2
79+
80+
exitLatch: ; preds = %Latch
81+
ret i64 1
82+
83+
exit: ; preds = %Header
84+
%result.in3.lcssa = phi ptr [ %result.in3, %Header ]
85+
%result.le = load i64, ptr %result.in3.lcssa, align 8
86+
ret i64 %result.le
87+
}
88+
!0 = !{!"branch_weights", i32 1, i32 1}
89+
90+
; Same as the previous one, but with zero weights (should be treated as if no profile - equal probability)
91+
define i64 @predicate_eq_zeroes(ptr nocapture readonly %arg, i32 %length, ptr nocapture readonly %arg2, ptr nocapture readonly %n_addr, i64 %i) !prof !21 {
92+
; CHECK-PROF-LABEL: define i64 @predicate_eq_zeroes(
93+
; CHECK-PROF-SAME: ptr nocapture readonly [[ARG:%.*]], i32 [[LENGTH:%.*]], ptr nocapture readonly [[ARG2:%.*]], ptr nocapture readonly [[N_ADDR:%.*]], i64 [[I:%.*]]) !prof [[PROF0]] {
94+
; CHECK-PROF-NEXT: entry:
95+
; CHECK-PROF-NEXT: [[LENGTH_EXT:%.*]] = zext i32 [[LENGTH]] to i64
96+
; CHECK-PROF-NEXT: [[N_PRE:%.*]] = load i64, ptr [[N_ADDR]], align 4
97+
; CHECK-PROF-NEXT: [[TMP0:%.*]] = icmp ule i64 1048576, [[LENGTH_EXT]]
98+
; CHECK-PROF-NEXT: [[TMP1:%.*]] = icmp ult i64 0, [[LENGTH_EXT]]
99+
; CHECK-PROF-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
100+
; CHECK-PROF-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]]
101+
; CHECK-PROF-NEXT: br label [[HEADER:%.*]]
102+
; CHECK-PROF: Header:
103+
; CHECK-PROF-NEXT: [[RESULT_IN3:%.*]] = phi ptr [ [[ARG2]], [[ENTRY:%.*]] ], [ [[ARG]], [[LATCH:%.*]] ]
104+
; CHECK-PROF-NEXT: [[J2:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[J_NEXT:%.*]], [[LATCH]] ]
105+
; CHECK-PROF-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i64 [[J2]], [[LENGTH_EXT]]
106+
; CHECK-PROF-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
107+
; CHECK-PROF-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
108+
; CHECK-PROF-NEXT: [[INNERCMP:%.*]] = icmp eq i64 [[J2]], [[N_PRE]]
109+
; CHECK-PROF-NEXT: [[J_NEXT]] = add nuw nsw i64 [[J2]], 1
110+
; CHECK-PROF-NEXT: br i1 [[INNERCMP]], label [[LATCH]], label [[EXIT:%.*]], !prof [[PROF3:![0-9]+]]
111+
; CHECK-PROF: Latch:
112+
; CHECK-PROF-NEXT: [[SPECULATE_TRIP_COUNT:%.*]] = icmp ult i64 [[J_NEXT]], 1048576
113+
; CHECK-PROF-NEXT: br i1 [[SPECULATE_TRIP_COUNT]], label [[HEADER]], label [[EXITLATCH:%.*]], !prof [[PROF2]]
114+
; CHECK-PROF: exitLatch:
115+
; CHECK-PROF-NEXT: ret i64 1
116+
; CHECK-PROF: exit:
117+
; CHECK-PROF-NEXT: [[RESULT_IN3_LCSSA:%.*]] = phi ptr [ [[RESULT_IN3]], [[HEADER]] ]
118+
; CHECK-PROF-NEXT: [[RESULT_LE:%.*]] = load i64, ptr [[RESULT_IN3_LCSSA]], align 8
119+
; CHECK-PROF-NEXT: ret i64 [[RESULT_LE]]
120+
;
121+
; CHECK-NOTPROF-LABEL: define i64 @predicate_eq_zeroes(
122+
; CHECK-NOTPROF-SAME: ptr nocapture readonly [[ARG:%.*]], i32 [[LENGTH:%.*]], ptr nocapture readonly [[ARG2:%.*]], ptr nocapture readonly [[N_ADDR:%.*]], i64 [[I:%.*]]) !prof [[PROF0]] {
123+
; CHECK-NOTPROF-NEXT: entry:
124+
; CHECK-NOTPROF-NEXT: [[LENGTH_EXT:%.*]] = zext i32 [[LENGTH]] to i64
125+
; CHECK-NOTPROF-NEXT: [[N_PRE:%.*]] = load i64, ptr [[N_ADDR]], align 4
126+
; CHECK-NOTPROF-NEXT: br label [[HEADER:%.*]]
127+
; CHECK-NOTPROF: Header:
128+
; CHECK-NOTPROF-NEXT: [[RESULT_IN3:%.*]] = phi ptr [ [[ARG2]], [[ENTRY:%.*]] ], [ [[ARG]], [[LATCH:%.*]] ]
129+
; CHECK-NOTPROF-NEXT: [[J2:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[J_NEXT:%.*]], [[LATCH]] ]
130+
; CHECK-NOTPROF-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i64 [[J2]], [[LENGTH_EXT]]
131+
; CHECK-NOTPROF-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
132+
; CHECK-NOTPROF-NEXT: [[INNERCMP:%.*]] = icmp eq i64 [[J2]], [[N_PRE]]
133+
; CHECK-NOTPROF-NEXT: [[J_NEXT]] = add nuw nsw i64 [[J2]], 1
134+
; CHECK-NOTPROF-NEXT: br i1 [[INNERCMP]], label [[LATCH]], label [[EXIT:%.*]], !prof [[PROF3:![0-9]+]]
135+
; CHECK-NOTPROF: Latch:
136+
; CHECK-NOTPROF-NEXT: [[SPECULATE_TRIP_COUNT:%.*]] = icmp ult i64 [[J_NEXT]], 1048576
137+
; CHECK-NOTPROF-NEXT: br i1 [[SPECULATE_TRIP_COUNT]], label [[HEADER]], label [[EXITLATCH:%.*]], !prof [[PROF2]]
138+
; CHECK-NOTPROF: exitLatch:
139+
; CHECK-NOTPROF-NEXT: ret i64 1
140+
; CHECK-NOTPROF: exit:
141+
; CHECK-NOTPROF-NEXT: [[RESULT_IN3_LCSSA:%.*]] = phi ptr [ [[RESULT_IN3]], [[HEADER]] ]
142+
; CHECK-NOTPROF-NEXT: [[RESULT_LE:%.*]] = load i64, ptr [[RESULT_IN3_LCSSA]], align 8
143+
; CHECK-NOTPROF-NEXT: ret i64 [[RESULT_LE]]
144+
;
145+
entry:
146+
%length.ext = zext i32 %length to i64
147+
%n.pre = load i64, ptr %n_addr, align 4
148+
br label %Header
149+
150+
Header: ; preds = %entry, %Latch
151+
%result.in3 = phi ptr [ %arg2, %entry ], [ %arg, %Latch ]
152+
%j2 = phi i64 [ 0, %entry ], [ %j.next, %Latch ]
153+
%within.bounds = icmp ult i64 %j2, %length.ext
154+
call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
155+
%innercmp = icmp eq i64 %j2, %n.pre
156+
%j.next = add nuw nsw i64 %j2, 1
157+
br i1 %innercmp, label %Latch, label %exit, !prof !1
158+
159+
Latch: ; preds = %Header
160+
%speculate_trip_count = icmp ult i64 %j.next, 1048576
161+
br i1 %speculate_trip_count, label %Header, label %exitLatch, !prof !2
162+
163+
exitLatch: ; preds = %Latch
164+
ret i64 1
165+
166+
exit: ; preds = %Header
167+
%result.in3.lcssa = phi ptr [ %result.in3, %Header ]
168+
%result.le = load i64, ptr %result.in3.lcssa, align 8
169+
ret i64 %result.le
170+
}
171+
!1 = !{!"branch_weights", i32 0, i32 0}
172+
173+
; No profile on br in Header
174+
define i64 @predicate_eq_none(ptr nocapture readonly %arg, i32 %length, ptr nocapture readonly %arg2, ptr nocapture readonly %n_addr, i64 %i) !prof !21 {
175+
; CHECK-PROF-LABEL: define i64 @predicate_eq_none(
176+
; CHECK-PROF-SAME: ptr nocapture readonly [[ARG:%.*]], i32 [[LENGTH:%.*]], ptr nocapture readonly [[ARG2:%.*]], ptr nocapture readonly [[N_ADDR:%.*]], i64 [[I:%.*]]) !prof [[PROF0]] {
177+
; CHECK-PROF-NEXT: entry:
178+
; CHECK-PROF-NEXT: [[LENGTH_EXT:%.*]] = zext i32 [[LENGTH]] to i64
179+
; CHECK-PROF-NEXT: [[N_PRE:%.*]] = load i64, ptr [[N_ADDR]], align 4
180+
; CHECK-PROF-NEXT: [[TMP0:%.*]] = icmp ule i64 1048576, [[LENGTH_EXT]]
181+
; CHECK-PROF-NEXT: [[TMP1:%.*]] = icmp ult i64 0, [[LENGTH_EXT]]
182+
; CHECK-PROF-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
183+
; CHECK-PROF-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]]
184+
; CHECK-PROF-NEXT: br label [[HEADER:%.*]]
185+
; CHECK-PROF: Header:
186+
; CHECK-PROF-NEXT: [[RESULT_IN3:%.*]] = phi ptr [ [[ARG2]], [[ENTRY:%.*]] ], [ [[ARG]], [[LATCH:%.*]] ]
187+
; CHECK-PROF-NEXT: [[J2:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[J_NEXT:%.*]], [[LATCH]] ]
188+
; CHECK-PROF-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i64 [[J2]], [[LENGTH_EXT]]
189+
; CHECK-PROF-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
190+
; CHECK-PROF-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]])
191+
; CHECK-PROF-NEXT: [[INNERCMP:%.*]] = icmp eq i64 [[J2]], [[N_PRE]]
192+
; CHECK-PROF-NEXT: [[J_NEXT]] = add nuw nsw i64 [[J2]], 1
193+
; CHECK-PROF-NEXT: br i1 [[INNERCMP]], label [[LATCH]], label [[EXIT:%.*]]
194+
; CHECK-PROF: Latch:
195+
; CHECK-PROF-NEXT: [[SPECULATE_TRIP_COUNT:%.*]] = icmp ult i64 [[J_NEXT]], 1048576
196+
; CHECK-PROF-NEXT: br i1 [[SPECULATE_TRIP_COUNT]], label [[HEADER]], label [[EXITLATCH:%.*]], !prof [[PROF2]]
197+
; CHECK-PROF: exitLatch:
198+
; CHECK-PROF-NEXT: ret i64 1
199+
; CHECK-PROF: exit:
200+
; CHECK-PROF-NEXT: [[RESULT_IN3_LCSSA:%.*]] = phi ptr [ [[RESULT_IN3]], [[HEADER]] ]
201+
; CHECK-PROF-NEXT: [[RESULT_LE:%.*]] = load i64, ptr [[RESULT_IN3_LCSSA]], align 8
202+
; CHECK-PROF-NEXT: ret i64 [[RESULT_LE]]
203+
;
204+
; CHECK-NOTPROF-LABEL: define i64 @predicate_eq_none(
205+
; CHECK-NOTPROF-SAME: ptr nocapture readonly [[ARG:%.*]], i32 [[LENGTH:%.*]], ptr nocapture readonly [[ARG2:%.*]], ptr nocapture readonly [[N_ADDR:%.*]], i64 [[I:%.*]]) !prof [[PROF0]] {
206+
; CHECK-NOTPROF-NEXT: entry:
207+
; CHECK-NOTPROF-NEXT: [[LENGTH_EXT:%.*]] = zext i32 [[LENGTH]] to i64
208+
; CHECK-NOTPROF-NEXT: [[N_PRE:%.*]] = load i64, ptr [[N_ADDR]], align 4
209+
; CHECK-NOTPROF-NEXT: br label [[HEADER:%.*]]
210+
; CHECK-NOTPROF: Header:
211+
; CHECK-NOTPROF-NEXT: [[RESULT_IN3:%.*]] = phi ptr [ [[ARG2]], [[ENTRY:%.*]] ], [ [[ARG]], [[LATCH:%.*]] ]
212+
; CHECK-NOTPROF-NEXT: [[J2:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[J_NEXT:%.*]], [[LATCH]] ]
213+
; CHECK-NOTPROF-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i64 [[J2]], [[LENGTH_EXT]]
214+
; CHECK-NOTPROF-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
215+
; CHECK-NOTPROF-NEXT: [[INNERCMP:%.*]] = icmp eq i64 [[J2]], [[N_PRE]]
216+
; CHECK-NOTPROF-NEXT: [[J_NEXT]] = add nuw nsw i64 [[J2]], 1
217+
; CHECK-NOTPROF-NEXT: br i1 [[INNERCMP]], label [[LATCH]], label [[EXIT:%.*]]
218+
; CHECK-NOTPROF: Latch:
219+
; CHECK-NOTPROF-NEXT: [[SPECULATE_TRIP_COUNT:%.*]] = icmp ult i64 [[J_NEXT]], 1048576
220+
; CHECK-NOTPROF-NEXT: br i1 [[SPECULATE_TRIP_COUNT]], label [[HEADER]], label [[EXITLATCH:%.*]], !prof [[PROF2]]
221+
; CHECK-NOTPROF: exitLatch:
222+
; CHECK-NOTPROF-NEXT: ret i64 1
223+
; CHECK-NOTPROF: exit:
224+
; CHECK-NOTPROF-NEXT: [[RESULT_IN3_LCSSA:%.*]] = phi ptr [ [[RESULT_IN3]], [[HEADER]] ]
225+
; CHECK-NOTPROF-NEXT: [[RESULT_LE:%.*]] = load i64, ptr [[RESULT_IN3_LCSSA]], align 8
226+
; CHECK-NOTPROF-NEXT: ret i64 [[RESULT_LE]]
227+
;
228+
entry:
229+
%length.ext = zext i32 %length to i64
230+
%n.pre = load i64, ptr %n_addr, align 4
231+
br label %Header
232+
233+
Header: ; preds = %entry, %Latch
234+
%result.in3 = phi ptr [ %arg2, %entry ], [ %arg, %Latch ]
235+
%j2 = phi i64 [ 0, %entry ], [ %j.next, %Latch ]
236+
%within.bounds = icmp ult i64 %j2, %length.ext
237+
call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
238+
%innercmp = icmp eq i64 %j2, %n.pre
239+
%j.next = add nuw nsw i64 %j2, 1
240+
br i1 %innercmp, label %Latch, label %exit
241+
242+
Latch: ; preds = %Header
243+
%speculate_trip_count = icmp ult i64 %j.next, 1048576
244+
br i1 %speculate_trip_count, label %Header, label %exitLatch, !prof !2
245+
246+
exitLatch: ; preds = %Latch
247+
ret i64 1
248+
249+
exit: ; preds = %Header
250+
%result.in3.lcssa = phi ptr [ %result.in3, %Header ]
251+
%result.le = load i64, ptr %result.in3.lcssa, align 8
252+
ret i64 %result.le
253+
}
254+
255+
!2 = !{!"branch_weights", i32 3, i32 1}
256+
!21 = !{!"function_entry_count", i64 20000}
257+
258+
declare i64 @llvm.experimental.deoptimize.i64(...)
259+
declare void @llvm.experimental.guard(i1, ...)

0 commit comments

Comments
 (0)