E3004
E3004 — Type mismatch in binary operation
What the compiler reports
E3004{{.*}}cannot assign Tensor<f32, [4]> to Tensor<f16, [4]>
The fragments the test suite holds the compiler to. An ellipsis marks text the test does not constrain; the emitted message also carries a source location.
A program that triggers it
//
// Part of the Vx Project, under the Apache License v2.0 with LLVM Exceptions.
// See LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// Storing a widened slice back into half storage has to say so.
//
// A half slice is storage: it widens to f32 on load and the arithmetic happens
// there, so `o[0] * corr` is an f32 slice whatever `corr` is. Assigning that
// into an f16 row is a narrowing conversion, and Vx has no implicit numeric
// conversion -- the program writes `as f16`, exactly as a scalar would.
//
// This used to be accepted, and then crashed the emitter: the lowering widened
// the row, assumed everything else was already f32, and stored a vector<4xf32>
// into a memref<4xf16>. The module did not parse. An `as` the checker demands is
// the difference between a conversion the program asked for and one the backend
// invented.
//
fn main() -> i32 {
let mut o = Tensor<f16, [ 2, 4 ]>::new();
// Non-zero and distinct per lane, so the file stays a valid program to run if
// the refusal below is ever lifted.
for d in 0..4 {
o[0][d] = 1.5 + (d as f16);
}
let corr : f32 = 0.5;
o[0] = o[0] * corr;
return 0;
}
From tests/frontend/fail/slice_narrowing_needs_a_cast.vx, which asserts this diagnostic on every commit.