Fix match_bits on bfloat and drop strip_widening_cast integer guard#9218
Conversation
match_bits widened the narrower operand with Type::with_bits, which on a bfloat16 produced a bfloat32 - a type codegen can't handle. Reachable directly, e.g. widening_mul(bf16, f32). Widen a bfloat to a regular float instead (matching the wider operand's bit count), consistent with Type::widen(). With that fixed, the is_int_or_uint guard in strip_widening_cast is no longer needed to avoid synthesizing a bfloat32, so drop it. bfloat16 inner types are now stripped like other floats, so f32(bf16) * f32(bf16) is recognized as a widening_mul, matching the existing float16 handling. Add a deterministic codegen regression test for widening_mul(bf16, f32), the widening_mul(bf16, bf16) case, and give the lossless_cast fuzzer an isolated float/bfloat16/float16 expression pool (kept separate from the integer pool, since float->int casts of unbounded floats are UB). The fuzzer is what surfaced the match_bits bug. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Failures appear to be real |
Yeah, seems this broke some pattern the X86 backend depended on. Looking into it. |
|
The changes to the lossless cast fuzz test don't make sense to me - that test compares the output for exact equality after casting to int64, which is simultaneously too precise and not precise enough for floating point transformations. I think the new bfloat pattern should just be in simd_op_check. |
It doesn't check equality for floating point though... just that it doesn't assert-fail the compiler. The previous widening logic produced a BFloat(32) that was nonsensical and crashed.
It's already in the diff. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9218 +/- ##
=======================================
Coverage ? 69.80%
=======================================
Files ? 255
Lines ? 78580
Branches ? 18790
=======================================
Hits ? 54849
Misses ? 18167
Partials ? 5564 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
match_bits widened the narrower operand with Type::with_bits, which on a bfloat16 produced a bfloat32 - a type codegen can't handle. Reachable directly, e.g. widening_mul(bf16, f32). Widen a bfloat to a regular float instead (matching the wider operand's bit count), consistent with Type::widen().
With that fixed, the is_int_or_uint guard in strip_widening_cast is no longer needed to avoid synthesizing a bfloat32, so drop it. bfloat16 inner types are now stripped like other floats, so f32(bf16) * f32(bf16) is recognized as a widening_mul, matching the existing float16 handling.
Add a deterministic codegen regression test for widening_mul(bf16, f32), the widening_mul(bf16, bf16) case, and give the lossless_cast fuzzer an isolated float/bfloat16/float16 expression pool (kept separate from the integer pool, since float->int casts of unbounded floats are UB). The fuzzer is what surfaced the match_bits bug.
Checklist