Skip to content

Commit bb8d4d8

Browse files
authored
Fix infinite recursion in FindIntrinsics (#9109)
1 parent 6174d5b commit bb8d4d8

2 files changed

Lines changed: 13 additions & 1 deletion

File tree

src/FindIntrinsics.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,13 @@ class FindIntrinsics : public IRMutator {
128128
Expr a = c->args[0];
129129
Expr b = c->args[1];
130130

131+
if (Call::as_intrinsic(b, {Call::signed_integer_overflow})) {
132+
// Letting signed integer overflow through here would result in
133+
// infinite recursion when we try to construct the rounding
134+
// terms.
135+
return Expr{};
136+
}
137+
131138
// Helper to make the appropriate shift.
132139
auto rounding_shift = [&](const Expr &a, const Expr &b) {
133140
if (c->is_intrinsic(Call::shift_right)) {
@@ -203,7 +210,7 @@ class FindIntrinsics : public IRMutator {
203210
}
204211
}
205212

206-
return Expr();
213+
return Expr{};
207214
}
208215

209216
template<typename LetOrLetStmt>

test/correctness/intrinsics.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,11 @@ int main(int argc, char **argv) {
346346
check_intrinsics_over_range<int32_t>();
347347
check_intrinsics_over_range<uint32_t>();
348348

349+
// Signed integer overflow on the RHS of a shift used to cause infinite
350+
// recursion (issue #9108)
351+
Expr e = simplify(i32x << (i32x << 67));
352+
check(e, e);
353+
349354
// The intrinsics-matching pass substitutes in widening lets. At
350355
// one point this caused a missing symbol bug for the code below
351356
// due to a subexpression not getting mutated.

0 commit comments

Comments
 (0)