Open
Description
Zig Version: 0.10.0-dev.2887+9a5c7b4b4
Repro:
$ stage2/bin/zig test ../lib/std/std.zig -target i386-linux-none
LLVM Emit Object... error: <unknown>:0: expected relocatable expression
Reduced LLVM IR:
source_filename = "test"
target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128"
target triple = "i386-unknown-linux-unknown"
%os.linux.io_uring_sqe = type { i8, i8, i16, i32, i64, i64, i32, i32, i64, i16, i16, i32, [2 x i64] }
@os.linux.io_uring.test.openat__anon_60060 = internal unnamed_addr constant [21 x i8] c"test_io_uring_openat\00", align 1
@0 = private unnamed_addr constant %os.linux.io_uring_sqe { i8 18, i8 0, i16 0, i32 -100, i64 0, i64 ptrtoint ([21 x i8]* @os.linux.io_uring.test.openat__anon_60060 to i64), i32 438, i32 524354, i64 858993459, i16 0, i16 0, i32 0, [2 x i64] zeroinitializer }, align 4
Confirmed happens with both LLVM 13.0.1 and LLVM 14.0.6.
The source code comes from here:
zig/lib/std/os/linux/io_uring.zig
Lines 1902 to 1914 in f639cb3
It's just a @ptrToInt
on a string literal, inside a const struct literal. Stage2 emits it, correctly, like this:
@os.linux.io_uring.test.openat__anon_60060 = internal unnamed_addr constant [21 x i8] c"test_io_uring_openat\00", align 1
@1140 = private unnamed_addr constant %os.linux.io_uring_sqe { i8 18, i8 0, i16 0, i32 -100, i64 0, i64 ptrtoint ([21 x i8]* @os.linux.io_uring.test.openat__anon_60060 to i64), i32 438, i32 524354, i64 858993459, i16 0, i16 0, i32 0, [2 x i64] zeroinitializer }, align 4
Looks good. Why doesn't the issue happen with stage1? The answer is that stage1 failed to notice that the struct initializer should be constant, and initialized the struct at runtime, accidentally avoiding LLVM's bug:
%60 = getelementptr inbounds %os.linux.io_uring_sqe, %os.linux.io_uring_sqe* %5, i32 0, i32 0, !dbg !22452
%61 = getelementptr inbounds %os.linux.io_uring_sqe, %os.linux.io_uring_sqe* %5, i32 0, i32 1, !dbg !22453
%62 = getelementptr inbounds %os.linux.io_uring_sqe, %os.linux.io_uring_sqe* %5, i32 0, i32 2, !dbg !22454
%63 = getelementptr inbounds %os.linux.io_uring_sqe, %os.linux.io_uring_sqe* %5, i32 0, i32 3, !dbg !22455
%64 = getelementptr inbounds %os.linux.io_uring_sqe, %os.linux.io_uring_sqe* %5, i32 0, i32 4, !dbg !22456
%65 = getelementptr inbounds %os.linux.io_uring_sqe, %os.linux.io_uring_sqe* %5, i32 0, i32 5, !dbg !22457
store i64 zext (i32 ptrtoint ([21 x i8]* @10355 to i32) to i64), i64* %65, align 4, !dbg !22458
%66 = getelementptr inbounds %os.linux.io_uring_sqe, %os.linux.io_uring_sqe* %5, i32 0, i32 6, !dbg !22459
%67 = getelementptr inbounds %os.linux.io_uring_sqe, %os.linux.io_uring_sqe* %5, i32 0, i32 7, !dbg !22460
%68 = getelementptr inbounds %os.linux.io_uring_sqe, %os.linux.io_uring_sqe* %5, i32 0, i32 8, !dbg !22461
%69 = getelementptr inbounds %os.linux.io_uring_sqe, %os.linux.io_uring_sqe* %5, i32 0, i32 9, !dbg !22462
%70 = getelementptr inbounds %os.linux.io_uring_sqe, %os.linux.io_uring_sqe* %5, i32 0, i32 10, !dbg !22463
%71 = getelementptr inbounds %os.linux.io_uring_sqe, %os.linux.io_uring_sqe* %5, i32 0, i32 11, !dbg !22464
%72 = getelementptr inbounds %os.linux.io_uring_sqe, %os.linux.io_uring_sqe* %5, i32 0, i32 12, !dbg !22465
store i8 18, i8* %60, align 1, !dbg !22452
store i8 0, i8* %61, align 1, !dbg !22453
store i16 0, i16* %62, align 2, !dbg !22454
store i32 -100, i32* %63, align 4, !dbg !22455
store i64 0, i64* %64, align 4, !dbg !22456
store i32 438, i32* %66, align 4, !dbg !22459
store i32 524354, i32* %67, align 4, !dbg !22460
store i64 858993459, i64* %68, align 4, !dbg !22461
store i16 0, i16* %69, align 2, !dbg !22462
store i16 0, i16* %70, align 2, !dbg !22463
store i32 0, i32* %71, align 4, !dbg !22464
%73 = bitcast [2 x i64]* %72 to i8*, !dbg !22465
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %73, i8* align 4 bitcast ([2 x i64]* @10360 to i8*), i32 16, i1 false), !dbg !22465
%74 = load %os.linux.io_uring_sqe*, %os.linux.io_uring_sqe** %sqe_openat, align 4, !dbg !22466
%75 = bitcast %os.linux.io_uring_sqe* %74 to i8*, !dbg !22467
%76 = bitcast %os.linux.io_uring_sqe* %6 to i8*, !dbg !22467
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %76, i8* align 4 %75, i32 64, i1 false), !dbg !22467
%77 = call fastcc i16 @testing.expectEqual.2452(%builtin.StackTrace* %0, %os.linux.io_uring_sqe* %5, %os.linux.io_uring_sqe* %74), !dbg !22468
Upstream bug report: llvm/llvm-project#56400