zig icon indicating copy to clipboard operation
zig copied to clipboard

aarch64 llvm 14 regression with vectors: assertion `TmpVec.size() > 1' failed

Open andrewrk opened this issue 3 years ago • 1 comments

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

andrewrk avatar Jul 06 '22 01:07 andrewrk

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:

  1. Cloned the zig repo.

  2. Used nix flake init -t 'github:mitchellh/zig-overlay#compiler-dev' (compiler-dev flake) to get a working environment.

  3. Followed the README.md to build everything.

  4. Build qemu by using https://github.com/ziglang/qemu-static.

  5. Compiled the test below:

    build/zig2 test --test-no-exec -femit-bin=regression -target aarch64-linux-none regression.zig
    
  6. Executed the test case with qemu:

    ../artifact/qemu-linux-x86_64-9.0.0/bin/qemu-aarch64 regression
    

    Output:

    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.

TheFunctionalGuy avatar Jul 23 '24 21:07 TheFunctionalGuy