aarch64 llvm 14 regression with vectors: assertion `TmpVec.size() > 1' failed
Zig Version: 0.10.0-dev.2876+fbd6c8832
This test case regressed with the update from LLVM 13 to 14:
test "tuple to vector" {
const S = struct {
fn doTheTest() !void {
const Vec3 = @Vector(3, i32);
var v: Vec3 = .{ 1, 0, 0 };
for ([_]Vec3{ .{ 0, 1, 0 }, .{ 0, 0, 1 } }) |it| {
v += it;
}
try std.testing.expectEqual(v, Vec3{ 1, 1, 1 });
if (builtin.zig_backend != .stage1) {
try std.testing.expectEqual(v, .{ 1, 1, 1 });
}
}
};
try S.doTheTest();
comptime try S.doTheTest();
}
[nix-shell:~/dev/zig/build-llvm14-debug]$ stage1/bin/zig cc test.ll -target aarch64-linux-none
zig: /home/andy/Downloads/llvm-project-14/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp:656: llvm::MachineInstrBuilder llvm::MachineIRBuilder::buildUnmerge(llvm::ArrayRef<llvm::Register>, const llvm::SrcOp&): Assertion `TmpVec.size() > 1' failed.
Reduced LLVM IR:
define internal fastcc i16 @test2.doTheTest.S.doTheTest() {
Block10:
%0 = call fastcc i16 undef(<3 x i32> zeroinitializer, <3 x i32> zeroinitializer)
ret i16 0
}
Upstream bug report: https://github.com/llvm/llvm-project/issues/56397
I'm very new to this but I think this is not regressed anymore as the fix for https://github.com/llvm/llvm-project/issues/56397 landed some time ago in https://github.com/llvm/llvm-project/commit/2483f43d47ca30a9d9ff3f1714a45ca63d9b3410.
I did the following to confirm this:
-
Cloned the
zigrepo. -
Used
nix flake init -t 'github:mitchellh/zig-overlay#compiler-dev'(compiler-dev flake) to get a working environment. -
Followed the
README.mdto build everything. -
Build
qemuby using https://github.com/ziglang/qemu-static. -
Compiled the test below:
build/zig2 test --test-no-exec -femit-bin=regression -target aarch64-linux-none regression.zig -
Executed the test case with qemu:
../artifact/qemu-linux-x86_64-9.0.0/bin/qemu-aarch64 regressionOutput:
AARCH64 detected! All 1 tests passed.
Test snippet: (regression.zig)
const std = @import("std");
const builtin = @import("builtin");
test "tuple to vector" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) {
// Regressed with LLVM 14:
// https://github.com/ziglang/zig/issues/12012
std.debug.print("AARCH64 detected!\n", .{});
// return error.SkipZigTest;
}
const S = struct {
fn doTheTest() !void {
const Vec3 = @Vector(3, i32);
var v: Vec3 = .{ 1, 0, 0 };
for ([_]Vec3{ .{ 0, 1, 0 }, .{ 0, 0, 1 } }) |it| {
v += it;
}
try std.testing.expectEqual(v, Vec3{ 1, 1, 1 });
try std.testing.expectEqual(v, .{ 1, 1, 1 });
}
};
try S.doTheTest();
try comptime S.doTheTest();
}
If you want I can open a PR that re-enables the test case.