Closed
Description
Zig Version
0.11.0-dev.1969+d525ecb52
Steps to Reproduce and Observed Behavior
const std = @import("std");
const expect = std.testing.expect;
pub fn main() !void {
var buf: [9]u8 align(4) = .{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const ptr = @ptrCast(*align(1) Header, buf[1..][0..8]);
const x = ptr.bytes_len;
std.debug.print("x=0x{x}\n", .{x});
}
const Header = extern struct {
tag: u32,
bytes_len: u32,
};
$ stage3/bin/zig build-exe test3.zig -target mipsel-linux-musl
$ qemu-mipsel ./test3
Bus error (core dumped)
The problem is incorrect alignment in the LLVM IR:
const std = @import("std");
pub fn panic(msg: []const u8, st: ?*std.builtin.StackTrace, start: ?usize) noreturn {
_ = .{ msg, st, start };
unreachable;
}
export fn entry() bool {
doTheTest() catch return false;
return true;
}
fn doTheTest() !void {
var buf: [9]u8 align(4) = .{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const ptr: *align(1) Header = @ptrCast(buf[1..][0..8]);
const x = ptr.bytes_len;
foo(x);
}
extern fn foo(u32) void;
const Header = extern struct {
tag: u32,
bytes_len: u32,
};
$ stage3/bin/zig build-obj test2.zig -target mipsel-linux-musl --verbose-llvm-ir -fstrip -OReleaseFast
define internal fastcc i16 @test2.doTheTest() unnamed_addr #0 {
Entry:
%0 = alloca ptr, align 4
%1 = alloca [9 x i8], align 4
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %1, ptr align 1 @0, i32 9, i1 false)
%2 = getelementptr inbounds [9 x i8], ptr %1, i32 0, i32 1
store ptr %2, ptr %0, align 4
%3 = load ptr, ptr %0, align 4
%4 = getelementptr inbounds [8 x i8], ptr %3, i32 0, i32 0
%5 = getelementptr inbounds %test2.Header, ptr %4, i32 0, i32 1
%6 = load i32, ptr %5, align 4
call void @foo(i32 %6)
ret i16 0
}
The problem is %6 = load i32, ptr %5, align 4
which has align 4 instead of align 1.
Side note: it is very annoying that the panic
override above does not eliminate panicOutOfBounds
from calling into std.debug.panicExtra
and dragging in a whole lot of formatting code.
I have no evidence this is a regression, but I suspect it is.
Expected Behavior
I expect to see %6 = load i32, ptr %5, align 1
which would cause LLVM to generate machine code that did not cause a Bus Error.