@@ -15,7 +15,7 @@ void check(Expr test, Expr expected, Type required_type) {
1515
1616 // Make sure the pattern is robust to CSE. We only enforce this
1717 // for types with well-defined overflow for now.
18- if (test.type ().bits () < 32 || test. type (). is_uint ()) {
18+ if (test.type ().can_overflow ()) {
1919 auto bundle = [](const Expr &e) {
2020 return Call::make (e.type (), Call::bundle, {e, e}, Call::PureIntrinsic);
2121 };
@@ -131,7 +131,10 @@ int main(int argc, char **argv) {
131131 Expr u8y = make_leaf (UInt (8 , 4 ), " u8y" );
132132 Expr u8z = make_leaf (UInt (8 , 4 ), " u8w" );
133133 Expr u8w = make_leaf (UInt (8 , 4 ), " u8z" );
134+ Expr i16x = make_leaf (Int (16 , 4 ), " i16x" );
134135 Expr u16x = make_leaf (UInt (16 , 4 ), " u16x" );
136+ Expr i16y = make_leaf (Int (16 , 4 ), " i16y" );
137+ Expr u16y = make_leaf (UInt (16 , 4 ), " u16y" );
135138 Expr u32x = make_leaf (UInt (32 , 4 ), " u32x" );
136139 Expr u32y = make_leaf (UInt (32 , 4 ), " u32y" );
137140 Expr i32x = make_leaf (Int (32 , 4 ), " i32x" );
@@ -170,6 +173,21 @@ int main(int argc, char **argv) {
170173 check (u32 (u8x) * u8y, u32 (widening_mul (u8x, u8y)));
171174 check (f32 (f16x) * f32 (f16y), widening_mul (f16x, f16y));
172175
176+ // Check mixed float/int promotion
177+ check (widening_mul (i8x, f16y), widening_mul (f16 (i8x), f16y));
178+ check (widening_mul (i8x, f32y), widening_mul (f32 (i8x), f32y));
179+ check (widening_mul (u8x, f16y), widening_mul (f16 (u8x), f16y));
180+ check (widening_mul (u8x, f32y), widening_mul (f32 (u8x), f32y));
181+ check (widening_mul (i16x, f32y), widening_mul (f32 (i16x), f32y));
182+ check (widening_mul (u16x, f32y), widening_mul (f32 (u16x), f32y));
183+
184+ check (widening_mul (f16x, i8y), widening_mul (f16x, f16 (i8y)));
185+ check (widening_mul (f32x, i8y), widening_mul (f32x, f32 (i8y)));
186+ check (widening_mul (f16x, u8y), widening_mul (f16x, f16 (u8y)));
187+ check (widening_mul (f32x, u8y), widening_mul (f32x, f32 (u8y)));
188+ check (widening_mul (f32x, i16y), widening_mul (f32x, f32 (i16y)));
189+ check (widening_mul (f32x, u16y), widening_mul (f32x, f32 (u16y)));
190+
173191 // Widening mul allows mixed signs
174192 check (i16 (i8x) * u8y, widening_mul (i8x, u8y), Int (16 , 4 ));
175193 check (i32 (i8x) * u8y, i32 (widening_mul (i8x, u8y)));
@@ -377,6 +395,16 @@ int main(int argc, char **argv) {
377395 g.compile_jit ();
378396 }
379397
398+ // Mixed integer-floating-point used to crash codegen
399+ {
400+ Func f, q, s;
401+ q (x) = cast<int8_t >(0 );
402+ s (x) = cast (Float (16 ), 1 .0f );
403+ f (x) = widening_mul (q (x), s (x));
404+
405+ f.compile_jit ();
406+ }
407+
380408 printf (" Success!\n " );
381409 return 0 ;
382410}
0 commit comments