Skip to content

Commit 5f17d6f

Browse files
Move some large stack frames off recursive paths. (#8507)
* Remove large stack frames from recursive paths There were several large (>2kb) stack frames on recursive paths, which invites stack overflow. In all cases the code could be moved into a helper function out of the recursive path, eliminating the problem. Some of these stack frames were also shrunk by removing state from the Intrin IR matcher, and removing unnecessary precision in the IsInt and IsUInt IR matchers. Also added IRMatcher helpers for a few more intrinsics Note the tables in HexagonOptimize are unchanged, they just got indented more by being moved into a lambda. * Update ConstantBounds.cpp --------- Co-authored-by: Steven Johnson <[email protected]>
1 parent c3f4de0 commit 5f17d6f

8 files changed

+387
-328
lines changed

src/ConstantBounds.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ ConstantInterval bounds_helper(const Expr &e,
7373
ScopedBinding bind(scope, op->name, recurse(op->value));
7474
return recurse(op->body);
7575
} else if (const Call *op = e.as<Call>()) {
76-
ConstantInterval result;
7776
if (op->is_intrinsic(Call::abs)) {
7877
return abs(recurse(op->args[0]));
7978
} else if (op->is_intrinsic(Call::absd)) {

src/FindIntrinsics.cpp

+16-4
Original file line numberDiff line numberDiff line change
@@ -516,8 +516,12 @@ class FindIntrinsics : public IRMutator {
516516
return IRMutator::visit(op);
517517
}
518518

519-
Expr value = mutate(op->value);
519+
return visit_cast(op, mutate(op->value));
520+
}
520521

522+
// Isolated in its own function to keep the (large) stack frame off the
523+
// recursive path.
524+
HALIDE_NEVER_INLINE Expr visit_cast(const Cast *op, Expr &&value) {
521525
// This mutator can generate redundant casts. We can't use the simplifier because it
522526
// undoes some of the intrinsic lowering here, and it causes some problems due to
523527
// factoring (instead of distributing) constants.
@@ -550,6 +554,7 @@ class FindIntrinsics : public IRMutator {
550554
auto is_x_same_uint = op->type.is_uint() && is_uint(x, bits);
551555
auto is_x_same_int_or_uint = is_x_same_int || is_x_same_uint;
552556
auto x_y_same_sign = (is_int(x) && is_int(y)) || (is_uint(x) && is_uint(y));
557+
553558
if (
554559
// Saturating patterns
555560
rewrite(max(min(widening_add(x, y), upper), lower),
@@ -566,11 +571,11 @@ class FindIntrinsics : public IRMutator {
566571

567572
rewrite(min(widening_add(x, y), upper),
568573
saturating_add(x, y),
569-
op->type.is_uint() && is_x_same_uint) ||
574+
is_x_same_uint) ||
570575

571576
rewrite(max(widening_sub(x, y), lower),
572577
saturating_sub(x, y),
573-
op->type.is_uint() && is_x_same_uint) ||
578+
is_x_same_uint) ||
574579

575580
// Saturating narrow patterns.
576581
rewrite(max(min(x, upper), lower),
@@ -721,10 +726,17 @@ class FindIntrinsics : public IRMutator {
721726
op = mutated.as<Call>();
722727
if (!op) {
723728
return mutated;
729+
} else {
730+
return visit_call(op);
724731
}
732+
}
725733

734+
// Isolated in its own function to keep the (large) stack frame off the
735+
// recursive path. The Call node has already been mutated by the base class
736+
// visitor.
737+
HALIDE_NEVER_INLINE Expr visit_call(const Call *op) {
726738
auto rewrite = IRMatcher::rewriter(op, op->type);
727-
if (rewrite(intrin(Call::abs, widening_sub(x, y)), cast(op->type, intrin(Call::absd, x, y))) ||
739+
if (rewrite(abs(widening_sub(x, y)), cast(op->type, absd(x, y))) ||
728740
false) {
729741
return rewrite.result;
730742
}

src/HexagonOptimize.cpp

+264-248
Large diffs are not rendered by default.

src/IRMatch.h

+89-57
Original file line numberDiff line numberDiff line change
@@ -1325,15 +1325,30 @@ constexpr int const_min(int a, int b) {
13251325
return a < b ? a : b;
13261326
}
13271327

1328-
template<typename... Args>
1328+
template<Call::IntrinsicOp intrin>
1329+
struct OptionalIntrinType {
1330+
bool check(const Type &) const {
1331+
return true;
1332+
}
1333+
};
1334+
1335+
template<>
1336+
struct OptionalIntrinType<Call::saturating_cast> {
1337+
halide_type_t type;
1338+
bool check(const Type &t) const {
1339+
return t == Type(type);
1340+
}
1341+
};
1342+
1343+
template<Call::IntrinsicOp intrin, typename... Args>
13291344
struct Intrin {
13301345
struct pattern_tag {};
1331-
Call::IntrinsicOp intrin;
13321346
std::tuple<Args...> args;
13331347
// The type of the output of the intrinsic node.
13341348
// Only necessary in cases where it can't be inferred
13351349
// from the input types (e.g. saturating_cast).
1336-
Type optional_type_hint;
1350+
1351+
OptionalIntrinType<intrin> optional_type_hint;
13371352

13381353
static constexpr uint32_t binds = bitwise_or_reduce((bindings<Args>::mask)...);
13391354

@@ -1362,7 +1377,7 @@ struct Intrin {
13621377
}
13631378
const Call &c = (const Call &)e;
13641379
return (c.is_intrinsic(intrin) &&
1365-
((optional_type_hint == Type()) || optional_type_hint == e.type) &&
1380+
optional_type_hint.check(e.type) &&
13661381
match_args<0, bound>(0, c, state));
13671382
}
13681383

@@ -1394,8 +1409,8 @@ struct Intrin {
13941409
return likely_if_innermost(std::move(arg0));
13951410
} else if (intrin == Call::abs) {
13961411
return abs(std::move(arg0));
1397-
} else if (intrin == Call::saturating_cast) {
1398-
return saturating_cast(optional_type_hint, std::move(arg0));
1412+
} else if constexpr (intrin == Call::saturating_cast) {
1413+
return saturating_cast(optional_type_hint.type, std::move(arg0));
13991414
}
14001415

14011416
Expr arg1 = std::get<const_min(1, sizeof...(Args) - 1)>(args).make(state, type_hint);
@@ -1489,98 +1504,113 @@ struct Intrin {
14891504
}
14901505

14911506
HALIDE_ALWAYS_INLINE
1492-
Intrin(Call::IntrinsicOp intrin, Args... args) noexcept
1493-
: intrin(intrin), args(args...) {
1507+
Intrin(Args... args) noexcept
1508+
: args(args...) {
14941509
}
14951510
};
14961511

1497-
template<typename... Args>
1498-
std::ostream &operator<<(std::ostream &s, const Intrin<Args...> &op) {
1499-
s << op.intrin << "(";
1512+
template<Call::IntrinsicOp intrin, typename... Args>
1513+
std::ostream &operator<<(std::ostream &s, const Intrin<intrin, Args...> &op) {
1514+
s << intrin << "(";
15001515
op.print_args(s);
15011516
s << ")";
15021517
return s;
15031518
}
15041519

1505-
template<typename... Args>
1506-
HALIDE_ALWAYS_INLINE auto intrin(Call::IntrinsicOp intrinsic_op, Args... args) noexcept -> Intrin<decltype(pattern_arg(args))...> {
1507-
return {intrinsic_op, pattern_arg(args)...};
1508-
}
1509-
15101520
template<typename A, typename B>
1511-
auto widen_right_add(A &&a, B &&b) noexcept -> Intrin<decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1512-
return {Call::widen_right_add, pattern_arg(a), pattern_arg(b)};
1521+
auto widen_right_add(A &&a, B &&b) noexcept -> Intrin<Call::widen_right_add, decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1522+
return {pattern_arg(a), pattern_arg(b)};
15131523
}
15141524
template<typename A, typename B>
1515-
auto widen_right_mul(A &&a, B &&b) noexcept -> Intrin<decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1516-
return {Call::widen_right_mul, pattern_arg(a), pattern_arg(b)};
1525+
auto widen_right_mul(A &&a, B &&b) noexcept -> Intrin<Call::widen_right_mul, decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1526+
return {pattern_arg(a), pattern_arg(b)};
15171527
}
15181528
template<typename A, typename B>
1519-
auto widen_right_sub(A &&a, B &&b) noexcept -> Intrin<decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1520-
return {Call::widen_right_sub, pattern_arg(a), pattern_arg(b)};
1529+
auto widen_right_sub(A &&a, B &&b) noexcept -> Intrin<Call::widen_right_sub, decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1530+
return {pattern_arg(a), pattern_arg(b)};
15211531
}
15221532

15231533
template<typename A, typename B>
1524-
auto widening_add(A &&a, B &&b) noexcept -> Intrin<decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1525-
return {Call::widening_add, pattern_arg(a), pattern_arg(b)};
1534+
auto widening_add(A &&a, B &&b) noexcept -> Intrin<Call::widening_add, decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1535+
return {pattern_arg(a), pattern_arg(b)};
15261536
}
15271537
template<typename A, typename B>
1528-
auto widening_sub(A &&a, B &&b) noexcept -> Intrin<decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1529-
return {Call::widening_sub, pattern_arg(a), pattern_arg(b)};
1538+
auto widening_sub(A &&a, B &&b) noexcept -> Intrin<Call::widening_sub, decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1539+
return {pattern_arg(a), pattern_arg(b)};
15301540
}
15311541
template<typename A, typename B>
1532-
auto widening_mul(A &&a, B &&b) noexcept -> Intrin<decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1533-
return {Call::widening_mul, pattern_arg(a), pattern_arg(b)};
1542+
auto widening_mul(A &&a, B &&b) noexcept -> Intrin<Call::widening_mul, decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1543+
return {pattern_arg(a), pattern_arg(b)};
15341544
}
15351545
template<typename A, typename B>
1536-
auto saturating_add(A &&a, B &&b) noexcept -> Intrin<decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1537-
return {Call::saturating_add, pattern_arg(a), pattern_arg(b)};
1546+
auto saturating_add(A &&a, B &&b) noexcept -> Intrin<Call::saturating_add, decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1547+
return {pattern_arg(a), pattern_arg(b)};
15381548
}
15391549
template<typename A, typename B>
1540-
auto saturating_sub(A &&a, B &&b) noexcept -> Intrin<decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1541-
return {Call::saturating_sub, pattern_arg(a), pattern_arg(b)};
1550+
auto saturating_sub(A &&a, B &&b) noexcept -> Intrin<Call::saturating_sub, decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1551+
return {pattern_arg(a), pattern_arg(b)};
15421552
}
15431553
template<typename A>
1544-
auto saturating_cast(const Type &t, A &&a) noexcept -> Intrin<decltype(pattern_arg(a))> {
1545-
Intrin<decltype(pattern_arg(a))> p = {Call::saturating_cast, pattern_arg(a)};
1546-
p.optional_type_hint = t;
1554+
auto saturating_cast(const Type &t, A &&a) noexcept -> Intrin<Call::saturating_cast, decltype(pattern_arg(a))> {
1555+
Intrin<Call::saturating_cast, decltype(pattern_arg(a))> p = {pattern_arg(a)};
1556+
p.optional_type_hint.type = t;
15471557
return p;
15481558
}
15491559
template<typename A, typename B>
1550-
auto halving_add(A &&a, B &&b) noexcept -> Intrin<decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1551-
return {Call::halving_add, pattern_arg(a), pattern_arg(b)};
1560+
auto halving_add(A &&a, B &&b) noexcept -> Intrin<Call::halving_add, decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1561+
return {pattern_arg(a), pattern_arg(b)};
15521562
}
15531563
template<typename A, typename B>
1554-
auto halving_sub(A &&a, B &&b) noexcept -> Intrin<decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1555-
return {Call::halving_sub, pattern_arg(a), pattern_arg(b)};
1564+
auto halving_sub(A &&a, B &&b) noexcept -> Intrin<Call::halving_sub, decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1565+
return {pattern_arg(a), pattern_arg(b)};
15561566
}
15571567
template<typename A, typename B>
1558-
auto rounding_halving_add(A &&a, B &&b) noexcept -> Intrin<decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1559-
return {Call::rounding_halving_add, pattern_arg(a), pattern_arg(b)};
1568+
auto rounding_halving_add(A &&a, B &&b) noexcept -> Intrin<Call::rounding_halving_add, decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1569+
return {pattern_arg(a), pattern_arg(b)};
15601570
}
15611571
template<typename A, typename B>
1562-
auto shift_left(A &&a, B &&b) noexcept -> Intrin<decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1563-
return {Call::shift_left, pattern_arg(a), pattern_arg(b)};
1572+
auto shift_left(A &&a, B &&b) noexcept -> Intrin<Call::shift_left, decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1573+
return {pattern_arg(a), pattern_arg(b)};
15641574
}
15651575
template<typename A, typename B>
1566-
auto shift_right(A &&a, B &&b) noexcept -> Intrin<decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1567-
return {Call::shift_right, pattern_arg(a), pattern_arg(b)};
1576+
auto shift_right(A &&a, B &&b) noexcept -> Intrin<Call::shift_right, decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1577+
return {pattern_arg(a), pattern_arg(b)};
15681578
}
15691579
template<typename A, typename B>
1570-
auto rounding_shift_left(A &&a, B &&b) noexcept -> Intrin<decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1571-
return {Call::rounding_shift_left, pattern_arg(a), pattern_arg(b)};
1580+
auto rounding_shift_left(A &&a, B &&b) noexcept -> Intrin<Call::rounding_shift_left, decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1581+
return {pattern_arg(a), pattern_arg(b)};
15721582
}
15731583
template<typename A, typename B>
1574-
auto rounding_shift_right(A &&a, B &&b) noexcept -> Intrin<decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1575-
return {Call::rounding_shift_right, pattern_arg(a), pattern_arg(b)};
1584+
auto rounding_shift_right(A &&a, B &&b) noexcept -> Intrin<Call::rounding_shift_right, decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1585+
return {pattern_arg(a), pattern_arg(b)};
15761586
}
15771587
template<typename A, typename B, typename C>
1578-
auto mul_shift_right(A &&a, B &&b, C &&c) noexcept -> Intrin<decltype(pattern_arg(a)), decltype(pattern_arg(b)), decltype(pattern_arg(c))> {
1579-
return {Call::mul_shift_right, pattern_arg(a), pattern_arg(b), pattern_arg(c)};
1588+
auto mul_shift_right(A &&a, B &&b, C &&c) noexcept -> Intrin<Call::mul_shift_right, decltype(pattern_arg(a)), decltype(pattern_arg(b)), decltype(pattern_arg(c))> {
1589+
return {pattern_arg(a), pattern_arg(b), pattern_arg(c)};
15801590
}
15811591
template<typename A, typename B, typename C>
1582-
auto rounding_mul_shift_right(A &&a, B &&b, C &&c) noexcept -> Intrin<decltype(pattern_arg(a)), decltype(pattern_arg(b)), decltype(pattern_arg(c))> {
1583-
return {Call::rounding_mul_shift_right, pattern_arg(a), pattern_arg(b), pattern_arg(c)};
1592+
auto rounding_mul_shift_right(A &&a, B &&b, C &&c) noexcept -> Intrin<Call::rounding_mul_shift_right, decltype(pattern_arg(a)), decltype(pattern_arg(b)), decltype(pattern_arg(c))> {
1593+
return {pattern_arg(a), pattern_arg(b), pattern_arg(c)};
1594+
}
1595+
1596+
template<typename A>
1597+
auto abs(A &&a) noexcept -> Intrin<Call::abs, decltype(pattern_arg(a))> {
1598+
return {pattern_arg(a)};
1599+
}
1600+
1601+
template<typename A, typename B>
1602+
auto absd(A &&a, B &&b) noexcept -> Intrin<Call::absd, decltype(pattern_arg(a)), decltype(pattern_arg(b))> {
1603+
return {pattern_arg(a), pattern_arg(b)};
1604+
}
1605+
1606+
template<typename A>
1607+
auto likely(A &&a) noexcept -> Intrin<Call::likely, decltype(pattern_arg(a))> {
1608+
return {pattern_arg(a)};
1609+
}
1610+
1611+
template<typename A>
1612+
auto likely_if_innermost(A &&a) noexcept -> Intrin<Call::likely_if_innermost, decltype(pattern_arg(a))> {
1613+
return {pattern_arg(a)};
15841614
}
15851615

15861616
template<typename A>
@@ -2425,7 +2455,8 @@ template<typename A>
24252455
struct IsInt {
24262456
struct pattern_tag {};
24272457
A a;
2428-
int bits, lanes;
2458+
uint8_t bits;
2459+
uint16_t lanes;
24292460

24302461
constexpr static uint32_t binds = bindings<A>::mask;
24312462

@@ -2448,7 +2479,7 @@ struct IsInt {
24482479
};
24492480

24502481
template<typename A>
2451-
HALIDE_ALWAYS_INLINE auto is_int(A &&a, int bits = 0, int lanes = 0) noexcept -> IsInt<decltype(pattern_arg(a))> {
2482+
HALIDE_ALWAYS_INLINE auto is_int(A &&a, uint8_t bits = 0, uint16_t lanes = 0) noexcept -> IsInt<decltype(pattern_arg(a))> {
24522483
assert_is_lvalue_if_expr<A>();
24532484
return {pattern_arg(a), bits, lanes};
24542485
}
@@ -2470,7 +2501,8 @@ template<typename A>
24702501
struct IsUInt {
24712502
struct pattern_tag {};
24722503
A a;
2473-
int bits, lanes;
2504+
uint8_t bits;
2505+
uint16_t lanes;
24742506

24752507
constexpr static uint32_t binds = bindings<A>::mask;
24762508

@@ -2493,7 +2525,7 @@ struct IsUInt {
24932525
};
24942526

24952527
template<typename A>
2496-
HALIDE_ALWAYS_INLINE auto is_uint(A &&a, int bits = 0, int lanes = 0) noexcept -> IsUInt<decltype(pattern_arg(a))> {
2528+
HALIDE_ALWAYS_INLINE auto is_uint(A &&a, uint8_t bits = 0, uint16_t lanes = 0) noexcept -> IsUInt<decltype(pattern_arg(a))> {
24972529
assert_is_lvalue_if_expr<A>();
24982530
return {pattern_arg(a), bits, lanes};
24992531
}

src/Simplify_Max.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,10 @@ Expr Simplify::visit(const Max *op, ExprInfo *info) {
9191
rewrite(max(select(x, w, max(z, y)), z), max(select(x, w, y), z)) ||
9292
rewrite(max(select(x, w, max(z, y)), y), max(select(x, w, z), y)) ||
9393

94-
rewrite(max(intrin(Call::likely, x), x), b) ||
95-
rewrite(max(x, intrin(Call::likely, x)), a) ||
96-
rewrite(max(intrin(Call::likely_if_innermost, x), x), b) ||
97-
rewrite(max(x, intrin(Call::likely_if_innermost, x)), a) ||
94+
rewrite(max(likely(x), x), b) ||
95+
rewrite(max(x, likely(x)), a) ||
96+
rewrite(max(likely_if_innermost(x), x), b) ||
97+
rewrite(max(x, likely_if_innermost(x)), a) ||
9898

9999
(no_overflow(op->type) &&
100100
(rewrite(max(ramp(x, y, lanes), broadcast(z, lanes)), a,

src/Simplify_Min.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,10 @@ Expr Simplify::visit(const Min *op, ExprInfo *info) {
9292
rewrite(min(select(x, w, min(z, y)), y), min(select(x, w, z), y)) ||
9393
rewrite(min(select(x, w, min(z, y)), z), min(select(x, w, y), z)) ||
9494

95-
rewrite(min(intrin(Call::likely, x), x), b) ||
96-
rewrite(min(x, intrin(Call::likely, x)), a) ||
97-
rewrite(min(intrin(Call::likely_if_innermost, x), x), b) ||
98-
rewrite(min(x, intrin(Call::likely_if_innermost, x)), a) ||
95+
rewrite(min(likely(x), x), b) ||
96+
rewrite(min(x, likely(x)), a) ||
97+
rewrite(min(likely_if_innermost(x), x), b) ||
98+
rewrite(min(x, likely_if_innermost(x)), a) ||
9999

100100
(no_overflow(op->type) &&
101101
(rewrite(min(ramp(x, y, lanes), broadcast(z, lanes)), a,

src/Simplify_Not.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ Expr Simplify::visit(const Not *op, ExprInfo *info) {
1818
}
1919

2020
if (rewrite(!broadcast(x, c0), broadcast(!x, c0)) ||
21-
rewrite(!intrin(Call::likely, x), intrin(Call::likely, !x)) ||
22-
rewrite(!intrin(Call::likely_if_innermost, x), intrin(Call::likely_if_innermost, !x)) ||
21+
rewrite(!likely(x), likely(!x)) ||
22+
rewrite(!likely_if_innermost(x), likely_if_innermost(!x)) ||
2323
rewrite(!(!x && y), x || !y) ||
2424
rewrite(!(!x || y), x && !y) ||
2525
rewrite(!(x && !y), !x || y) ||

src/Simplify_Select.cpp

+8-8
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,17 @@ Expr Simplify::visit(const Select *op, ExprInfo *info) {
2121

2222
// clang-format off
2323
if (EVAL_IN_LAMBDA
24-
(rewrite(select(IRMatcher::intrin(Call::likely, true), x, y), x) ||
25-
rewrite(select(IRMatcher::intrin(Call::likely, false), x, y), y) ||
26-
rewrite(select(IRMatcher::intrin(Call::likely_if_innermost, true), x, y), x) ||
27-
rewrite(select(IRMatcher::intrin(Call::likely_if_innermost, false), x, y), y) ||
24+
(rewrite(select(IRMatcher::likely(true), x, y), x) ||
25+
rewrite(select(IRMatcher::likely(false), x, y), y) ||
26+
rewrite(select(IRMatcher::likely_if_innermost(true), x, y), x) ||
27+
rewrite(select(IRMatcher::likely_if_innermost(false), x, y), y) ||
2828
rewrite(select(1, x, y), x) ||
2929
rewrite(select(0, x, y), y) ||
3030
rewrite(select(x, y, y), y) ||
31-
rewrite(select(x, intrin(Call::likely, y), y), false_value) ||
32-
rewrite(select(x, y, intrin(Call::likely, y)), true_value) ||
33-
rewrite(select(x, intrin(Call::likely_if_innermost, y), y), false_value) ||
34-
rewrite(select(x, y, intrin(Call::likely_if_innermost, y)), true_value) ||
31+
rewrite(select(x, likely(y), y), false_value) ||
32+
rewrite(select(x, y, likely(y)), true_value) ||
33+
rewrite(select(x, likely_if_innermost(y), y), false_value) ||
34+
rewrite(select(x, y, likely_if_innermost(y)), true_value) ||
3535
false)) {
3636
return rewrite.result;
3737
}

0 commit comments

Comments
 (0)