Skip to content

Commit b87ca3d

Browse files
committed
fix: inst simplification size aware equality
1 parent 75fa7a8 commit b87ca3d

3 files changed

Lines changed: 60 additions & 2 deletions

File tree

libs/@local/hashql/mir/src/pass/transform/inst_simplify/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,8 @@ impl<'heap, A: Allocator> InstSimplifyVisitor<'_, 'heap, A> {
258258
BinOp::BitAnd => return Some(lhs & rhs),
259259
BinOp::BitOr => return Some(lhs | rhs),
260260
// Comparisons produce booleans
261-
BinOp::Eq => lhs.as_int() == rhs.as_int(),
262-
BinOp::Ne => lhs.as_int() != rhs.as_int(),
261+
BinOp::Eq => lhs == rhs,
262+
BinOp::Ne => lhs != rhs,
263263
BinOp::Lt => lhs.as_int() < rhs.as_int(),
264264
BinOp::Lte => lhs.as_int() <= rhs.as_int(),
265265
BinOp::Gt => lhs.as_int() > rhs.as_int(),

libs/@local/hashql/mir/src/pass/transform/inst_simplify/tests.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,38 @@ fn const_fold_bit_or() {
246246
);
247247
}
248248

249+
/// Tests that `Eq` uses size-aware comparison when folding constants.
250+
///
251+
/// `true` and `1` have the same numeric value but different sizes (1 bit vs
252+
/// 128 bits), so they must compare as not equal. If `Eq` used `as_int()`
253+
/// instead of the size-aware `==`, this would incorrectly fold to `true`.
254+
#[test]
255+
fn const_fold_eq_bool_vs_int() {
256+
let heap = Heap::new();
257+
let interner = Interner::new(&heap);
258+
let env = Environment::new(&heap);
259+
260+
let body = body!(interner, env; fn@0/0 -> Bool {
261+
decl result: Bool;
262+
263+
bb0() {
264+
result = bin.== true 1;
265+
return result;
266+
}
267+
});
268+
269+
assert_inst_simplify_pass(
270+
"const_fold_eq_bool_vs_int",
271+
body,
272+
&mut MirContext {
273+
heap: &heap,
274+
env: &env,
275+
interner: &interner,
276+
diagnostics: DiagnosticIssues::new(),
277+
},
278+
);
279+
}
280+
249281
/// Tests constant folding for unary NOT.
250282
#[test]
251283
fn const_fold_unary_not() {

libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_eq_bool_vs_int.snap

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)