@@ -81,6 +81,28 @@ int lossless_cast_test() {
8181 e = cast (i64 , 1024 ) * cast (i64 , 1024 ) * cast (i64 , 1024 );
8282 res |= check_lossless_cast (i32 , e, (cast (i32 , 1024 ) * 1024 ) * 1024 );
8383
84+ // Check narrowing a vector reduction of something narrowable to bool ...
85+ auto make_reduce = [&](Type t, VectorReduce::Operator op) {
86+ return VectorReduce::make (op,
87+ cast (t.with_lanes (4 ), Ramp::make (x, 1 , 4 ) > 4 ), 2 );
88+ };
89+
90+ // It's OK to narrow it to 8-bit.
91+ e = make_reduce (UInt (16 ), VectorReduce::Add);
92+ res |= check_lossless_cast (UInt (8 ), e, make_reduce (UInt (8 ), VectorReduce::Add));
93+
94+ // ... but we can't reduce it all the way to bool if the operator isn't
95+ // legal for bools (issue #9011)
96+ e = make_reduce (UInt (8 ), VectorReduce::Add);
97+ res |= check_lossless_cast (Bool (), e, Expr ());
98+
99+ // Min or Max, however, can just become And and Or
100+ e = make_reduce (UInt (8 ), VectorReduce::Min);
101+ res |= check_lossless_cast (Bool (), e, make_reduce (Bool (), VectorReduce::And));
102+
103+ e = make_reduce (UInt (8 ), VectorReduce::Max);
104+ res |= check_lossless_cast (Bool (), e, make_reduce (Bool (), VectorReduce::Or));
105+
84106 return res;
85107}
86108
0 commit comments