zig
zig copied to clipboard
Corrupted slice in release build
I've been hammering at a weird bug for a while and finally got a reduced case. See the code and output. I have a string slice being passed around and at some point the slice value (ptr and/or len?) is getting corrupted. union(enum)s are involved but I don't know if that's relevant.
The weirdest thing is the problem will shift or go away if you change seemingly innocuous bits of code (see the comments I left throughout the code sample). This makes it a bit tricky to pare the test case down even further.
This problem only happens in ReleaseSmall and ReleaseFast. It has been around since at least 0.6.0. I'm sure the release build of my projects used to work at some point, I'm going to guess it broke some time after 0.5.0?
Apologies for the size of the code snippet, a lot of it is types. Scroll down and start with the main function and it's pretty easy to follow I think.
const std = @import("std");
pub const TempRef = struct {
index: usize,
is_weak: bool,
};
pub const BuiltinEnum = struct {
name: []const u8,
};
pub const ParamType = union(enum) {
boolean,
buffer,
// one way to make the problem go away: make `one_of` a plain
// enum value with no data (get rid of BuiltinEnum)
one_of: BuiltinEnum,
};
pub const CallArg = struct {
value: Expression,
};
pub const Expression = union(enum) {
literal_boolean: bool,
literal_enum_value: EnumLiteral,
};
pub const EnumLiteral = struct {
label: []const u8,
};
pub const ExpressionResult = union(enum) {
temp_buffer: TempRef,
literal_boolean: bool,
literal_enum_value: []const u8,
};
fn commitCalleeParam(
result: ExpressionResult,
callee_param_type: ParamType,
) ExpressionResult {
// another way to make the problem go away: copy `result` into
// a local variable here, and use the copy below
switch (callee_param_type) {
.boolean => {
return result;
},
.buffer => {
// another way to make the problem go away: replace this with
// a simple `return result;`
return ExpressionResult{
.temp_buffer = .{ .index = 0, .is_weak = false },
};
},
.one_of => {
return result;
},
}
}
fn genExpression(expr: Expression) ExpressionResult {
switch (expr) {
.literal_boolean => |value| {
return ExpressionResult{
.literal_boolean = value,
};
},
.literal_enum_value => |v| {
std.debug.warn("literal enum \"{}\"\n", .{v.label});
const result: ExpressionResult = .{
.literal_enum_value = v.label,
};
// another way to make the problem go away: comment out this
// switch block (which does nothing but print something)
switch (result) {
.literal_enum_value => |w| {
std.debug.warn("in result \"{}\"\n", .{w});
},
else => {},
}
return result;
},
}
}
pub fn main() void {
var param: ParamType = .{
.one_of = .{ .name = "FilterType" },
};
var arg: CallArg = .{
.value = .{
.literal_enum_value = .{
.label = "what happened to me",
},
},
};
const result = genExpression(arg.value);
switch (result) {
.literal_enum_value => |w| {
std.debug.warn("after genExpression \"{}\"\n", .{w});
},
else => {},
}
// comment out all the code below this point and the problem goes away as
// well (it even affects the output of the print BEFORE this point)
const derp = commitCalleeParam(result, param);
switch (derp) {
.literal_enum_value => |w| {
std.debug.warn("after commit \"{}\"\n", .{w});
},
else => {},
}
}
$ zig version
0.7.0+9af53f8e0
$ zig run -O ReleaseFast asdf.zig
literal enum "what happened to me"
in result "what happened to me"
after genExpression "w"
after commit "w"
I'm on a Mac.
I ran out of time to debug this but I've got a pretty good idea of what's wrong.
The SROA pass kicks in and becomes confused by the is_weak: bool field, the pass gets something wrong (that doesn't trip any assertion) and ends up writing the is_weak part of .temp_buffer = .{ .index = 0, .is_weak = false }, into result's slice len field.
Running the following LLVM IR code with opt -debug -S -O3 < file.ll gives something like this, I've highlighted the important parts:
; ModuleID = 'foo'
source_filename = "foo"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
%"[]u8" = type { i8*, i64 }
%std.builtin.StackTrace = type { i64, %"[]usize" }
%"[]usize" = type { i64*, i64 }
%std.target.LinuxVersionRange = type { %std.builtin.Range, %std.builtin.Version }
%std.builtin.Range = type { %std.builtin.Version, %std.builtin.Version }
%std.builtin.Version = type { i32, i32, i32 }
%std.target.Set = type { [3 x i64] }
%std.target.Model = type { %"[]u8", %"?[:0]const u8", %std.target.Set }
%"?[:0]const u8" = type { %"[]u8", i1 }
%std.mutex.Dummy = type { i1 }
%ParamType = type { %BuiltinEnum, i2 }
%BuiltinEnum = type { %"[]u8" }
%CallArg = type { %Expression }
%Expression = type { %EnumLiteral, i1 }
%EnumLiteral = type { %"[]u8" }
%ExpressionResult = type { %TempRef, i2 }
%TempRef = type { i64, i1 }
%"?std.mutex.Held" = type { %std.mutex.Held, i1 }
%std.mutex.Held = type { %std.mutex.Dummy* }
%"?usize" = type { i64, i1 }
%"struct:96:29" = type { %"[]u8", %"[]u8" }
%std.fs.file.File = type { i32 }
%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)" = type { %std.fs.file.File }
%"[]std.target.x86.Feature" = type { i8*, i64 }
%std.fmt.FormatOptions = type { %"?usize", %"?usize", i2, i8 }
%"std.os.struct:4571:51" = type { i64 }
@panic.1 = internal unnamed_addr constant void (%"[]u8"*, %std.builtin.StackTrace*)* @panic, align 8
@output_mode = internal unnamed_addr constant i2 0, align 1
@link_libc = internal unnamed_addr constant i1 false, align 1
@os = internal unnamed_addr constant { <{ i6, [3 x i8] }>, { %std.target.LinuxVersionRange, i2, [3 x i8] } } { <{ i6, [3 x i8] }> <{ i6 8, [3 x i8] undef }>, { %std.target.LinuxVersionRange, i2, [3 x i8] } { %std.target.LinuxVersionRange { %std.builtin.Range { %std.builtin.Version { i32 4, i32 19, i32 0 }, %std.builtin.Version { i32 4, i32 19, i32 0 } }, %std.builtin.Version { i32 2, i32 28, i32 0 } }, i2 -2, [3 x i8] undef } }, align 4
@0 = internal unnamed_addr constant [10 x i8] c"ivybridge\00", align 1
@ivybridge = internal unnamed_addr constant { %"[]u8", { %"[]u8", i1, [7 x i8] }, %std.target.Set } { %"[]u8" { i8* getelementptr inbounds ([10 x i8], [10 x i8]* @0, i64 0, i64 0), i64 9 }, { %"[]u8", i1, [7 x i8] } { %"[]u8" { i8* getelementptr inbounds ([10 x i8], [10 x i8]* @0, i64 0, i64 0), i64 9 }, i1 true, [7 x i8] undef }, %std.target.Set { [3 x i64] [i64 685253747084886276, i64 2310381932816443448, i64 21] } }, align 8
@cpu = internal unnamed_addr constant { <{ i6, [7 x i8] }>, %std.target.Model*, %std.target.Set } { <{ i6, [7 x i8] }> <{ i6 31, [7 x i8] undef }>, %std.target.Model* bitcast ({ %"[]u8", { %"[]u8", i1, [7 x i8] }, %std.target.Set }* @ivybridge to %std.target.Model*), %std.target.Set { [3 x i64] [i64 685253747084886276, i64 2332477718471452728, i64 21] } }, align 8
@abi = internal unnamed_addr constant i5 1, align 1
@current = internal unnamed_addr constant { { <{ i6, [7 x i8] }>, %std.target.Model*, %std.target.Set }, { <{ i6, [3 x i8] }>, { %std.target.LinuxVersionRange, i2, [3 x i8] } }, <{ i5, [3 x i8] }> } { { <{ i6, [7 x i8] }>, %std.target.Model*, %std.target.Set } { <{ i6, [7 x i8] }> <{ i6 31, [7 x i8] undef }>, %std.target.Model* bitcast ({ %"[]u8", { %"[]u8", i1, [7 x i8] }, %std.target.Set }* @ivybridge to %std.target.Model*), %std.target.Set { [3 x i64] [i64 685253747084886276, i64 2332477718471452728, i64 21] } }, { <{ i6, [3 x i8] }>, { %std.target.LinuxVersionRange, i2, [3 x i8] } } { <{ i6, [3 x i8] }> <{ i6 8, [3 x i8] undef }>, { %std.target.LinuxVersionRange, i2, [3 x i8] } { %std.target.LinuxVersionRange { %std.builtin.Range { %std.builtin.Version { i32 4, i32 19, i32 0 }, %std.builtin.Version { i32 4, i32 19, i32 0 } }, %std.builtin.Version { i32 2, i32 28, i32 0 } }, i2 -2, [3 x i8] undef } }, <{ i5, [3 x i8] }> <{ i5 1, [3 x i8] undef }> }, align 8
@arch = internal unnamed_addr constant i6 31, align 1
@1 = internal unnamed_addr constant [7 x i8] c"_start\00", align 1
@start_sym_name = internal unnamed_addr constant [7 x i8]* @1, align 8
@single_threaded = internal unnamed_addr constant i1 true, align 1
@mode = internal unnamed_addr constant i2 0, align 1
@runtime_safety = internal unnamed_addr constant i1 true, align 1
@lock_init = internal unnamed_addr constant i1 false, align 1
@stderr_mutex = internal unnamed_addr global %std.mutex.Dummy zeroinitializer, align 1
@is_mips = internal unnamed_addr constant i1 false, align 1
@is_sparc = internal unnamed_addr constant i1 false, align 1
@mode.2 = internal unnamed_addr constant i1 false, align 1
@is_async = internal unnamed_addr constant i1 false, align 1
@is_windows = internal unnamed_addr constant i1 false, align 1
@assert = internal unnamed_addr constant void (i1)* @std.debug.assert, align 8
@errno = internal unnamed_addr constant i12 (i64)* @std.os.linux.getErrno, align 8
@unexpected_error_tracing = internal unnamed_addr constant i1 true, align 1
@strip_debug_info = internal unnamed_addr constant i1 true, align 1
@assert.3 = internal unnamed_addr constant void (i1)* @std.debug.assert, align 8
@assert.4 = internal unnamed_addr constant void (i1)* @std.debug.assert, align 8
@2 = internal unnamed_addr constant %ParamType { %BuiltinEnum undef, i2 1 }, align 8
@3 = internal unnamed_addr constant [20 x i8] c"what happened to me\00", align 1
@4 = internal unnamed_addr constant %CallArg { %Expression { %EnumLiteral { %"[]u8" { i8* getelementptr inbounds ([20 x i8], [20 x i8]* @3, i64 0, i64 0), i64 19 } }, i1 true } }, align 8
@5 = internal unnamed_addr constant [31 x i8] c"access of inactive union field\00", align 1
@6 = internal unnamed_addr constant %"[]u8" { i8* getelementptr inbounds ([31 x i8], [31 x i8]* @5, i64 0, i64 0), i64 30 }, align 8
@7 = internal unnamed_addr constant [3 x i64] zeroinitializer, align 8
@8 = internal unnamed_addr constant [17 x i8] c"division by zero\00", align 1
@9 = internal unnamed_addr constant %"[]u8" { i8* getelementptr inbounds ([17 x i8], [17 x i8]* @8, i64 0, i64 0), i64 16 }, align 8
@10 = internal unnamed_addr constant [45 x i8] c"remainder division by zero or negative value\00", align 1
@11 = internal unnamed_addr constant %"[]u8" { i8* getelementptr inbounds ([45 x i8], [45 x i8]* @10, i64 0, i64 0), i64 44 }, align 8
@12 = internal unnamed_addr constant [28 x i8] c"integer cast truncated bits\00", align 1
@13 = internal unnamed_addr constant %"[]u8" { i8* getelementptr inbounds ([28 x i8], [28 x i8]* @12, i64 0, i64 0), i64 27 }, align 8
@14 = internal unnamed_addr constant [20 x i8] c"index out of bounds\00", align 1
@15 = internal unnamed_addr constant %"[]u8" { i8* getelementptr inbounds ([20 x i8], [20 x i8]* @14, i64 0, i64 0), i64 19 }, align 8
@16 = internal unnamed_addr constant [25 x i8] c"reached unreachable code\00", align 1
@17 = internal unnamed_addr constant %"[]u8" { i8* getelementptr inbounds ([25 x i8], [25 x i8]* @16, i64 0, i64 0), i64 24 }, align 8
@18 = internal unnamed_addr constant %ExpressionResult { %TempRef undef, i2 0 }, align 8
@19 = internal unnamed_addr constant [18 x i8] c"deadlock detected\00", align 1
@20 = internal unnamed_addr constant %"[]u8" { i8* getelementptr inbounds ([18 x i8], [18 x i8]* @19, i64 0, i64 0), i64 17 }, align 8
@21 = internal unnamed_addr constant %"?std.mutex.Held" { %std.mutex.Held undef, i1 false }, align 8
@22 = internal unnamed_addr constant { %"?usize", %"?usize", i2, <{ i8, [6 x i8] }> } { %"?usize" { i64 undef, i1 false }, %"?usize" { i64 undef, i1 false }, i2 -2, <{ i8, [6 x i8] }> <{ i8 32, [6 x i8] undef }> }, align 8
@23 = internal unnamed_addr constant %"?usize" { i64 undef, i1 false }, align 8
@24 = internal unnamed_addr constant %"?usize" { i64 undef, i1 false }, align 8
@25 = internal unnamed_addr constant %"?usize" { i64 undef, i1 false }, align 8
@26 = internal unnamed_addr constant %"?usize" { i64 undef, i1 false }, align 8
@27 = internal unnamed_addr constant %"?usize" { i64 undef, i1 false }, align 8
@28 = internal unnamed_addr constant %"?usize" { i64 undef, i1 false }, align 8
@29 = internal unnamed_addr constant %"?usize" { i64 undef, i1 false }, align 8
@30 = internal unnamed_addr constant %"?usize" { i64 undef, i1 false }, align 8
@31 = internal unnamed_addr constant [17 x i8] c"integer overflow\00", align 1
@32 = internal unnamed_addr constant %"[]u8" { i8* getelementptr inbounds ([17 x i8], [17 x i8]* @31, i64 0, i64 0), i64 16 }, align 8
@33 = internal unnamed_addr constant [51 x i8] c"attempt to cast negative value to unsigned integer\00", align 1
@34 = internal unnamed_addr constant %"[]u8" { i8* getelementptr inbounds ([51 x i8], [51 x i8]* @33, i64 0, i64 0), i64 50 }, align 8
@35 = internal unnamed_addr constant %"?usize" { i64 undef, i1 false }, align 8
@36 = internal unnamed_addr constant [31 x i8] c"cast causes pointer to be null\00", align 1
@37 = internal unnamed_addr constant %"[]u8" { i8* getelementptr inbounds ([31 x i8], [31 x i8]* @36, i64 0, i64 0), i64 30 }, align 8
@38 = internal unnamed_addr constant [43 x i8] c"shift amount is greater than the type size\00", align 1
@39 = internal unnamed_addr constant %"[]u8" { i8* getelementptr inbounds ([43 x i8], [43 x i8]* @38, i64 0, i64 0), i64 42 }, align 8
@40 = internal unnamed_addr constant { %"?usize", %"?usize", i2, <{ i8, [6 x i8] }> } { %"?usize" { i64 undef, i1 false }, %"?usize" { i64 undef, i1 false }, i2 -2, <{ i8, [6 x i8] }> <{ i8 32, [6 x i8] undef }> }, align 8
@41 = internal unnamed_addr constant [22 x i8] c"unexpected errno: {}\0A\00", align 1
@42 = internal unnamed_addr constant %"[]u8" { i8* getelementptr inbounds ([22 x i8], [22 x i8]* @41, i64 0, i64 0), i64 18 }, align 8
@43 = internal unnamed_addr constant %"?usize" { i64 undef, i1 false }, align 8
@44 = internal unnamed_addr constant %"?usize" { i64 undef, i1 false }, align 8
@45 = internal unnamed_addr constant %"?usize" { i64 undef, i1 false }, align 8
@46 = internal unnamed_addr constant %"?usize" { i64 undef, i1 false }, align 8
@47 = internal unnamed_addr constant %"[]u8" { i8* getelementptr inbounds ([22 x i8], [22 x i8]* @41, i64 0, i64 20), i64 1 }, align 8
@48 = internal unnamed_addr constant { %"?usize", %"?usize", i2, <{ i8, [6 x i8] }> } { %"?usize" { i64 undef, i1 false }, %"?usize" { i64 undef, i1 false }, i2 -2, <{ i8, [6 x i8] }> <{ i8 32, [6 x i8] undef }> }, align 8
@49 = internal unnamed_addr constant [49 x i8] c"Unable to dump stack trace: debug info stripped\0A\00", align 1
@50 = internal unnamed_addr constant %"[]u8" { i8* getelementptr inbounds ([49 x i8], [49 x i8]* @49, i64 0, i64 0), i64 48 }, align 8
; Function Attrs: nobuiltin noreturn nounwind
define internal fastcc void @panic(%"[]u8"* nonnull readonly align 8 %0, %std.builtin.StackTrace* align 8 %1) unnamed_addr #0 {
Entry:
%error_return_trace = alloca %std.builtin.StackTrace*, align 8
store %std.builtin.StackTrace* %1, %std.builtin.StackTrace** %error_return_trace, align 8
br label %WhileCond
WhileCond: ; preds = %WhileCond, %Entry
br label %WhileCond
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.debug.assert(i1 %0) unnamed_addr #1 {
Entry:
%ok = alloca i1, align 1
store i1 %0, i1* %ok, align 1
%1 = load i1, i1* %ok, align 1
%2 = icmp eq i1 %1, false
br i1 %2, label %Then, label %Else
Then: ; preds = %Entry
call fastcc void @panic(%"[]u8"* @17, %std.builtin.StackTrace* null)
unreachable
Else: ; preds = %Entry
br label %EndIf
EndIf: ; preds = %Else
ret void
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i12 @std.os.linux.getErrno(i64 %0) unnamed_addr #1 {
Entry:
%result = alloca i12, align 2
%signed_r = alloca i64, align 8
%r = alloca i64, align 8
store i64 %0, i64* %r, align 8
%1 = load i64, i64* %r, align 8
store i64 %1, i64* %signed_r, align 8
%2 = load i64, i64* %signed_r, align 8
%3 = sext i64 %2 to i65
%4 = icmp sgt i65 %3, -4096
br i1 %4, label %BoolAndTrue, label %BoolAndFalse
BoolAndTrue: ; preds = %Entry
%5 = load i64, i64* %signed_r, align 8
%6 = icmp slt i64 %5, 0
br label %BoolAndFalse
BoolAndFalse: ; preds = %BoolAndTrue, %Entry
%7 = phi i1 [ %4, %Entry ], [ %6, %BoolAndTrue ]
br i1 %7, label %Then, label %Else
Then: ; preds = %BoolAndFalse
%8 = load i64, i64* %signed_r, align 8
%9 = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 0, i64 %8)
%10 = extractvalue { i64, i1 } %9, 0
%11 = extractvalue { i64, i1 } %9, 1
br i1 %11, label %OverflowFail, label %OverflowOk
Else: ; preds = %BoolAndFalse
store i12 0, i12* %result, align 2
br label %EndIf
EndIf: ; preds = %Else, %CastShortenOk
%12 = load i12, i12* %result, align 2
ret i12 %12
OverflowFail: ; preds = %Then
call fastcc void @panic(%"[]u8"* @32, %std.builtin.StackTrace* null)
unreachable
OverflowOk: ; preds = %Then
%13 = icmp sge i64 %10, 0
br i1 %13, label %SignCastOk, label %SignCastFail
SignCastOk: ; preds = %OverflowOk
%14 = trunc i64 %10 to i12
%15 = zext i12 %14 to i64
%16 = icmp eq i64 %10, %15
br i1 %16, label %CastShortenOk, label %CastShortenFail
SignCastFail: ; preds = %OverflowOk
call fastcc void @panic(%"[]u8"* @34, %std.builtin.StackTrace* null)
unreachable
CastShortenOk: ; preds = %SignCastOk
store i12 %14, i12* %result, align 2
br label %EndIf
CastShortenFail: ; preds = %SignCastOk
call fastcc void @panic(%"[]u8"* @13, %std.builtin.StackTrace* null)
unreachable
}
; Function Attrs: nobuiltin noinline nounwind alignstack(16)
define void @_start() #2 {
Entry:
%param = alloca %ParamType, align 8
%arg = alloca %CallArg, align 8
%result = alloca %ExpressionResult, align 8
%old = alloca %"[]u8", align 8
%derp = alloca %ExpressionResult, align 8
%0 = alloca %"struct:96:29", align 8
%1 = bitcast %ParamType* %param to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %1, i8* align 8 bitcast (%ParamType* @2 to i8*), i64 24, i1 false)
%2 = bitcast %CallArg* %arg to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %2, i8* align 8 bitcast (%CallArg* @4 to i8*), i64 24, i1 false)
%3 = getelementptr inbounds %CallArg, %CallArg* %arg, i32 0, i32 0
call fastcc void @genExpression(%ExpressionResult* sret %result, %Expression* %3)
%4 = getelementptr inbounds %ExpressionResult, %ExpressionResult* %result, i32 0, i32 1
%5 = load i2, i2* %4, align 1
%6 = icmp eq i2 %5, -2
br i1 %6, label %UnionCheckOk, label %UnionCheckFail
UnionCheckOk: ; preds = %Entry
%7 = getelementptr inbounds %ExpressionResult, %ExpressionResult* %result, i32 0, i32 0
%8 = bitcast %TempRef* %7 to %"[]u8"*
%9 = bitcast %"[]u8"* %8 to i8*
%10 = bitcast %"[]u8"* %old to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %10, i8* align 8 %9, i64 16, i1 false)
call fastcc void @commitCalleeParam(%ExpressionResult* sret %derp, %ExpressionResult* %result, %ParamType* %param)
%11 = getelementptr inbounds %ExpressionResult, %ExpressionResult* %result, i32 0, i32 1
%12 = load i2, i2* %11, align 1
%13 = icmp eq i2 %12, -2
br i1 %13, label %UnionCheckOk1, label %UnionCheckFail2
UnionCheckFail: ; preds = %Entry
call fastcc void @panic(%"[]u8"* @6, %std.builtin.StackTrace* null)
unreachable
UnionCheckOk1: ; preds = %UnionCheckOk
%14 = getelementptr inbounds %ExpressionResult, %ExpressionResult* %result, i32 0, i32 0
%15 = bitcast %TempRef* %14 to %"[]u8"*
%16 = getelementptr inbounds %"struct:96:29", %"struct:96:29"* %0, i32 0, i32 0
%17 = bitcast %"[]u8"* %15 to i8*
%18 = bitcast %"[]u8"* %16 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %18, i8* align 8 %17, i64 16, i1 false)
%19 = getelementptr inbounds %"struct:96:29", %"struct:96:29"* %0, i32 0, i32 1
%20 = bitcast %"[]u8"* %old to i8*
%21 = bitcast %"[]u8"* %19 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %21, i8* align 8 %20, i64 16, i1 false)
call fastcc void @std.debug.print(%"struct:96:29"* %0)
ret void
UnionCheckFail2: ; preds = %UnionCheckOk
call fastcc void @panic(%"[]u8"* @6, %std.builtin.StackTrace* null)
unreachable
}
; Function Attrs: argmemonly nounwind willreturn
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #3
; Function Attrs: nobuiltin nounwind
define internal fastcc void @genExpression(%ExpressionResult* nonnull sret %0, %Expression* nonnull readonly align 8 %1) unnamed_addr #1 {
Entry:
%value = alloca i1, align 1
%v = alloca %EnumLiteral, align 8
%result = alloca %ExpressionResult, align 8
%2 = getelementptr inbounds %Expression, %Expression* %1, i32 0, i32 1
%3 = load i1, i1* %2, align 1
switch i1 %3, label %SwitchElse [
i1 false, label %SwitchProng
i1 true, label %SwitchProng1
]
SwitchProng: ; preds = %Entry
%4 = getelementptr inbounds %Expression, %Expression* %1, i32 0, i32 0
%5 = bitcast %EnumLiteral* %4 to i1*
%6 = load i1, i1* %5, align 1
store i1 %6, i1* %value, align 1
%7 = getelementptr inbounds %ExpressionResult, %ExpressionResult* %0, i32 0, i32 1
store i2 1, i2* %7, align 1
%8 = getelementptr inbounds %ExpressionResult, %ExpressionResult* %0, i32 0, i32 0
%9 = bitcast %TempRef* %8 to i1*
%10 = load i1, i1* %value, align 1
store i1 %10, i1* %9, align 1
ret void
SwitchProng1: ; preds = %Entry
%11 = getelementptr inbounds %Expression, %Expression* %1, i32 0, i32 0
%12 = bitcast %EnumLiteral* %11 to i8*
%13 = bitcast %EnumLiteral* %v to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %13, i8* align 8 %12, i64 16, i1 false)
%14 = getelementptr inbounds %ExpressionResult, %ExpressionResult* %result, i32 0, i32 1
store i2 -2, i2* %14, align 1
%15 = getelementptr inbounds %ExpressionResult, %ExpressionResult* %result, i32 0, i32 0
%16 = bitcast %TempRef* %15 to %"[]u8"*
%17 = getelementptr inbounds %EnumLiteral, %EnumLiteral* %v, i32 0, i32 0
%18 = bitcast %"[]u8"* %17 to i8*
%19 = bitcast %"[]u8"* %16 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %19, i8* align 8 %18, i64 16, i1 false)
%20 = bitcast %ExpressionResult* %result to i8*
%21 = bitcast %ExpressionResult* %0 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %21, i8* align 8 %20, i64 24, i1 false)
ret void
SwitchElse: ; preds = %Entry
call fastcc void @panic(%"[]u8"* @17, %std.builtin.StackTrace* null)
unreachable
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @commitCalleeParam(%ExpressionResult* nonnull sret %0, %ExpressionResult* nonnull readonly align 8 %1, %ParamType* nonnull readonly align 8 %2) unnamed_addr #1 {
Entry:
%rr = alloca %ExpressionResult, align 8
%3 = getelementptr inbounds %ParamType, %ParamType* %2, i32 0, i32 1
%4 = load i2, i2* %3, align 1
switch i2 %4, label %SwitchElse [
i2 0, label %SwitchProng
i2 1, label %SwitchProng1
i2 -2, label %SwitchProng2
]
SwitchProng: ; preds = %Entry
%5 = bitcast %ExpressionResult* %1 to i8*
%6 = bitcast %ExpressionResult* %0 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %6, i8* align 8 %5, i64 24, i1 false)
ret void
SwitchProng1: ; preds = %Entry
%7 = bitcast %ExpressionResult* %rr to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %7, i8* align 8 bitcast (%ExpressionResult* @18 to i8*), i64 24, i1 false)
%8 = getelementptr inbounds %ExpressionResult, %ExpressionResult* %rr, i32 0, i32 1
%9 = load i2, i2* %8, align 1
%10 = icmp eq i2 %9, 0
br i1 %10, label %UnionCheckOk, label %UnionCheckFail
SwitchProng2: ; preds = %Entry
%11 = bitcast %ExpressionResult* %1 to i8*
%12 = bitcast %ExpressionResult* %0 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %12, i8* align 8 %11, i64 24, i1 false)
ret void
SwitchElse: ; preds = %Entry
call fastcc void @panic(%"[]u8"* @17, %std.builtin.StackTrace* null)
unreachable
UnionCheckOk: ; preds = %SwitchProng1
%13 = getelementptr inbounds %ExpressionResult, %ExpressionResult* %rr, i32 0, i32 0
%14 = getelementptr inbounds %TempRef, %TempRef* %13, i32 0, i32 0
store i64 0, i64* %14, align 8
%15 = getelementptr inbounds %TempRef, %TempRef* %13, i32 0, i32 1
store i1 true, i1* %15, align 1
%16 = bitcast %ExpressionResult* %rr to i8*
%17 = bitcast %ExpressionResult* %0 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %17, i8* align 8 %16, i64 24, i1 false)
ret void
UnionCheckFail: ; preds = %SwitchProng1
call fastcc void @panic(%"[]u8"* @6, %std.builtin.StackTrace* null)
unreachable
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.debug.print(%"struct:96:29"* nonnull readonly align 8 %0) unnamed_addr #1 {
Entry:
%held = alloca %std.mutex.Held, align 8
%1 = alloca %std.fs.file.File, align 4
%stderr = alloca %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)", align 4
%2 = alloca %"struct:96:29", align 8
%3 = alloca i16, align 2
call fastcc void @std.mutex.Dummy.acquire(%std.mutex.Held* sret %held, %std.mutex.Dummy* @stderr_mutex)
call fastcc void @std.io.getStdErr(%std.fs.file.File* sret %1)
call fastcc void @std.fs.file.File.writer(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* sret %stderr, %std.fs.file.File* %1)
%4 = bitcast %"struct:96:29"* %0 to i8*
%5 = bitcast %"struct:96:29"* %2 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %5, i8* align 8 %4, i64 32, i1 false)
%6 = call fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %stderr, %"struct:96:29"* %0)
store i16 %6, i16* %3, align 2
%7 = icmp ne i16 %6, 0
br i1 %7, label %UnwrapErrError, label %UnwrapErrOk
UnwrapErrError: ; preds = %Entry
call fastcc void @std.mutex.Held.release(%std.mutex.Held* %held)
ret void
UnwrapErrOk: ; preds = %Entry
br label %UnwrapErrEnd
UnwrapErrEnd: ; preds = %UnwrapErrOk
call fastcc void @std.mutex.Held.release(%std.mutex.Held* %held)
ret void
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @"std.target.Feature.feature_set_fns(std.target.x86.Feature).featureSet"(%std.target.Set* nonnull sret %0, %"[]std.target.x86.Feature"* nonnull readonly align 8 %1) unnamed_addr #1 {
Entry:
%x = alloca %std.target.Set, align 8
%i = alloca i64, align 8
%feature = alloca i8, align 1
call fastcc void @std.target.Set.empty_workaround(%std.target.Set* sret %x)
store i64 0, i64* %i, align 8
%2 = getelementptr inbounds %"[]std.target.x86.Feature", %"[]std.target.x86.Feature"* %1, i32 0, i32 1
%3 = load i64, i64* %2, align 8
br label %ForCond
ForCond: ; preds = %ForBody, %Entry
%4 = load i64, i64* %i, align 8
%5 = icmp ult i64 %4, %3
br i1 %5, label %ForBody, label %ForEnd
ForBody: ; preds = %ForCond
%6 = getelementptr inbounds %"[]std.target.x86.Feature", %"[]std.target.x86.Feature"* %1, i32 0, i32 0
%7 = load i8*, i8** %6, align 8
%8 = getelementptr inbounds i8, i8* %7, i64 %4
%9 = load i8, i8* %8, align 1
store i8 %9, i8* %feature, align 1
%10 = load i8, i8* %feature, align 1
call fastcc void @std.target.Set.addFeature(%std.target.Set* %x, i8 %10)
%11 = add nuw i64 %4, 1
store i64 %11, i64* %i, align 8
br label %ForCond
ForEnd: ; preds = %ForCond
%12 = bitcast %std.target.Set* %x to i8*
%13 = bitcast %std.target.Set* %0 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %13, i8* align 8 %12, i64 24, i1 false)
ret void
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.target.Set.empty_workaround(%std.target.Set* nonnull sret %0) unnamed_addr #1 {
Entry:
%1 = getelementptr inbounds %std.target.Set, %std.target.Set* %0, i32 0, i32 0
%2 = bitcast [3 x i64]* %1 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %2, i8* align 8 bitcast ([3 x i64]* @7 to i8*), i64 24, i1 false)
ret void
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.target.Set.addFeature(%std.target.Set* nonnull align 8 %0, i8 %1) unnamed_addr #1 {
Entry:
%usize_index = alloca i8, align 1
%bit_index = alloca i6, align 1
%set = alloca %std.target.Set*, align 8
%arch_feature_index = alloca i8, align 1
store %std.target.Set* %0, %std.target.Set** %set, align 8
store i8 %1, i8* %arch_feature_index, align 1
%2 = load i8, i8* %arch_feature_index, align 1
br i1 false, label %DivZeroFail, label %DivZeroOk
DivZeroFail: ; preds = %Entry
call fastcc void @panic(%"[]u8"* @9, %std.builtin.StackTrace* null)
unreachable
DivZeroOk: ; preds = %Entry
%3 = udiv i8 %2, 64
store i8 %3, i8* %usize_index, align 1
%4 = load i8, i8* %arch_feature_index, align 1
br i1 false, label %RemZeroFail, label %RemZeroOk
RemZeroOk: ; preds = %DivZeroOk
%5 = urem i8 %4, 64
%6 = trunc i8 %5 to i6
%7 = zext i6 %6 to i8
%8 = icmp eq i8 %5, %7
br i1 %8, label %CastShortenOk, label %CastShortenFail
RemZeroFail: ; preds = %DivZeroOk
call fastcc void @panic(%"[]u8"* @11, %std.builtin.StackTrace* null)
unreachable
CastShortenOk: ; preds = %RemZeroOk
store i6 %6, i6* %bit_index, align 1
%9 = load %std.target.Set*, %std.target.Set** %set, align 8
%10 = getelementptr inbounds %std.target.Set, %std.target.Set* %9, i32 0, i32 0
%11 = load i8, i8* %usize_index, align 1
%12 = zext i8 %11 to i64
%13 = icmp ult i64 %12, 3
br i1 %13, label %BoundsCheckOk, label %BoundsCheckFail
CastShortenFail: ; preds = %RemZeroOk
call fastcc void @panic(%"[]u8"* @13, %std.builtin.StackTrace* null)
unreachable
BoundsCheckFail: ; preds = %CastShortenOk
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk: ; preds = %CastShortenOk
%14 = getelementptr inbounds [3 x i64], [3 x i64]* %10, i64 0, i64 %12
%15 = load i64, i64* %14, align 8
%16 = load i6, i6* %bit_index, align 1
%17 = zext i6 %16 to i64
%18 = shl i64 1, %17
%19 = or i64 %15, %18
store i64 %19, i64* %14, align 8
ret void
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i1 @std.target.Arch.isWasm(i6 %0) unnamed_addr #1 {
Entry:
%result = alloca i1, align 1
%arch = alloca i6, align 1
store i6 %0, i6* %arch, align 1
%1 = load i6, i6* %arch, align 1
switch i6 %1, label %SwitchElse [
i6 -18, label %SwitchProng
i6 -17, label %SwitchProng
]
SwitchElse: ; preds = %Entry
store i1 false, i1* %result, align 1
br label %SwitchEnd
SwitchProng: ; preds = %Entry, %Entry
store i1 true, i1* %result, align 1
br label %SwitchEnd
SwitchEnd: ; preds = %SwitchProng, %SwitchElse
%2 = load i1, i1* %result, align 1
ret i1 %2
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i1 @std.target.Arch.isMIPS(i6 %0) unnamed_addr #1 {
Entry:
%result = alloca i1, align 1
%arch = alloca i6, align 1
store i6 %0, i6* %arch, align 1
%1 = load i6, i6* %arch, align 1
switch i6 %1, label %SwitchElse [
i6 10, label %SwitchProng
i6 11, label %SwitchProng
i6 12, label %SwitchProng
i6 13, label %SwitchProng
]
SwitchElse: ; preds = %Entry
store i1 false, i1* %result, align 1
br label %SwitchEnd
SwitchProng: ; preds = %Entry, %Entry, %Entry, %Entry
store i1 true, i1* %result, align 1
br label %SwitchEnd
SwitchEnd: ; preds = %SwitchProng, %SwitchElse
%2 = load i1, i1* %result, align 1
ret i1 %2
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.mutex.Dummy.acquire(%std.mutex.Held* nonnull sret %0, %std.mutex.Dummy* nonnull align 1 %1) unnamed_addr #1 {
Entry:
%2 = alloca %"?std.mutex.Held", align 8
%self = alloca %std.mutex.Dummy*, align 8
store %std.mutex.Dummy* %1, %std.mutex.Dummy** %self, align 8
%3 = load %std.mutex.Dummy*, %std.mutex.Dummy** %self, align 8
call fastcc void @std.mutex.Dummy.tryAcquire(%"?std.mutex.Held"* sret %2, %std.mutex.Dummy* %3)
%4 = getelementptr inbounds %"?std.mutex.Held", %"?std.mutex.Held"* %2, i32 0, i32 1
%5 = load i1, i1* %4, align 1
br i1 %5, label %OptionalNonNull, label %OptionalNull
OptionalNull: ; preds = %Entry
call fastcc void @panic(%"[]u8"* @20, %std.builtin.StackTrace* null)
unreachable
OptionalNonNull: ; preds = %Entry
%6 = getelementptr inbounds %"?std.mutex.Held", %"?std.mutex.Held"* %2, i32 0, i32 0
%7 = bitcast %std.mutex.Held* %6 to i8*
%8 = bitcast %std.mutex.Held* %0 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %8, i8* align 8 %7, i64 8, i1 false)
ret void
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.io.getStdErr(%std.fs.file.File* nonnull sret %0) unnamed_addr #1 {
Entry:
%1 = getelementptr inbounds %std.fs.file.File, %std.fs.file.File* %0, i32 0, i32 0
%2 = call fastcc i32 @std.io.getStdErrHandle()
store i32 %2, i32* %1, align 4
ret void
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.fs.file.File.writer(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* nonnull sret %0, %std.fs.file.File* nonnull readonly align 4 %1) unnamed_addr #1 {
Entry:
%2 = getelementptr inbounds %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)", %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %0, i32 0, i32 0
%3 = bitcast %std.fs.file.File* %1 to i8*
%4 = bitcast %std.fs.file.File* %2 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %4, i8* align 4 %3, i64 4, i1 false)
ret void
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* nonnull readonly align 4 %0, %"struct:96:29"* nonnull readonly align 8 %1) unnamed_addr #1 {
Entry:
%result = alloca i16, align 2
%2 = alloca %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)", align 4
%3 = alloca %"struct:96:29", align 8
%4 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %0 to i8*
%5 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %5, i8* align 4 %4, i64 4, i1 false)
%6 = bitcast %"struct:96:29"* %1 to i8*
%7 = bitcast %"struct:96:29"* %3 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %7, i8* align 8 %6, i64 32, i1 false)
%8 = call fastcc i16 @std.fmt.format(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %0, %"struct:96:29"* %1)
store i16 %8, i16* %result, align 2
%9 = load i16, i16* %result, align 2
ret i16 %9
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.mutex.Held.release(%std.mutex.Held* nonnull readonly align 8 %0) unnamed_addr #1 {
Entry:
%1 = getelementptr inbounds %std.mutex.Held, %std.mutex.Held* %0, i32 0, i32 0
%2 = load %std.mutex.Dummy*, %std.mutex.Dummy** %1, align 8
%3 = getelementptr inbounds %std.mutex.Dummy, %std.mutex.Dummy* %2, i32 0, i32 0
store i1 false, i1* %3, align 1
ret void
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.mutex.Dummy.tryAcquire(%"?std.mutex.Held"* nonnull sret %0, %std.mutex.Dummy* nonnull align 1 %1) unnamed_addr #1 {
Entry:
%self = alloca %std.mutex.Dummy*, align 8
store %std.mutex.Dummy* %1, %std.mutex.Dummy** %self, align 8
%2 = load %std.mutex.Dummy*, %std.mutex.Dummy** %self, align 8
%3 = getelementptr inbounds %std.mutex.Dummy, %std.mutex.Dummy* %2, i32 0, i32 0
%4 = load i1, i1* %3, align 1
br i1 %4, label %Then, label %Else
Then: ; preds = %Entry
%5 = bitcast %"?std.mutex.Held"* %0 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %5, i8* align 8 bitcast (%"?std.mutex.Held"* @21 to i8*), i64 16, i1 false)
ret void
Else: ; preds = %Entry
br label %EndIf
EndIf: ; preds = %Else
%6 = load %std.mutex.Dummy*, %std.mutex.Dummy** %self, align 8
%7 = getelementptr inbounds %std.mutex.Dummy, %std.mutex.Dummy* %6, i32 0, i32 0
store i1 true, i1* %7, align 1
%8 = getelementptr inbounds %"?std.mutex.Held", %"?std.mutex.Held"* %0, i32 0, i32 1
store i1 true, i1* %8, align 1
%9 = getelementptr inbounds %"?std.mutex.Held", %"?std.mutex.Held"* %0, i32 0, i32 0
%10 = getelementptr inbounds %std.mutex.Held, %std.mutex.Held* %9, i32 0, i32 0
%11 = load %std.mutex.Dummy*, %std.mutex.Dummy** %self, align 8
store %std.mutex.Dummy* %11, %std.mutex.Dummy** %10, align 8
%12 = getelementptr inbounds %"?std.mutex.Held", %"?std.mutex.Held"* %0, i32 0, i32 1
store i1 true, i1* %12, align 1
%13 = getelementptr inbounds %"?std.mutex.Held", %"?std.mutex.Held"* %0, i32 0, i32 0
%14 = bitcast %std.mutex.Held* %9 to i8*
%15 = bitcast %std.mutex.Held* %13 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %15, i8* align 8 %14, i64 8, i1 false)
ret void
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i1 @std.target.Arch.isSPARC(i6 %0) unnamed_addr #1 {
Entry:
%result = alloca i1, align 1
%arch = alloca i6, align 1
store i6 %0, i6* %arch, align 1
%1 = load i6, i6* %arch, align 1
switch i6 %1, label %SwitchElse [
i6 22, label %SwitchProng
i6 24, label %SwitchProng
i6 23, label %SwitchProng
]
SwitchElse: ; preds = %Entry
store i1 false, i1* %result, align 1
br label %SwitchEnd
SwitchProng: ; preds = %Entry, %Entry, %Entry
store i1 true, i1* %result, align 1
br label %SwitchEnd
SwitchEnd: ; preds = %SwitchProng, %SwitchElse
%2 = load i1, i1* %result, align 1
ret i1 %2
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i32 @std.io.getStdErrHandle() unnamed_addr #1 {
Entry:
%result = alloca i32, align 4
store i32 2, i32* %result, align 4
%0 = load i32, i32* %result, align 4
ret i32 %0
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.fs.file.File.write({ i64, i16 }* nonnull sret %0, %std.fs.file.File* nonnull readonly align 4 %1, %"[]u8"* nonnull readonly align 8 %2) unnamed_addr #1 {
Entry:
%3 = getelementptr inbounds %std.fs.file.File, %std.fs.file.File* %1, i32 0, i32 0
%4 = load i32, i32* %3, align 4
call fastcc void @std.os.write({ i64, i16 }* sret %0, i32 %4, %"[]u8"* %2)
ret void
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.os.write({ i64, i16 }* nonnull sret %0, i32 %1, %"[]u8"* nonnull readonly align 8 %2) unnamed_addr #1 {
Entry:
%3 = alloca i64, align 8
%adjusted_len = alloca i64, align 8
%rc = alloca i64, align 8
%4 = alloca i12, align 2
%err = alloca i12, align 2
%fd = alloca i32, align 4
store i32 %1, i32* %fd, align 4
%5 = getelementptr inbounds %"[]u8", %"[]u8"* %2, i32 0, i32 1
%6 = load i64, i64* %5, align 8
store i64 %6, i64* %3, align 8
%7 = call fastcc i64 @std.math.min(i64 %6)
store i64 %7, i64* %adjusted_len, align 8
br label %WhileCond
WhileCond: ; preds = %SwitchProng1, %Entry
br label %WhileBody
WhileBody: ; preds = %WhileCond
%8 = load i32, i32* %fd, align 4
%9 = getelementptr inbounds %"[]u8", %"[]u8"* %2, i32 0, i32 0
%10 = load i8*, i8** %9, align 8
%11 = load i64, i64* %adjusted_len, align 8
%12 = call fastcc i64 @std.os.linux.write(i32 %8, i8* %10, i64 %11)
store i64 %12, i64* %rc, align 8
%13 = load i64, i64* %rc, align 8
%14 = call fastcc i12 @std.os.linux.getErrno(i64 %13)
store i12 %14, i12* %4, align 2
switch i12 %14, label %SwitchElse [
i12 0, label %SwitchProng
i12 4, label %SwitchProng1
i12 22, label %SwitchProng2
i12 14, label %SwitchProng3
i12 11, label %SwitchProng4
i12 9, label %SwitchProng5
i12 89, label %SwitchProng6
i12 122, label %SwitchProng7
i12 27, label %SwitchProng8
i12 5, label %SwitchProng9
i12 28, label %SwitchProng10
i12 1, label %SwitchProng11
i12 32, label %SwitchProng12
]
SwitchElse: ; preds = %WhileBody
store i12 %14, i12* %err, align 2
%15 = load i12, i12* %err, align 2
%16 = zext i12 %15 to i64
%17 = call fastcc i16 @std.os.unexpectedErrno(i64 %16)
%18 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %0, i32 0, i32 1
store i16 %17, i16* %18, align 2
ret void
SwitchProng: ; preds = %WhileBody
%19 = load i64, i64* %rc, align 8
%20 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %0, i32 0, i32 1
store i16 0, i16* %20, align 2
%21 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %0, i32 0, i32 0
store i64 %19, i64* %21, align 8
ret void
SwitchProng1: ; preds = %WhileBody
br label %WhileCond
SwitchProng2: ; preds = %WhileBody
call fastcc void @panic(%"[]u8"* @17, %std.builtin.StackTrace* null)
unreachable
SwitchProng3: ; preds = %WhileBody
call fastcc void @panic(%"[]u8"* @17, %std.builtin.StackTrace* null)
unreachable
SwitchProng4: ; preds = %WhileBody
%22 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %0, i32 0, i32 1
store i16 10, i16* %22, align 2
ret void
SwitchProng5: ; preds = %WhileBody
%23 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %0, i32 0, i32 1
store i16 9, i16* %23, align 2
ret void
SwitchProng6: ; preds = %WhileBody
call fastcc void @panic(%"[]u8"* @17, %std.builtin.StackTrace* null)
unreachable
SwitchProng7: ; preds = %WhileBody
%24 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %0, i32 0, i32 1
store i16 1, i16* %24, align 2
ret void
SwitchProng8: ; preds = %WhileBody
%25 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %0, i32 0, i32 1
store i16 2, i16* %25, align 2
ret void
SwitchProng9: ; preds = %WhileBody
%26 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %0, i32 0, i32 1
store i16 3, i16* %26, align 2
ret void
SwitchProng10: ; preds = %WhileBody
%27 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %0, i32 0, i32 1
store i16 4, i16* %27, align 2
ret void
SwitchProng11: ; preds = %WhileBody
%28 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %0, i32 0, i32 1
store i16 5, i16* %28, align 2
ret void
SwitchProng12: ; preds = %WhileBody
%29 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %0, i32 0, i32 1
store i16 6, i16* %29, align 2
ret void
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i16 @std.fmt.format(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* nonnull readonly align 4 %0, %"struct:96:29"* nonnull readonly align 8 %1) unnamed_addr #1 {
Entry:
%result = alloca i16, align 2
%options = alloca %std.fmt.FormatOptions, align 8
%2 = alloca %"[]u8", align 8
%3 = alloca %std.fmt.FormatOptions, align 8
%4 = alloca %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)", align 4
%5 = alloca i16, align 2
%6 = alloca %"[]u8", align 8
%7 = alloca %std.fmt.FormatOptions, align 8
%8 = alloca %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)", align 4
%9 = alloca i16, align 2
%10 = bitcast %std.fmt.FormatOptions* %options to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %10, i8* align 8 bitcast ({ %"?usize", %"?usize", i2, <{ i8, [6 x i8] }> }* @22 to i8*), i64 40, i1 false)
%11 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %options, i32 0, i32 0
%12 = bitcast %"?usize"* %11 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %12, i8* align 8 bitcast (%"?usize"* @23 to i8*), i64 16, i1 false)
%13 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %options, i32 0, i32 1
%14 = bitcast %"?usize"* %13 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %14, i8* align 8 bitcast (%"?usize"* @24 to i8*), i64 16, i1 false)
%15 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %options, i32 0, i32 2
store i2 -2, i2* %15, align 1
%16 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %options, i32 0, i32 3
store i8 32, i8* %16, align 1
%17 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %options, i32 0, i32 1
%18 = bitcast %"?usize"* %17 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %18, i8* align 8 bitcast (%"?usize"* @25 to i8*), i64 16, i1 false)
br label %BlockEnd
BlockEnd: ; preds = %Entry
%19 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %options, i32 0, i32 0
%20 = bitcast %"?usize"* %19 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %20, i8* align 8 bitcast (%"?usize"* @26 to i8*), i64 16, i1 false)
br label %BlockEnd1
BlockEnd1: ; preds = %BlockEnd
%21 = getelementptr inbounds %"struct:96:29", %"struct:96:29"* %1, i32 0, i32 0
%22 = bitcast %"[]u8"* %21 to i8*
%23 = bitcast %"[]u8"* %2 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %23, i8* align 8 %22, i64 16, i1 false)
%24 = bitcast %std.fmt.FormatOptions* %options to i8*
%25 = bitcast %std.fmt.FormatOptions* %3 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %25, i8* align 8 %24, i64 40, i1 false)
%26 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %0 to i8*
%27 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %4 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %27, i8* align 4 %26, i64 4, i1 false)
%28 = call fastcc i16 @std.fmt.formatType(%"[]u8"* %21, %std.fmt.FormatOptions* %options, %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %0, i64 3)
store i16 %28, i16* %5, align 2
%29 = icmp ne i16 %28, 0
br i1 %29, label %ErrRetReturn, label %ErrRetContinue
ErrRetReturn: ; preds = %BlockEnd1
%30 = load i16, i16* %5, align 2
store i16 %30, i16* %result, align 2
ret i16 %30
ErrRetContinue: ; preds = %BlockEnd1
%31 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %options, i32 0, i32 0
%32 = bitcast %"?usize"* %31 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %32, i8* align 8 bitcast (%"?usize"* @27 to i8*), i64 16, i1 false)
%33 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %options, i32 0, i32 1
%34 = bitcast %"?usize"* %33 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %34, i8* align 8 bitcast (%"?usize"* @28 to i8*), i64 16, i1 false)
%35 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %options, i32 0, i32 2
store i2 -2, i2* %35, align 1
%36 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %options, i32 0, i32 3
store i8 32, i8* %36, align 1
%37 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %options, i32 0, i32 1
%38 = bitcast %"?usize"* %37 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %38, i8* align 8 bitcast (%"?usize"* @29 to i8*), i64 16, i1 false)
br label %BlockEnd2
BlockEnd2: ; preds = %ErrRetContinue
%39 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %options, i32 0, i32 0
%40 = bitcast %"?usize"* %39 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %40, i8* align 8 bitcast (%"?usize"* @30 to i8*), i64 16, i1 false)
br label %BlockEnd3
BlockEnd3: ; preds = %BlockEnd2
%41 = getelementptr inbounds %"struct:96:29", %"struct:96:29"* %1, i32 0, i32 1
%42 = bitcast %"[]u8"* %41 to i8*
%43 = bitcast %"[]u8"* %6 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %43, i8* align 8 %42, i64 16, i1 false)
%44 = bitcast %std.fmt.FormatOptions* %options to i8*
%45 = bitcast %std.fmt.FormatOptions* %7 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %45, i8* align 8 %44, i64 40, i1 false)
%46 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %0 to i8*
%47 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %8 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %47, i8* align 4 %46, i64 4, i1 false)
%48 = call fastcc i16 @std.fmt.formatType(%"[]u8"* %41, %std.fmt.FormatOptions* %options, %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %0, i64 3)
store i16 %48, i16* %9, align 2
%49 = icmp ne i16 %48, 0
br i1 %49, label %ErrRetReturn4, label %ErrRetContinue5
ErrRetReturn4: ; preds = %BlockEnd3
%50 = load i16, i16* %9, align 2
store i16 %50, i16* %result, align 2
ret i16 %50
ErrRetContinue5: ; preds = %BlockEnd3
store i16 0, i16* %result, align 2
ret i16 0
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i64 @std.math.min(i64 %0) unnamed_addr #1 {
Entry:
%result = alloca i64, align 8
%y = alloca i64, align 8
store i64 %0, i64* %y, align 8
%1 = load i64, i64* %y, align 8
%2 = icmp ult i64 2147479552, %1
br i1 %2, label %Then, label %Else
Then: ; preds = %Entry
store i64 2147479552, i64* %result, align 8
%3 = load i64, i64* %result, align 8
ret i64 %3
Else: ; preds = %Entry
%4 = load i64, i64* %y, align 8
store i64 %4, i64* %result, align 8
%5 = load i64, i64* %result, align 8
ret i64 %5
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i64 @std.os.linux.write(i32 %0, i8* nonnull readonly align 1 %1, i64 %2) unnamed_addr #1 {
Entry:
%result = alloca i64, align 8
%fd = alloca i32, align 4
%buf = alloca i8*, align 8
%count = alloca i64, align 8
store i32 %0, i32* %fd, align 4
store i8* %1, i8** %buf, align 8
store i64 %2, i64* %count, align 8
%3 = load i32, i32* %fd, align 4
%4 = sext i32 %3 to i64
%5 = sext i32 %3 to i64
%6 = load i8*, i8** %buf, align 8
%7 = ptrtoint i8* %6 to i64
%8 = load i64, i64* %count, align 8
%9 = call fastcc i64 @std.os.linux.x86_64.syscall3(i64 1, i64 %5, i64 %7, i64 %8)
store i64 %9, i64* %result, align 8
%10 = load i64, i64* %result, align 8
ret i64 %10
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i16 @std.os.unexpectedErrno(i64 %0) unnamed_addr #1 {
Entry:
%result = alloca i16, align 2
%1 = alloca %"std.os.struct:4571:51", align 8
%err = alloca i64, align 8
store i64 %0, i64* %err, align 8
%2 = load i64, i64* %err, align 8
%3 = getelementptr inbounds %"std.os.struct:4571:51", %"std.os.struct:4571:51"* %1, i32 0, i32 0
store i64 %2, i64* %3, align 8
call fastcc void @std.debug.print.5(%"std.os.struct:4571:51"* %1)
call fastcc void @std.debug.dumpCurrentStackTrace(%"?usize"* @35)
store i16 11, i16* %result, align 2
%4 = load i16, i16* %result, align 2
ret i16 %4
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i16 @std.fmt.formatType(%"[]u8"* nonnull readonly align 8 %0, %std.fmt.FormatOptions* nonnull readonly align 8 %1, %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* nonnull readonly align 4 %2, i64 %3) unnamed_addr #1 {
Entry:
%result = alloca i16, align 2
%4 = alloca %std.fmt.FormatOptions, align 8
%5 = alloca %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)", align 4
%max_depth = alloca i64, align 8
store i64 %3, i64* %max_depth, align 8
%6 = bitcast %std.fmt.FormatOptions* %1 to i8*
%7 = bitcast %std.fmt.FormatOptions* %4 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %7, i8* align 8 %6, i64 40, i1 false)
%8 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2 to i8*
%9 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %5 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %9, i8* align 4 %8, i64 4, i1 false)
%10 = call fastcc i16 @std.fmt.formatText(%"[]u8"* %0, %std.fmt.FormatOptions* %1, %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2)
store i16 %10, i16* %result, align 2
%11 = load i16, i16* %result, align 2
ret i16 %11
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i16 @std.fmt.formatText(%"[]u8"* nonnull readonly align 8 %0, %std.fmt.FormatOptions* nonnull readonly align 8 %1, %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* nonnull readonly align 4 %2) unnamed_addr #1 {
Entry:
%result = alloca i16, align 2
%3 = alloca %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)", align 4
%4 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2 to i8*
%5 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %3 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %5, i8* align 4 %4, i64 4, i1 false)
%6 = call fastcc i16 @std.fmt.formatBuf(%"[]u8"* %0, %std.fmt.FormatOptions* %1, %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2)
store i16 %6, i16* %result, align 2
%7 = load i16, i16* %result, align 2
ret i16 %7
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i64 @std.os.linux.x86_64.syscall3(i64 %0, i64 %1, i64 %2, i64 %3) unnamed_addr #1 {
Entry:
%result = alloca i64, align 8
%number = alloca i64, align 8
%arg1 = alloca i64, align 8
%arg2 = alloca i64, align 8
%arg3 = alloca i64, align 8
store i64 %0, i64* %number, align 8
store i64 %1, i64* %arg1, align 8
store i64 %2, i64* %arg2, align 8
store i64 %3, i64* %arg3, align 8
%4 = load i64, i64* %number, align 8
%5 = load i64, i64* %arg1, align 8
%6 = load i64, i64* %arg2, align 8
%7 = load i64, i64* %arg3, align 8
%8 = call i64 asm sideeffect "syscall", "={rax},{rax},{rdi},{rsi},{rdx},~{rcx},~{r11},~{memory},~{dirflag},~{fpsr},~{flags}"(i64 %4, i64 %5, i64 %6, i64 %7)
store i64 %8, i64* %result, align 8
%9 = load i64, i64* %result, align 8
ret i64 %9
}
; Function Attrs: nounwind readnone speculatable willreturn
declare { i64, i1 } @llvm.ssub.with.overflow.i64(i64, i64) #4
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.debug.print.5(%"std.os.struct:4571:51"* nonnull readonly align 8 %0) unnamed_addr #1 {
Entry:
%held = alloca %std.mutex.Held, align 8
%1 = alloca %std.fs.file.File, align 4
%stderr = alloca %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)", align 4
%2 = alloca %"std.os.struct:4571:51", align 8
%3 = alloca i16, align 2
call fastcc void @std.mutex.Dummy.acquire(%std.mutex.Held* sret %held, %std.mutex.Dummy* @stderr_mutex)
call fastcc void @std.io.getStdErr(%std.fs.file.File* sret %1)
call fastcc void @std.fs.file.File.writer(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* sret %stderr, %std.fs.file.File* %1)
%4 = bitcast %"std.os.struct:4571:51"* %0 to i8*
%5 = bitcast %"std.os.struct:4571:51"* %2 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %5, i8* align 8 %4, i64 8, i1 false)
%6 = call fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print.7"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %stderr, %"std.os.struct:4571:51"* %0)
store i16 %6, i16* %3, align 2
%7 = icmp ne i16 %6, 0
br i1 %7, label %UnwrapErrError, label %UnwrapErrOk
UnwrapErrError: ; preds = %Entry
call fastcc void @std.mutex.Held.release(%std.mutex.Held* %held)
ret void
UnwrapErrOk: ; preds = %Entry
br label %UnwrapErrEnd
UnwrapErrEnd: ; preds = %UnwrapErrOk
call fastcc void @std.mutex.Held.release(%std.mutex.Held* %held)
ret void
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.debug.dumpCurrentStackTrace(%"?usize"* nonnull readonly align 8 %0) unnamed_addr #1 {
Entry:
%1 = alloca %std.fs.file.File, align 4
%stderr = alloca %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)", align 4
%2 = alloca i16, align 2
call fastcc void @std.io.getStdErr(%std.fs.file.File* sret %1)
call fastcc void @std.fs.file.File.writer(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* sret %stderr, %std.fs.file.File* %1)
%3 = call fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print.8"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %stderr)
store i16 %3, i16* %2, align 2
%4 = icmp ne i16 %3, 0
br i1 %4, label %UnwrapErrError, label %UnwrapErrOk
UnwrapErrError: ; preds = %Entry
ret void
UnwrapErrOk: ; preds = %Entry
br label %UnwrapErrEnd
UnwrapErrEnd: ; preds = %UnwrapErrOk
ret void
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i16 @std.fmt.formatBuf(%"[]u8"* nonnull readonly align 8 %0, %std.fmt.FormatOptions* nonnull readonly align 8 %1, %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* nonnull readonly align 4 %2) unnamed_addr #1 {
Entry:
%result = alloca i16, align 2
%min_width = alloca i64, align 8
%3 = alloca { i64, i16 }, align 8
%_ = alloca i16, align 2
%width = alloca i64, align 8
%padding = alloca i64, align 8
%4 = alloca i16, align 2
%5 = alloca i16, align 2
%left_padding = alloca i64, align 8
%right_padding = alloca i64, align 8
%6 = alloca i16, align 2
%7 = alloca i16, align 2
%8 = alloca i16, align 2
%9 = alloca i16, align 2
%10 = alloca i16, align 2
%11 = alloca i16, align 2
%12 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %1, i32 0, i32 1
%13 = getelementptr inbounds %"?usize", %"?usize"* %12, i32 0, i32 1
%14 = load i1, i1* %13, align 1
br i1 %14, label %OptionalThen, label %OptionalElse
OptionalThen: ; preds = %Entry
%15 = getelementptr inbounds %"?usize", %"?usize"* %12, i32 0, i32 0
%16 = load i64, i64* %15, align 8
store i64 %16, i64* %min_width, align 8
call fastcc void @std.unicode.utf8CountCodepoints({ i64, i16 }* sret %3, %"[]u8"* %0)
%17 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %3, i32 0, i32 1
%18 = load i16, i16* %17, align 2
%19 = icmp ne i16 %18, 0
br i1 %19, label %UnwrapErrError, label %UnwrapErrOk
UnwrapErrError: ; preds = %OptionalThen
%20 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %3, i32 0, i32 1
%21 = load i16, i16* %20, align 2
store i16 %21, i16* %_, align 2
%22 = getelementptr inbounds %"[]u8", %"[]u8"* %0, i32 0, i32 1
%23 = load i64, i64* %22, align 8
store i64 %23, i64* %width, align 8
br label %UnwrapErrEnd
UnwrapErrOk: ; preds = %OptionalThen
%24 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %3, i32 0, i32 0
%25 = load i64, i64* %24, align 8
store i64 %25, i64* %width, align 8
br label %UnwrapErrEnd
UnwrapErrEnd: ; preds = %UnwrapErrOk, %UnwrapErrError
%26 = load i64, i64* %width, align 8
%27 = load i64, i64* %min_width, align 8
%28 = icmp ult i64 %26, %27
br i1 %28, label %Then, label %Else
Then: ; preds = %UnwrapErrEnd
%29 = load i64, i64* %min_width, align 8
%30 = load i64, i64* %width, align 8
%31 = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %29, i64 %30)
%32 = extractvalue { i64, i1 } %31, 0
%33 = extractvalue { i64, i1 } %31, 1
br i1 %33, label %OverflowFail, label %OverflowOk
Else: ; preds = %UnwrapErrEnd
store i64 0, i64* %padding, align 8
br label %EndIf
EndIf: ; preds = %Else, %OverflowOk
%34 = load i64, i64* %padding, align 8
%35 = icmp eq i64 %34, 0
br i1 %35, label %Then1, label %Else2
Then1: ; preds = %EndIf
%36 = call fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeAll"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2, %"[]u8"* %0)
store i16 %36, i16* %result, align 2
%37 = load i16, i16* %result, align 2
ret i16 %37
Else2: ; preds = %EndIf
br label %EndIf3
EndIf3: ; preds = %Else2
%38 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %1, i32 0, i32 2
%39 = load i2, i2* %38, align 1
switch i2 %39, label %SwitchElse [
i2 0, label %SwitchProng
i2 1, label %SwitchProng5
i2 -2, label %SwitchProng11
]
SwitchProng: ; preds = %EndIf3
%40 = call fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeAll"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2, %"[]u8"* %0)
store i16 %40, i16* %4, align 2
%41 = icmp ne i16 %40, 0
br i1 %41, label %ErrRetReturn, label %ErrRetContinue
ErrRetReturn: ; preds = %SwitchProng
%42 = load i16, i16* %4, align 2
store i16 %42, i16* %result, align 2
ret i16 %42
ErrRetContinue: ; preds = %SwitchProng
%43 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %1, i32 0, i32 3
%44 = load i8, i8* %43, align 1
%45 = load i64, i64* %padding, align 8
%46 = call fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeByteNTimes"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2, i8 %44, i64 %45)
store i16 %46, i16* %5, align 2
%47 = icmp ne i16 %46, 0
br i1 %47, label %ErrRetReturn4, label %ErrRetContinue15
ErrRetReturn4: ; preds = %ErrRetContinue
%48 = load i16, i16* %5, align 2
store i16 %48, i16* %result, align 2
ret i16 %48
SwitchProng5: ; preds = %EndIf3
%49 = load i64, i64* %padding, align 8
br i1 false, label %DivZeroFail, label %DivZeroOk
ErrRetReturn6: ; preds = %DivZeroOk23
%50 = load i16, i16* %6, align 2
store i16 %50, i16* %result, align 2
ret i16 %50
ErrRetContinue7: ; preds = %DivZeroOk23
%51 = call fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeAll"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2, %"[]u8"* %0)
store i16 %51, i16* %7, align 2
%52 = icmp ne i16 %51, 0
br i1 %52, label %ErrRetReturn8, label %ErrRetContinue9
ErrRetReturn8: ; preds = %ErrRetContinue7
%53 = load i16, i16* %7, align 2
store i16 %53, i16* %result, align 2
ret i16 %53
ErrRetContinue9: ; preds = %ErrRetContinue7
%54 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %1, i32 0, i32 3
%55 = load i8, i8* %54, align 1
%56 = load i64, i64* %right_padding, align 8
%57 = call fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeByteNTimes"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2, i8 %55, i64 %56)
store i16 %57, i16* %8, align 2
%58 = icmp ne i16 %57, 0
br i1 %58, label %ErrRetReturn10, label %ErrRetContinue16
ErrRetReturn10: ; preds = %ErrRetContinue9
%59 = load i16, i16* %8, align 2
store i16 %59, i16* %result, align 2
ret i16 %59
SwitchProng11: ; preds = %EndIf3
%60 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %1, i32 0, i32 3
%61 = load i8, i8* %60, align 1
%62 = load i64, i64* %padding, align 8
%63 = call fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeByteNTimes"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2, i8 %61, i64 %62)
store i16 %63, i16* %9, align 2
%64 = icmp ne i16 %63, 0
br i1 %64, label %ErrRetReturn12, label %ErrRetContinue13
ErrRetReturn12: ; preds = %SwitchProng11
%65 = load i16, i16* %9, align 2
store i16 %65, i16* %result, align 2
ret i16 %65
ErrRetContinue13: ; preds = %SwitchProng11
%66 = call fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeAll"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2, %"[]u8"* %0)
store i16 %66, i16* %10, align 2
%67 = icmp ne i16 %66, 0
br i1 %67, label %ErrRetReturn14, label %ErrRetContinue17
ErrRetReturn14: ; preds = %ErrRetContinue13
%68 = load i16, i16* %10, align 2
store i16 %68, i16* %result, align 2
ret i16 %68
SwitchElse: ; preds = %EndIf3
call fastcc void @panic(%"[]u8"* @17, %std.builtin.StackTrace* null)
unreachable
ErrRetContinue15: ; preds = %ErrRetContinue
br label %SwitchEnd
ErrRetContinue16: ; preds = %ErrRetContinue9
br label %SwitchEnd
ErrRetContinue17: ; preds = %ErrRetContinue13
br label %SwitchEnd
OptionalElse: ; preds = %Entry
%69 = call fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeAll"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2, %"[]u8"* %0)
store i16 %69, i16* %11, align 2
%70 = icmp ne i16 %69, 0
br i1 %70, label %ErrRetReturn18, label %ErrRetContinue19
ErrRetReturn18: ; preds = %OptionalElse
%71 = load i16, i16* %11, align 2
store i16 %71, i16* %result, align 2
ret i16 %71
SwitchEnd: ; preds = %ErrRetContinue17, %ErrRetContinue16, %ErrRetContinue15
br label %OptionalEndIf
ErrRetContinue19: ; preds = %OptionalElse
br label %OptionalEndIf
OptionalEndIf: ; preds = %ErrRetContinue19, %SwitchEnd
store i16 0, i16* %result, align 2
ret i16 0
OverflowFail: ; preds = %Then
call fastcc void @panic(%"[]u8"* @32, %std.builtin.StackTrace* null)
unreachable
OverflowOk: ; preds = %Then
store i64 %32, i64* %padding, align 8
br label %EndIf
DivZeroFail: ; preds = %SwitchProng5
call fastcc void @panic(%"[]u8"* @9, %std.builtin.StackTrace* null)
unreachable
DivZeroOk: ; preds = %SwitchProng5
%72 = udiv i64 %49, 2
store i64 %72, i64* %left_padding, align 8
%73 = load i64, i64* %padding, align 8
%74 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %73, i64 1)
%75 = extractvalue { i64, i1 } %74, 0
%76 = extractvalue { i64, i1 } %74, 1
br i1 %76, label %OverflowFail20, label %OverflowOk21
OverflowFail20: ; preds = %DivZeroOk
call fastcc void @panic(%"[]u8"* @32, %std.builtin.StackTrace* null)
unreachable
OverflowOk21: ; preds = %DivZeroOk
br i1 false, label %DivZeroFail22, label %DivZeroOk23
DivZeroFail22: ; preds = %OverflowOk21
call fastcc void @panic(%"[]u8"* @9, %std.builtin.StackTrace* null)
unreachable
DivZeroOk23: ; preds = %OverflowOk21
%77 = udiv i64 %75, 2
store i64 %77, i64* %right_padding, align 8
%78 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %1, i32 0, i32 3
%79 = load i8, i8* %78, align 1
%80 = load i64, i64* %left_padding, align 8
%81 = call fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeByteNTimes"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2, i8 %79, i64 %80)
store i16 %81, i16* %6, align 2
%82 = icmp ne i16 %81, 0
br i1 %82, label %ErrRetReturn6, label %ErrRetContinue7
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.unicode.utf8CountCodepoints({ i64, i16 }* nonnull sret %0, %"[]u8"* nonnull readonly align 8 %1) unnamed_addr #1 {
Entry:
%len = alloca i64, align 8
%i = alloca i64, align 8
%2 = alloca %"[]u8", align 8
%3 = alloca [8 x i8]*, align 8
%v = alloca i64, align 8
%4 = alloca { i3, i16 }, align 2
%5 = alloca { i64, i16 }, align 8
%n = alloca i3, align 1
%6 = alloca %"[]u8", align 8
%7 = alloca { i21, i16 }, align 4
%8 = alloca { i64, i16 }, align 8
store i64 0, i64* %len, align 8
store i64 0, i64* %i, align 8
br label %WhileCond
WhileCond: ; preds = %EndIf10, %Entry
%9 = load i64, i64* %i, align 8
%10 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%11 = load i64, i64* %10, align 8
%12 = icmp ult i64 %9, %11
br i1 %12, label %WhileBody, label %WhileEnd11
WhileBody: ; preds = %WhileCond
br label %WhileCond1
WhileCond1: ; preds = %OverflowOk21, %WhileBody
%13 = load i64, i64* %i, align 8
%14 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %13, i64 8)
%15 = extractvalue { i64, i1 } %14, 0
%16 = extractvalue { i64, i1 } %14, 1
br i1 %16, label %OverflowFail, label %OverflowOk
WhileBody2: ; preds = %OverflowOk
%17 = load i64, i64* %i, align 8
%18 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%19 = load i64, i64* %18, align 8
%20 = icmp ule i64 %17, %19
br i1 %20, label %BoundsCheckOk, label %BoundsCheckFail
Then: ; preds = %BoundsCheckOk17
br label %WhileEnd
Else: ; preds = %BoundsCheckOk17
br label %EndIf
EndIf: ; preds = %Else
%21 = load i64, i64* %len, align 8
%22 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %21, i64 8)
%23 = extractvalue { i64, i1 } %22, 0
%24 = extractvalue { i64, i1 } %22, 1
br i1 %24, label %OverflowFail18, label %OverflowOk19
WhileEnd: ; preds = %Then, %OverflowOk
%25 = load i64, i64* %i, align 8
%26 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%27 = load i64, i64* %26, align 8
%28 = icmp ult i64 %25, %27
br i1 %28, label %Then3, label %Else9
Then3: ; preds = %WhileEnd
%29 = load i64, i64* %i, align 8
%30 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%31 = load i64, i64* %30, align 8
%32 = icmp ult i64 %29, %31
br i1 %32, label %BoundsCheckOk23, label %BoundsCheckFail22
ErrRetReturn: ; preds = %BoundsCheckOk23
%33 = getelementptr inbounds { i3, i16 }, { i3, i16 }* %4, i32 0, i32 1
%34 = load i16, i16* %33, align 2
%35 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %0, i32 0, i32 1
store i16 %34, i16* %35, align 2
%36 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %5, i32 0, i32 1
store i16 %34, i16* %36, align 2
ret void
ErrRetContinue: ; preds = %BoundsCheckOk23
%37 = getelementptr inbounds { i3, i16 }, { i3, i16 }* %4, i32 0, i32 0
%38 = load i3, i3* %37, align 1
store i3 %38, i3* %n, align 1
%39 = load i64, i64* %i, align 8
%40 = load i3, i3* %n, align 1
%41 = zext i3 %40 to i64
%42 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %39, i64 %41)
%43 = extractvalue { i64, i1 } %42, 0
%44 = extractvalue { i64, i1 } %42, 1
br i1 %44, label %OverflowFail24, label %OverflowOk25
Then4: ; preds = %OverflowOk25
%45 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %0, i32 0, i32 1
store i16 13, i16* %45, align 2
ret void
Else5: ; preds = %OverflowOk25
br label %EndIf6
EndIf6: ; preds = %Else5
%46 = load i3, i3* %n, align 1
switch i3 %46, label %SwitchElse [
i3 1, label %SwitchProng
]
SwitchElse: ; preds = %EndIf6
%47 = load i64, i64* %i, align 8
%48 = load i64, i64* %i, align 8
%49 = load i3, i3* %n, align 1
%50 = zext i3 %49 to i64
%51 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %48, i64 %50)
%52 = extractvalue { i64, i1 } %51, 0
%53 = extractvalue { i64, i1 } %51, 1
br i1 %53, label %OverflowFail26, label %OverflowOk27
ErrRetReturn7: ; preds = %BoundsCheckOk31
%54 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %7, i32 0, i32 1
%55 = load i16, i16* %54, align 2
%56 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %0, i32 0, i32 1
store i16 %55, i16* %56, align 2
%57 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %8, i32 0, i32 1
store i16 %55, i16* %57, align 2
ret void
ErrRetContinue8: ; preds = %BoundsCheckOk31
%58 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %7, i32 0, i32 0
br label %SwitchEnd
SwitchProng: ; preds = %EndIf6
br label %SwitchEnd
SwitchEnd: ; preds = %SwitchProng, %ErrRetContinue8
%59 = load i64, i64* %i, align 8
%60 = load i3, i3* %n, align 1
%61 = zext i3 %60 to i64
%62 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %59, i64 %61)
%63 = extractvalue { i64, i1 } %62, 0
%64 = extractvalue { i64, i1 } %62, 1
br i1 %64, label %OverflowFail32, label %OverflowOk33
Else9: ; preds = %WhileEnd
br label %EndIf10
EndIf10: ; preds = %Else9, %OverflowOk35
br label %WhileCond
WhileEnd11: ; preds = %WhileCond
%65 = load i64, i64* %len, align 8
%66 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %0, i32 0, i32 1
store i16 0, i16* %66, align 2
%67 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %0, i32 0, i32 0
store i64 %65, i64* %67, align 8
ret void
OverflowFail: ; preds = %WhileCond1
call fastcc void @panic(%"[]u8"* @32, %std.builtin.StackTrace* null)
unreachable
OverflowOk: ; preds = %WhileCond1
%68 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%69 = load i64, i64* %68, align 8
%70 = icmp ule i64 %15, %69
br i1 %70, label %WhileBody2, label %WhileEnd
BoundsCheckFail: ; preds = %WhileBody2
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk: ; preds = %WhileBody2
%71 = icmp ule i64 %19, %19
br i1 %71, label %BoundsCheckOk13, label %BoundsCheckFail12
BoundsCheckFail12: ; preds = %BoundsCheckOk
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk13: ; preds = %BoundsCheckOk
%72 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%73 = load i8*, i8** %72, align 8
%74 = getelementptr inbounds i8, i8* %73, i64 %17
%75 = sub nuw i64 %19, %17
%76 = getelementptr inbounds %"[]u8", %"[]u8"* %2, i32 0, i32 0
store i8* %74, i8** %76, align 8
%77 = getelementptr inbounds %"[]u8", %"[]u8"* %2, i32 0, i32 1
store i64 %75, i64* %77, align 8
%78 = getelementptr inbounds %"[]u8", %"[]u8"* %2, i32 0, i32 1
%79 = load i64, i64* %78, align 8
br i1 true, label %BoundsCheckOk15, label %BoundsCheckFail14
BoundsCheckFail14: ; preds = %BoundsCheckOk13
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk15: ; preds = %BoundsCheckOk13
%80 = icmp ule i64 8, %79
br i1 %80, label %BoundsCheckOk17, label %BoundsCheckFail16
BoundsCheckFail16: ; preds = %BoundsCheckOk15
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk17: ; preds = %BoundsCheckOk15
%81 = getelementptr inbounds %"[]u8", %"[]u8"* %2, i32 0, i32 0
%82 = load i8*, i8** %81, align 8
%83 = getelementptr inbounds i8, i8* %82, i64 0
%84 = bitcast i8* %83 to [8 x i8]*
store [8 x i8]* %84, [8 x i8]** %3, align 8
%85 = call fastcc i64 @std.mem.readIntNative([8 x i8]* %84)
store i64 %85, i64* %v, align 8
%86 = load i64, i64* %v, align 8
%87 = and i64 %86, -9187201950435737472
%88 = icmp ne i64 %87, 0
br i1 %88, label %Then, label %Else
OverflowFail18: ; preds = %EndIf
call fastcc void @panic(%"[]u8"* @32, %std.builtin.StackTrace* null)
unreachable
OverflowOk19: ; preds = %EndIf
store i64 %23, i64* %len, align 8
%89 = load i64, i64* %i, align 8
%90 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %89, i64 8)
%91 = extractvalue { i64, i1 } %90, 0
%92 = extractvalue { i64, i1 } %90, 1
br i1 %92, label %OverflowFail20, label %OverflowOk21
OverflowFail20: ; preds = %OverflowOk19
call fastcc void @panic(%"[]u8"* @32, %std.builtin.StackTrace* null)
unreachable
OverflowOk21: ; preds = %OverflowOk19
store i64 %91, i64* %i, align 8
br label %WhileCond1
BoundsCheckFail22: ; preds = %Then3
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk23: ; preds = %Then3
%93 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%94 = load i8*, i8** %93, align 8
%95 = getelementptr inbounds i8, i8* %94, i64 %29
%96 = load i8, i8* %95, align 1
call fastcc void @std.unicode.utf8ByteSequenceLength({ i3, i16 }* sret %4, i8 %96)
%97 = getelementptr inbounds { i3, i16 }, { i3, i16 }* %4, i32 0, i32 1
%98 = load i16, i16* %97, align 2
%99 = icmp ne i16 %98, 0
br i1 %99, label %ErrRetReturn, label %ErrRetContinue
OverflowFail24: ; preds = %ErrRetContinue
call fastcc void @panic(%"[]u8"* @32, %std.builtin.StackTrace* null)
unreachable
OverflowOk25: ; preds = %ErrRetContinue
%100 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%101 = load i64, i64* %100, align 8
%102 = icmp ugt i64 %43, %101
br i1 %102, label %Then4, label %Else5
OverflowFail26: ; preds = %SwitchElse
call fastcc void @panic(%"[]u8"* @32, %std.builtin.StackTrace* null)
unreachable
OverflowOk27: ; preds = %SwitchElse
%103 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%104 = load i64, i64* %103, align 8
%105 = icmp ule i64 %47, %52
br i1 %105, label %BoundsCheckOk29, label %BoundsCheckFail28
BoundsCheckFail28: ; preds = %OverflowOk27
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk29: ; preds = %OverflowOk27
%106 = icmp ule i64 %52, %104
br i1 %106, label %BoundsCheckOk31, label %BoundsCheckFail30
BoundsCheckFail30: ; preds = %BoundsCheckOk29
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk31: ; preds = %BoundsCheckOk29
%107 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%108 = load i8*, i8** %107, align 8
%109 = getelementptr inbounds i8, i8* %108, i64 %47
%110 = sub nuw i64 %52, %47
%111 = getelementptr inbounds %"[]u8", %"[]u8"* %6, i32 0, i32 0
store i8* %109, i8** %111, align 8
%112 = getelementptr inbounds %"[]u8", %"[]u8"* %6, i32 0, i32 1
store i64 %110, i64* %112, align 8
call fastcc void @std.unicode.utf8Decode({ i21, i16 }* sret %7, %"[]u8"* %6)
%113 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %7, i32 0, i32 1
%114 = load i16, i16* %113, align 2
%115 = icmp ne i16 %114, 0
br i1 %115, label %ErrRetReturn7, label %ErrRetContinue8
OverflowFail32: ; preds = %SwitchEnd
call fastcc void @panic(%"[]u8"* @32, %std.builtin.StackTrace* null)
unreachable
OverflowOk33: ; preds = %SwitchEnd
store i64 %63, i64* %i, align 8
%116 = load i64, i64* %len, align 8
%117 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %116, i64 1)
%118 = extractvalue { i64, i1 } %117, 0
%119 = extractvalue { i64, i1 } %117, 1
br i1 %119, label %OverflowFail34, label %OverflowOk35
OverflowFail34: ; preds = %OverflowOk33
call fastcc void @panic(%"[]u8"* @32, %std.builtin.StackTrace* null)
unreachable
OverflowOk35: ; preds = %OverflowOk33
store i64 %118, i64* %len, align 8
br label %EndIf10
}
; Function Attrs: nounwind readnone speculatable willreturn
declare { i64, i1 } @llvm.usub.with.overflow.i64(i64, i64) #4
; Function Attrs: nobuiltin nounwind
define internal fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeAll"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* nonnull readonly align 4 %0, %"[]u8"* nonnull readonly align 8 %1) unnamed_addr #1 {
Entry:
%result = alloca i16, align 2
%index = alloca i64, align 8
%2 = alloca %"[]u8", align 8
%3 = alloca { i64, i16 }, align 8
store i64 0, i64* %index, align 8
br label %WhileCond
WhileCond: ; preds = %OverflowOk, %Entry
%4 = load i64, i64* %index, align 8
%5 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%6 = load i64, i64* %5, align 8
%7 = icmp ne i64 %4, %6
br i1 %7, label %WhileBody, label %WhileEnd
WhileBody: ; preds = %WhileCond
%8 = load i64, i64* %index, align 8
%9 = load i64, i64* %index, align 8
%10 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%11 = load i64, i64* %10, align 8
%12 = icmp ule i64 %9, %11
br i1 %12, label %BoundsCheckOk, label %BoundsCheckFail
ErrRetReturn: ; preds = %BoundsCheckOk2
%13 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %3, i32 0, i32 1
%14 = load i16, i16* %13, align 2
store i16 %14, i16* %result, align 2
ret i16 %14
ErrRetContinue: ; preds = %BoundsCheckOk2
%15 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %3, i32 0, i32 0
%16 = load i64, i64* %15, align 8
%17 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %8, i64 %16)
%18 = extractvalue { i64, i1 } %17, 0
%19 = extractvalue { i64, i1 } %17, 1
br i1 %19, label %OverflowFail, label %OverflowOk
WhileEnd: ; preds = %WhileCond
store i16 0, i16* %result, align 2
ret i16 0
BoundsCheckFail: ; preds = %WhileBody
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk: ; preds = %WhileBody
%20 = icmp ule i64 %11, %11
br i1 %20, label %BoundsCheckOk2, label %BoundsCheckFail1
BoundsCheckFail1: ; preds = %BoundsCheckOk
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk2: ; preds = %BoundsCheckOk
%21 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%22 = load i8*, i8** %21, align 8
%23 = getelementptr inbounds i8, i8* %22, i64 %9
%24 = sub nuw i64 %11, %9
%25 = getelementptr inbounds %"[]u8", %"[]u8"* %2, i32 0, i32 0
store i8* %23, i8** %25, align 8
%26 = getelementptr inbounds %"[]u8", %"[]u8"* %2, i32 0, i32 1
store i64 %24, i64* %26, align 8
call fastcc void @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).write"({ i64, i16 }* sret %3, %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %0, %"[]u8"* %2)
%27 = getelementptr inbounds { i64, i16 }, { i64, i16 }* %3, i32 0, i32 1
%28 = load i16, i16* %27, align 2
%29 = icmp ne i16 %28, 0
br i1 %29, label %ErrRetReturn, label %ErrRetContinue
OverflowFail: ; preds = %ErrRetContinue
call fastcc void @panic(%"[]u8"* @32, %std.builtin.StackTrace* null)
unreachable
OverflowOk: ; preds = %ErrRetContinue
store i64 %18, i64* %index, align 8
br label %WhileCond
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeByteNTimes"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* nonnull readonly align 4 %0, i8 %1, i64 %2) unnamed_addr #1 {
Entry:
%3 = alloca [6 x i64], align 8
%result = alloca i16, align 2
%bytes = alloca [256 x i8], align 1
%4 = alloca [256 x i8]*, align 8
%5 = alloca i8, align 1
%6 = alloca %"[]u8", align 8
%remaining = alloca i64, align 8
%7 = alloca i64, align 8
%to_write = alloca i64, align 8
%8 = alloca %"[]u8", align 8
%9 = alloca i16, align 2
%byte = alloca i8, align 1
%n = alloca i64, align 8
store i8 %1, i8* %byte, align 1
store i64 %2, i64* %n, align 8
%10 = bitcast [256 x i8]* %bytes to i8*
call void @llvm.memset.p0i8.i64(i8* align 1 %10, i8 -86, i64 256, i1 false)
%11 = ptrtoint i8* %10 to i64
%12 = getelementptr inbounds [6 x i64], [6 x i64]* %3, i64 0, i64 0
store i64 1296236545, i64* %12, align 8
%13 = getelementptr inbounds [6 x i64], [6 x i64]* %3, i64 0, i64 1
store i64 %11, i64* %13, align 8
%14 = getelementptr inbounds [6 x i64], [6 x i64]* %3, i64 0, i64 2
store i64 256, i64* %14, align 8
%15 = getelementptr inbounds [6 x i64], [6 x i64]* %3, i64 0, i64 3
store i64 0, i64* %15, align 8
%16 = getelementptr inbounds [6 x i64], [6 x i64]* %3, i64 0, i64 4
store i64 0, i64* %16, align 8
%17 = getelementptr inbounds [6 x i64], [6 x i64]* %3, i64 0, i64 5
store i64 0, i64* %17, align 8
%18 = ptrtoint [6 x i64]* %3 to i64
%19 = call i64 asm sideeffect "rolq $$3, %rdi ; rolq $$13, %rdi\0Arolq $$61, %rdi ; rolq $$51, %rdi\0Axchgq %rbx,%rbx\0A", "={rdx},{rax},0,~{cc},~{memory}"(i64 %18, i64 0)
br i1 true, label %BoundsCheckOk, label %BoundsCheckFail
WhileCond: ; preds = %OverflowOk, %BoundsCheckOk
%20 = load i64, i64* %remaining, align 8
%21 = icmp ugt i64 %20, 0
br i1 %21, label %WhileBody, label %WhileEnd
WhileBody: ; preds = %WhileCond
%22 = load i64, i64* %remaining, align 8
store i64 %22, i64* %7, align 8
%23 = call fastcc i64 @std.math.min.6(i64 %22, i64 256)
store i64 %23, i64* %to_write, align 8
%24 = load i64, i64* %to_write, align 8
%25 = icmp ule i64 0, %24
br i1 %25, label %BoundsCheckOk2, label %BoundsCheckFail1
ErrRetReturn: ; preds = %BoundsCheckOk4
%26 = load i16, i16* %9, align 2
store i16 %26, i16* %result, align 2
ret i16 %26
ErrRetContinue: ; preds = %BoundsCheckOk4
%27 = load i64, i64* %remaining, align 8
%28 = load i64, i64* %to_write, align 8
%29 = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %27, i64 %28)
%30 = extractvalue { i64, i1 } %29, 0
%31 = extractvalue { i64, i1 } %29, 1
br i1 %31, label %OverflowFail, label %OverflowOk
WhileEnd: ; preds = %WhileCond
store i16 0, i16* %result, align 2
ret i16 0
BoundsCheckFail: ; preds = %Entry
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk: ; preds = %Entry
%32 = getelementptr inbounds [256 x i8], [256 x i8]* %bytes, i64 0, i64 0
%33 = bitcast i8* %32 to [256 x i8]*
store [256 x i8]* %33, [256 x i8]** %4, align 8
%34 = load i8, i8* %byte, align 1
store i8 %34, i8* %5, align 1
%35 = getelementptr inbounds %"[]u8", %"[]u8"* %6, i32 0, i32 0
%36 = getelementptr inbounds [256 x i8], [256 x i8]* %33, i64 0, i64 0
store i8* %36, i8** %35, align 8
%37 = getelementptr inbounds %"[]u8", %"[]u8"* %6, i32 0, i32 1
store i64 256, i64* %37, align 8
call fastcc void @std.mem.set(%"[]u8"* %6, i8 %34)
%38 = load i64, i64* %n, align 8
store i64 %38, i64* %remaining, align 8
br label %WhileCond
BoundsCheckFail1: ; preds = %WhileBody
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk2: ; preds = %WhileBody
%39 = icmp ule i64 %24, 256
br i1 %39, label %BoundsCheckOk4, label %BoundsCheckFail3
BoundsCheckFail3: ; preds = %BoundsCheckOk2
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk4: ; preds = %BoundsCheckOk2
%40 = getelementptr inbounds [256 x i8], [256 x i8]* %bytes, i64 0, i64 0
%41 = sub nuw i64 %24, 0
%42 = getelementptr inbounds %"[]u8", %"[]u8"* %8, i32 0, i32 0
store i8* %40, i8** %42, align 8
%43 = getelementptr inbounds %"[]u8", %"[]u8"* %8, i32 0, i32 1
store i64 %41, i64* %43, align 8
%44 = call fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeAll"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %0, %"[]u8"* %8)
store i16 %44, i16* %9, align 2
%45 = icmp ne i16 %44, 0
br i1 %45, label %ErrRetReturn, label %ErrRetContinue
OverflowFail: ; preds = %ErrRetContinue
call fastcc void @panic(%"[]u8"* @32, %std.builtin.StackTrace* null)
unreachable
OverflowOk: ; preds = %ErrRetContinue
store i64 %30, i64* %remaining, align 8
br label %WhileCond
}
; Function Attrs: nounwind readnone speculatable willreturn
declare { i64, i1 } @llvm.uadd.with.overflow.i64(i64, i64) #4
; Function Attrs: nobuiltin nounwind
define internal fastcc i64 @std.mem.readIntNative([8 x i8]* nonnull readonly align 1 %0) unnamed_addr #1 {
Entry:
%result = alloca i64, align 8
%bytes = alloca [8 x i8]*, align 8
store [8 x i8]* %0, [8 x i8]** %bytes, align 8
%1 = load [8 x i8]*, [8 x i8]** %bytes, align 8
%2 = bitcast [8 x i8]* %1 to i64*
%3 = icmp ne i64* %2, null
br i1 %3, label %PtrCastOk, label %PtrCastFail
PtrCastFail: ; preds = %Entry
call fastcc void @panic(%"[]u8"* @37, %std.builtin.StackTrace* null)
unreachable
PtrCastOk: ; preds = %Entry
%4 = load i64, i64* %2, align 1
store i64 %4, i64* %result, align 8
%5 = load i64, i64* %result, align 8
ret i64 %5
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.unicode.utf8ByteSequenceLength({ i3, i16 }* nonnull sret %0, i8 %1) unnamed_addr #1 {
Entry:
%first_byte = alloca i8, align 1
store i8 %1, i8* %first_byte, align 1
%2 = load i8, i8* %first_byte, align 1
%3 = icmp ule i8 %2, 127
%4 = and i1 true, %3
br i1 %4, label %SwitchRangeYes, label %SwitchRangeNo
SwitchRangeYes: ; preds = %Entry
%5 = getelementptr inbounds { i3, i16 }, { i3, i16 }* %0, i32 0, i32 1
store i16 0, i16* %5, align 2
%6 = getelementptr inbounds { i3, i16 }, { i3, i16 }* %0, i32 0, i32 0
store i3 1, i3* %6, align 1
br label %SwitchEnd
SwitchRangeNo: ; preds = %Entry
%7 = icmp uge i8 %2, -64
%8 = icmp ule i8 %2, -33
%9 = and i1 %7, %8
br i1 %9, label %SwitchRangeYes1, label %SwitchRangeNo2
SwitchRangeYes1: ; preds = %SwitchRangeNo
%10 = getelementptr inbounds { i3, i16 }, { i3, i16 }* %0, i32 0, i32 1
store i16 0, i16* %10, align 2
%11 = getelementptr inbounds { i3, i16 }, { i3, i16 }* %0, i32 0, i32 0
store i3 2, i3* %11, align 1
br label %SwitchEnd
SwitchRangeNo2: ; preds = %SwitchRangeNo
%12 = icmp uge i8 %2, -32
%13 = icmp ule i8 %2, -17
%14 = and i1 %12, %13
br i1 %14, label %SwitchRangeYes3, label %SwitchRangeNo4
SwitchRangeYes3: ; preds = %SwitchRangeNo2
%15 = getelementptr inbounds { i3, i16 }, { i3, i16 }* %0, i32 0, i32 1
store i16 0, i16* %15, align 2
%16 = getelementptr inbounds { i3, i16 }, { i3, i16 }* %0, i32 0, i32 0
store i3 3, i3* %16, align 1
br label %SwitchEnd
SwitchRangeNo4: ; preds = %SwitchRangeNo2
%17 = icmp uge i8 %2, -16
%18 = icmp ule i8 %2, -9
%19 = and i1 %17, %18
br i1 %19, label %SwitchRangeYes5, label %SwitchRangeNo6
SwitchRangeYes5: ; preds = %SwitchRangeNo4
%20 = getelementptr inbounds { i3, i16 }, { i3, i16 }* %0, i32 0, i32 1
store i16 0, i16* %20, align 2
%21 = getelementptr inbounds { i3, i16 }, { i3, i16 }* %0, i32 0, i32 0
store i3 -4, i3* %21, align 1
br label %SwitchEnd
SwitchRangeNo6: ; preds = %SwitchRangeNo4
br label %SwitchElse
SwitchElse: ; preds = %SwitchRangeNo6
%22 = getelementptr inbounds { i3, i16 }, { i3, i16 }* %0, i32 0, i32 1
store i16 12, i16* %22, align 2
br label %SwitchEnd
SwitchEnd: ; preds = %SwitchElse, %SwitchRangeYes5, %SwitchRangeYes3, %SwitchRangeYes1, %SwitchRangeYes
ret void
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.unicode.utf8Decode({ i21, i16 }* nonnull sret %0, %"[]u8"* nonnull readonly align 8 %1) unnamed_addr #1 {
Entry:
%2 = alloca { i21, i16 }, align 4
%3 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%4 = load i64, i64* %3, align 8
switch i64 %4, label %SwitchElse [
i64 1, label %SwitchProng
i64 2, label %SwitchProng1
i64 3, label %SwitchProng2
i64 4, label %SwitchProng3
]
SwitchElse: ; preds = %Entry
call fastcc void @panic(%"[]u8"* @17, %std.builtin.StackTrace* null)
unreachable
SwitchProng: ; preds = %Entry
%5 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%6 = load i64, i64* %5, align 8
%7 = icmp ult i64 0, %6
br i1 %7, label %BoundsCheckOk, label %BoundsCheckFail
SwitchProng1: ; preds = %Entry
call fastcc void @std.unicode.utf8Decode2({ i21, i16 }* sret %0, %"[]u8"* %1)
%8 = bitcast { i21, i16 }* %0 to i8*
%9 = bitcast { i21, i16 }* %0 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %9, i8* align 4 %8, i64 8, i1 false)
br label %SwitchEnd
SwitchProng2: ; preds = %Entry
call fastcc void @std.unicode.utf8Decode3({ i21, i16 }* sret %0, %"[]u8"* %1)
%10 = bitcast { i21, i16 }* %0 to i8*
%11 = bitcast { i21, i16 }* %0 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %11, i8* align 4 %10, i64 8, i1 false)
br label %SwitchEnd
SwitchProng3: ; preds = %Entry
call fastcc void @std.unicode.utf8Decode4({ i21, i16 }* sret %0, %"[]u8"* %1)
%12 = bitcast { i21, i16 }* %0 to i8*
%13 = bitcast { i21, i16 }* %0 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %13, i8* align 4 %12, i64 8, i1 false)
br label %SwitchEnd
SwitchEnd: ; preds = %SwitchProng3, %SwitchProng2, %SwitchProng1, %BoundsCheckOk
ret void
BoundsCheckFail: ; preds = %SwitchProng
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk: ; preds = %SwitchProng
%14 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%15 = load i8*, i8** %14, align 8
%16 = getelementptr inbounds i8, i8* %15, i64 0
%17 = load i8, i8* %16, align 1
%18 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %0, i32 0, i32 1
store i16 0, i16* %18, align 2
%19 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %0, i32 0, i32 0
%20 = zext i8 %17 to i21
store i21 %20, i21* %19, align 4
%21 = zext i8 %17 to i21
store i21 %21, i21* %19, align 4
%22 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %2, i32 0, i32 1
store i16 0, i16* %22, align 2
%23 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %2, i32 0, i32 0
store i21 %21, i21* %23, align 4
br label %SwitchEnd
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.unicode.utf8Decode2({ i21, i16 }* nonnull sret %0, %"[]u8"* nonnull readonly align 8 %1) unnamed_addr #1 {
Entry:
%value = alloca i21, align 4
%2 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%3 = load i64, i64* %2, align 8
%4 = icmp eq i64 %3, 2
call fastcc void @std.debug.assert(i1 %4)
%5 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%6 = load i64, i64* %5, align 8
%7 = icmp ult i64 0, %6
br i1 %7, label %BoundsCheckOk, label %BoundsCheckFail
Then: ; preds = %BoundsCheckOk7
%8 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %0, i32 0, i32 1
store i16 14, i16* %8, align 2
ret void
Else: ; preds = %BoundsCheckOk7
br label %EndIf
EndIf: ; preds = %Else
%9 = load i21, i21* %value, align 4
br i1 true, label %CheckOk, label %CheckFail
Then1: ; preds = %BoundsCheckOk9
%10 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %0, i32 0, i32 1
store i16 15, i16* %10, align 2
ret void
Else2: ; preds = %BoundsCheckOk9
br label %EndIf3
EndIf3: ; preds = %Else2
%11 = load i21, i21* %value, align 4
%12 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %0, i32 0, i32 1
store i16 0, i16* %12, align 2
%13 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %0, i32 0, i32 0
store i21 %11, i21* %13, align 4
ret void
BoundsCheckFail: ; preds = %Entry
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk: ; preds = %Entry
%14 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%15 = load i8*, i8** %14, align 8
%16 = getelementptr inbounds i8, i8* %15, i64 0
%17 = load i8, i8* %16, align 1
%18 = and i8 %17, -32
%19 = icmp eq i8 %18, -64
call fastcc void @std.debug.assert(i1 %19)
%20 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%21 = load i64, i64* %20, align 8
%22 = icmp ult i64 0, %21
br i1 %22, label %BoundsCheckOk5, label %BoundsCheckFail4
BoundsCheckFail4: ; preds = %BoundsCheckOk
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk5: ; preds = %BoundsCheckOk
%23 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%24 = load i8*, i8** %23, align 8
%25 = getelementptr inbounds i8, i8* %24, i64 0
%26 = load i8, i8* %25, align 1
%27 = and i8 %26, 31
%28 = zext i8 %27 to i21
store i21 %28, i21* %value, align 4
%29 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%30 = load i64, i64* %29, align 8
%31 = icmp ult i64 1, %30
br i1 %31, label %BoundsCheckOk7, label %BoundsCheckFail6
BoundsCheckFail6: ; preds = %BoundsCheckOk5
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk7: ; preds = %BoundsCheckOk5
%32 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%33 = load i8*, i8** %32, align 8
%34 = getelementptr inbounds i8, i8* %33, i64 1
%35 = load i8, i8* %34, align 1
%36 = and i8 %35, -64
%37 = icmp ne i8 %36, -128
br i1 %37, label %Then, label %Else
CheckFail: ; preds = %EndIf
call fastcc void @panic(%"[]u8"* @39, %std.builtin.StackTrace* null)
unreachable
CheckOk: ; preds = %EndIf
%38 = shl i21 %9, 6
store i21 %38, i21* %value, align 4
%39 = load i21, i21* %value, align 4
%40 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%41 = load i64, i64* %40, align 8
%42 = icmp ult i64 1, %41
br i1 %42, label %BoundsCheckOk9, label %BoundsCheckFail8
BoundsCheckFail8: ; preds = %CheckOk
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk9: ; preds = %CheckOk
%43 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%44 = load i8*, i8** %43, align 8
%45 = getelementptr inbounds i8, i8* %44, i64 1
%46 = load i8, i8* %45, align 1
%47 = and i8 %46, 63
%48 = zext i8 %47 to i21
%49 = or i21 %39, %48
store i21 %49, i21* %value, align 4
%50 = load i21, i21* %value, align 4
%51 = icmp ult i21 %50, 128
br i1 %51, label %Then1, label %Else2
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.unicode.utf8Decode3({ i21, i16 }* nonnull sret %0, %"[]u8"* nonnull readonly align 8 %1) unnamed_addr #1 {
Entry:
%value = alloca i21, align 4
%2 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%3 = load i64, i64* %2, align 8
%4 = icmp eq i64 %3, 3
call fastcc void @std.debug.assert(i1 %4)
%5 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%6 = load i64, i64* %5, align 8
%7 = icmp ult i64 0, %6
br i1 %7, label %BoundsCheckOk, label %BoundsCheckFail
Then: ; preds = %BoundsCheckOk13
%8 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %0, i32 0, i32 1
store i16 14, i16* %8, align 2
ret void
Else: ; preds = %BoundsCheckOk13
br label %EndIf
EndIf: ; preds = %Else
%9 = load i21, i21* %value, align 4
br i1 true, label %CheckOk, label %CheckFail
Then1: ; preds = %BoundsCheckOk17
%10 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %0, i32 0, i32 1
store i16 14, i16* %10, align 2
ret void
Else2: ; preds = %BoundsCheckOk17
br label %EndIf3
EndIf3: ; preds = %Else2
%11 = load i21, i21* %value, align 4
br i1 true, label %CheckOk19, label %CheckFail18
Then4: ; preds = %BoundsCheckOk21
%12 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %0, i32 0, i32 1
store i16 15, i16* %12, align 2
ret void
Else5: ; preds = %BoundsCheckOk21
br label %EndIf6
EndIf6: ; preds = %Else5
%13 = load i21, i21* %value, align 4
%14 = icmp ule i21 55296, %13
br i1 %14, label %BoolAndTrue, label %BoolAndFalse
BoolAndTrue: ; preds = %EndIf6
%15 = load i21, i21* %value, align 4
%16 = icmp ule i21 %15, 57343
br label %BoolAndFalse
BoolAndFalse: ; preds = %BoolAndTrue, %EndIf6
%17 = phi i1 [ %14, %EndIf6 ], [ %16, %BoolAndTrue ]
br i1 %17, label %Then7, label %Else8
Then7: ; preds = %BoolAndFalse
%18 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %0, i32 0, i32 1
store i16 16, i16* %18, align 2
ret void
Else8: ; preds = %BoolAndFalse
br label %EndIf9
EndIf9: ; preds = %Else8
%19 = load i21, i21* %value, align 4
%20 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %0, i32 0, i32 1
store i16 0, i16* %20, align 2
%21 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %0, i32 0, i32 0
store i21 %19, i21* %21, align 4
ret void
BoundsCheckFail: ; preds = %Entry
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk: ; preds = %Entry
%22 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%23 = load i8*, i8** %22, align 8
%24 = getelementptr inbounds i8, i8* %23, i64 0
%25 = load i8, i8* %24, align 1
%26 = and i8 %25, -16
%27 = icmp eq i8 %26, -32
call fastcc void @std.debug.assert(i1 %27)
%28 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%29 = load i64, i64* %28, align 8
%30 = icmp ult i64 0, %29
br i1 %30, label %BoundsCheckOk11, label %BoundsCheckFail10
BoundsCheckFail10: ; preds = %BoundsCheckOk
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk11: ; preds = %BoundsCheckOk
%31 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%32 = load i8*, i8** %31, align 8
%33 = getelementptr inbounds i8, i8* %32, i64 0
%34 = load i8, i8* %33, align 1
%35 = and i8 %34, 15
%36 = zext i8 %35 to i21
store i21 %36, i21* %value, align 4
%37 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%38 = load i64, i64* %37, align 8
%39 = icmp ult i64 1, %38
br i1 %39, label %BoundsCheckOk13, label %BoundsCheckFail12
BoundsCheckFail12: ; preds = %BoundsCheckOk11
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk13: ; preds = %BoundsCheckOk11
%40 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%41 = load i8*, i8** %40, align 8
%42 = getelementptr inbounds i8, i8* %41, i64 1
%43 = load i8, i8* %42, align 1
%44 = and i8 %43, -64
%45 = icmp ne i8 %44, -128
br i1 %45, label %Then, label %Else
CheckFail: ; preds = %EndIf
call fastcc void @panic(%"[]u8"* @39, %std.builtin.StackTrace* null)
unreachable
CheckOk: ; preds = %EndIf
%46 = shl i21 %9, 6
store i21 %46, i21* %value, align 4
%47 = load i21, i21* %value, align 4
%48 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%49 = load i64, i64* %48, align 8
%50 = icmp ult i64 1, %49
br i1 %50, label %BoundsCheckOk15, label %BoundsCheckFail14
BoundsCheckFail14: ; preds = %CheckOk
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk15: ; preds = %CheckOk
%51 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%52 = load i8*, i8** %51, align 8
%53 = getelementptr inbounds i8, i8* %52, i64 1
%54 = load i8, i8* %53, align 1
%55 = and i8 %54, 63
%56 = zext i8 %55 to i21
%57 = or i21 %47, %56
store i21 %57, i21* %value, align 4
%58 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%59 = load i64, i64* %58, align 8
%60 = icmp ult i64 2, %59
br i1 %60, label %BoundsCheckOk17, label %BoundsCheckFail16
BoundsCheckFail16: ; preds = %BoundsCheckOk15
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk17: ; preds = %BoundsCheckOk15
%61 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%62 = load i8*, i8** %61, align 8
%63 = getelementptr inbounds i8, i8* %62, i64 2
%64 = load i8, i8* %63, align 1
%65 = and i8 %64, -64
%66 = icmp ne i8 %65, -128
br i1 %66, label %Then1, label %Else2
CheckFail18: ; preds = %EndIf3
call fastcc void @panic(%"[]u8"* @39, %std.builtin.StackTrace* null)
unreachable
CheckOk19: ; preds = %EndIf3
%67 = shl i21 %11, 6
store i21 %67, i21* %value, align 4
%68 = load i21, i21* %value, align 4
%69 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%70 = load i64, i64* %69, align 8
%71 = icmp ult i64 2, %70
br i1 %71, label %BoundsCheckOk21, label %BoundsCheckFail20
BoundsCheckFail20: ; preds = %CheckOk19
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk21: ; preds = %CheckOk19
%72 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%73 = load i8*, i8** %72, align 8
%74 = getelementptr inbounds i8, i8* %73, i64 2
%75 = load i8, i8* %74, align 1
%76 = and i8 %75, 63
%77 = zext i8 %76 to i21
%78 = or i21 %68, %77
store i21 %78, i21* %value, align 4
%79 = load i21, i21* %value, align 4
%80 = icmp ult i21 %79, 2048
br i1 %80, label %Then4, label %Else5
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.unicode.utf8Decode4({ i21, i16 }* nonnull sret %0, %"[]u8"* nonnull readonly align 8 %1) unnamed_addr #1 {
Entry:
%value = alloca i21, align 4
%2 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%3 = load i64, i64* %2, align 8
%4 = icmp eq i64 %3, 4
call fastcc void @std.debug.assert(i1 %4)
%5 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%6 = load i64, i64* %5, align 8
%7 = icmp ult i64 0, %6
br i1 %7, label %BoundsCheckOk, label %BoundsCheckFail
Then: ; preds = %BoundsCheckOk16
%8 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %0, i32 0, i32 1
store i16 14, i16* %8, align 2
ret void
Else: ; preds = %BoundsCheckOk16
br label %EndIf
EndIf: ; preds = %Else
%9 = load i21, i21* %value, align 4
br i1 true, label %CheckOk, label %CheckFail
Then1: ; preds = %BoundsCheckOk20
%10 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %0, i32 0, i32 1
store i16 14, i16* %10, align 2
ret void
Else2: ; preds = %BoundsCheckOk20
br label %EndIf3
EndIf3: ; preds = %Else2
%11 = load i21, i21* %value, align 4
br i1 true, label %CheckOk22, label %CheckFail21
Then4: ; preds = %BoundsCheckOk26
%12 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %0, i32 0, i32 1
store i16 14, i16* %12, align 2
ret void
Else5: ; preds = %BoundsCheckOk26
br label %EndIf6
EndIf6: ; preds = %Else5
%13 = load i21, i21* %value, align 4
br i1 true, label %CheckOk28, label %CheckFail27
Then7: ; preds = %BoundsCheckOk30
%14 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %0, i32 0, i32 1
store i16 15, i16* %14, align 2
ret void
Else8: ; preds = %BoundsCheckOk30
br label %EndIf9
EndIf9: ; preds = %Else8
%15 = load i21, i21* %value, align 4
%16 = icmp ugt i21 %15, -983041
br i1 %16, label %Then10, label %Else11
Then10: ; preds = %EndIf9
%17 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %0, i32 0, i32 1
store i16 17, i16* %17, align 2
ret void
Else11: ; preds = %EndIf9
br label %EndIf12
EndIf12: ; preds = %Else11
%18 = load i21, i21* %value, align 4
%19 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %0, i32 0, i32 1
store i16 0, i16* %19, align 2
%20 = getelementptr inbounds { i21, i16 }, { i21, i16 }* %0, i32 0, i32 0
store i21 %18, i21* %20, align 4
ret void
BoundsCheckFail: ; preds = %Entry
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk: ; preds = %Entry
%21 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%22 = load i8*, i8** %21, align 8
%23 = getelementptr inbounds i8, i8* %22, i64 0
%24 = load i8, i8* %23, align 1
%25 = and i8 %24, -8
%26 = icmp eq i8 %25, -16
call fastcc void @std.debug.assert(i1 %26)
%27 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%28 = load i64, i64* %27, align 8
%29 = icmp ult i64 0, %28
br i1 %29, label %BoundsCheckOk14, label %BoundsCheckFail13
BoundsCheckFail13: ; preds = %BoundsCheckOk
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk14: ; preds = %BoundsCheckOk
%30 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%31 = load i8*, i8** %30, align 8
%32 = getelementptr inbounds i8, i8* %31, i64 0
%33 = load i8, i8* %32, align 1
%34 = and i8 %33, 7
%35 = zext i8 %34 to i21
store i21 %35, i21* %value, align 4
%36 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%37 = load i64, i64* %36, align 8
%38 = icmp ult i64 1, %37
br i1 %38, label %BoundsCheckOk16, label %BoundsCheckFail15
BoundsCheckFail15: ; preds = %BoundsCheckOk14
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk16: ; preds = %BoundsCheckOk14
%39 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%40 = load i8*, i8** %39, align 8
%41 = getelementptr inbounds i8, i8* %40, i64 1
%42 = load i8, i8* %41, align 1
%43 = and i8 %42, -64
%44 = icmp ne i8 %43, -128
br i1 %44, label %Then, label %Else
CheckFail: ; preds = %EndIf
call fastcc void @panic(%"[]u8"* @39, %std.builtin.StackTrace* null)
unreachable
CheckOk: ; preds = %EndIf
%45 = shl i21 %9, 6
store i21 %45, i21* %value, align 4
%46 = load i21, i21* %value, align 4
%47 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%48 = load i64, i64* %47, align 8
%49 = icmp ult i64 1, %48
br i1 %49, label %BoundsCheckOk18, label %BoundsCheckFail17
BoundsCheckFail17: ; preds = %CheckOk
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk18: ; preds = %CheckOk
%50 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%51 = load i8*, i8** %50, align 8
%52 = getelementptr inbounds i8, i8* %51, i64 1
%53 = load i8, i8* %52, align 1
%54 = and i8 %53, 63
%55 = zext i8 %54 to i21
%56 = or i21 %46, %55
store i21 %56, i21* %value, align 4
%57 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%58 = load i64, i64* %57, align 8
%59 = icmp ult i64 2, %58
br i1 %59, label %BoundsCheckOk20, label %BoundsCheckFail19
BoundsCheckFail19: ; preds = %BoundsCheckOk18
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk20: ; preds = %BoundsCheckOk18
%60 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%61 = load i8*, i8** %60, align 8
%62 = getelementptr inbounds i8, i8* %61, i64 2
%63 = load i8, i8* %62, align 1
%64 = and i8 %63, -64
%65 = icmp ne i8 %64, -128
br i1 %65, label %Then1, label %Else2
CheckFail21: ; preds = %EndIf3
call fastcc void @panic(%"[]u8"* @39, %std.builtin.StackTrace* null)
unreachable
CheckOk22: ; preds = %EndIf3
%66 = shl i21 %11, 6
store i21 %66, i21* %value, align 4
%67 = load i21, i21* %value, align 4
%68 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%69 = load i64, i64* %68, align 8
%70 = icmp ult i64 2, %69
br i1 %70, label %BoundsCheckOk24, label %BoundsCheckFail23
BoundsCheckFail23: ; preds = %CheckOk22
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk24: ; preds = %CheckOk22
%71 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%72 = load i8*, i8** %71, align 8
%73 = getelementptr inbounds i8, i8* %72, i64 2
%74 = load i8, i8* %73, align 1
%75 = and i8 %74, 63
%76 = zext i8 %75 to i21
%77 = or i21 %67, %76
store i21 %77, i21* %value, align 4
%78 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%79 = load i64, i64* %78, align 8
%80 = icmp ult i64 3, %79
br i1 %80, label %BoundsCheckOk26, label %BoundsCheckFail25
BoundsCheckFail25: ; preds = %BoundsCheckOk24
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk26: ; preds = %BoundsCheckOk24
%81 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%82 = load i8*, i8** %81, align 8
%83 = getelementptr inbounds i8, i8* %82, i64 3
%84 = load i8, i8* %83, align 1
%85 = and i8 %84, -64
%86 = icmp ne i8 %85, -128
br i1 %86, label %Then4, label %Else5
CheckFail27: ; preds = %EndIf6
call fastcc void @panic(%"[]u8"* @39, %std.builtin.StackTrace* null)
unreachable
CheckOk28: ; preds = %EndIf6
%87 = shl i21 %13, 6
store i21 %87, i21* %value, align 4
%88 = load i21, i21* %value, align 4
%89 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%90 = load i64, i64* %89, align 8
%91 = icmp ult i64 3, %90
br i1 %91, label %BoundsCheckOk30, label %BoundsCheckFail29
BoundsCheckFail29: ; preds = %CheckOk28
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk30: ; preds = %CheckOk28
%92 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%93 = load i8*, i8** %92, align 8
%94 = getelementptr inbounds i8, i8* %93, i64 3
%95 = load i8, i8* %94, align 1
%96 = and i8 %95, 63
%97 = zext i8 %96 to i21
%98 = or i21 %88, %97
store i21 %98, i21* %value, align 4
%99 = load i21, i21* %value, align 4
%100 = icmp ult i21 %99, 65536
br i1 %100, label %Then7, label %Else8
}
; Function Attrs: nobuiltin nounwind
define internal fastcc void @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).write"({ i64, i16 }* nonnull sret %0, %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* nonnull readonly align 4 %1, %"[]u8"* nonnull readonly align 8 %2) unnamed_addr #1 {
Entry:
%3 = getelementptr inbounds %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)", %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %1, i32 0, i32 0
call fastcc void @std.fs.file.File.write({ i64, i16 }* sret %0, %std.fs.file.File* %3, %"[]u8"* %2)
ret void
}
; Function Attrs: argmemonly nounwind willreturn writeonly
declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) #5
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.mem.set(%"[]u8"* nonnull readonly align 8 %0, i8 %1) unnamed_addr #1 {
Entry:
%i = alloca i64, align 8
%d = alloca i8*, align 8
%value = alloca i8, align 1
store i8 %1, i8* %value, align 1
store i64 0, i64* %i, align 8
%2 = getelementptr inbounds %"[]u8", %"[]u8"* %0, i32 0, i32 1
%3 = load i64, i64* %2, align 8
br label %ForCond
ForCond: ; preds = %ForBody, %Entry
%4 = load i64, i64* %i, align 8
%5 = icmp ult i64 %4, %3
br i1 %5, label %ForBody, label %ForEnd
ForBody: ; preds = %ForCond
%6 = getelementptr inbounds %"[]u8", %"[]u8"* %0, i32 0, i32 0
%7 = load i8*, i8** %6, align 8
%8 = getelementptr inbounds i8, i8* %7, i64 %4
store i8* %8, i8** %d, align 8
%9 = load i8*, i8** %d, align 8
%10 = load i8, i8* %value, align 1
store i8 %10, i8* %9, align 1
%11 = add nuw i64 %4, 1
store i64 %11, i64* %i, align 8
br label %ForCond
ForEnd: ; preds = %ForCond
ret void
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i64 @std.math.min.6(i64 %0, i64 %1) unnamed_addr #1 {
Entry:
%result = alloca i64, align 8
%x = alloca i64, align 8
%y = alloca i64, align 8
store i64 %0, i64* %x, align 8
store i64 %1, i64* %y, align 8
%2 = load i64, i64* %x, align 8
%3 = load i64, i64* %y, align 8
%4 = icmp ult i64 %2, %3
br i1 %4, label %Then, label %Else
Then: ; preds = %Entry
%5 = load i64, i64* %x, align 8
store i64 %5, i64* %result, align 8
%6 = load i64, i64* %result, align 8
ret i64 %6
Else: ; preds = %Entry
%7 = load i64, i64* %y, align 8
store i64 %7, i64* %result, align 8
%8 = load i64, i64* %result, align 8
ret i64 %8
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print.7"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* nonnull readonly align 4 %0, %"std.os.struct:4571:51"* nonnull readonly align 8 %1) unnamed_addr #1 {
Entry:
%result = alloca i16, align 2
%2 = alloca %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)", align 4
%3 = alloca %"std.os.struct:4571:51", align 8
%4 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %0 to i8*
%5 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %5, i8* align 4 %4, i64 4, i1 false)
%6 = bitcast %"std.os.struct:4571:51"* %1 to i8*
%7 = bitcast %"std.os.struct:4571:51"* %3 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %7, i8* align 8 %6, i64 8, i1 false)
%8 = call fastcc i16 @std.fmt.format.9(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %0, %"std.os.struct:4571:51"* %1)
store i16 %8, i16* %result, align 2
%9 = load i16, i16* %result, align 2
ret i16 %9
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print.8"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* nonnull readonly align 4 %0) unnamed_addr #1 {
Entry:
%result = alloca i16, align 2
%1 = alloca %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)", align 4
%2 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %0 to i8*
%3 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %1 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %3, i8* align 4 %2, i64 4, i1 false)
%4 = call fastcc i16 @std.fmt.format.10(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %0)
store i16 %4, i16* %result, align 2
%5 = load i16, i16* %result, align 2
ret i16 %5
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i16 @std.fmt.format.9(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* nonnull readonly align 4 %0, %"std.os.struct:4571:51"* nonnull readonly align 8 %1) unnamed_addr #1 {
Entry:
%result = alloca i16, align 2
%options = alloca %std.fmt.FormatOptions, align 8
%2 = alloca i16, align 2
%3 = alloca i64, align 8
%4 = alloca %std.fmt.FormatOptions, align 8
%5 = alloca %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)", align 4
%6 = alloca i16, align 2
%7 = alloca i16, align 2
%8 = bitcast %std.fmt.FormatOptions* %options to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %8, i8* align 8 bitcast ({ %"?usize", %"?usize", i2, <{ i8, [6 x i8] }> }* @40 to i8*), i64 40, i1 false)
%9 = call fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeAll"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %0, %"[]u8"* @42)
store i16 %9, i16* %2, align 2
%10 = icmp ne i16 %9, 0
br i1 %10, label %ErrRetReturn, label %ErrRetContinue
ErrRetReturn: ; preds = %Entry
%11 = load i16, i16* %2, align 2
store i16 %11, i16* %result, align 2
ret i16 %11
ErrRetContinue: ; preds = %Entry
%12 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %options, i32 0, i32 0
%13 = bitcast %"?usize"* %12 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %13, i8* align 8 bitcast (%"?usize"* @43 to i8*), i64 16, i1 false)
%14 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %options, i32 0, i32 1
%15 = bitcast %"?usize"* %14 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %15, i8* align 8 bitcast (%"?usize"* @44 to i8*), i64 16, i1 false)
%16 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %options, i32 0, i32 2
store i2 -2, i2* %16, align 1
%17 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %options, i32 0, i32 3
store i8 32, i8* %17, align 1
%18 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %options, i32 0, i32 1
%19 = bitcast %"?usize"* %18 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %19, i8* align 8 bitcast (%"?usize"* @45 to i8*), i64 16, i1 false)
br label %BlockEnd
BlockEnd: ; preds = %ErrRetContinue
%20 = getelementptr inbounds %std.fmt.FormatOptions, %std.fmt.FormatOptions* %options, i32 0, i32 0
%21 = bitcast %"?usize"* %20 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %21, i8* align 8 bitcast (%"?usize"* @46 to i8*), i64 16, i1 false)
br label %BlockEnd1
BlockEnd1: ; preds = %BlockEnd
%22 = getelementptr inbounds %"std.os.struct:4571:51", %"std.os.struct:4571:51"* %1, i32 0, i32 0
%23 = load i64, i64* %22, align 8
store i64 %23, i64* %3, align 8
%24 = bitcast %std.fmt.FormatOptions* %options to i8*
%25 = bitcast %std.fmt.FormatOptions* %4 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %25, i8* align 8 %24, i64 40, i1 false)
%26 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %0 to i8*
%27 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %5 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %27, i8* align 4 %26, i64 4, i1 false)
%28 = call fastcc i16 @std.fmt.formatType.11(i64 %23, %std.fmt.FormatOptions* %options, %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %0, i64 3)
store i16 %28, i16* %6, align 2
%29 = icmp ne i16 %28, 0
br i1 %29, label %ErrRetReturn2, label %ErrRetContinue3
ErrRetReturn2: ; preds = %BlockEnd1
%30 = load i16, i16* %6, align 2
store i16 %30, i16* %result, align 2
ret i16 %30
ErrRetContinue3: ; preds = %BlockEnd1
%31 = call fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeAll"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %0, %"[]u8"* @47)
store i16 %31, i16* %7, align 2
%32 = icmp ne i16 %31, 0
br i1 %32, label %ErrRetReturn4, label %ErrRetContinue5
ErrRetReturn4: ; preds = %ErrRetContinue3
%33 = load i16, i16* %7, align 2
store i16 %33, i16* %result, align 2
ret i16 %33
ErrRetContinue5: ; preds = %ErrRetContinue3
store i16 0, i16* %result, align 2
ret i16 0
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i16 @std.fmt.format.10(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* nonnull readonly align 4 %0) unnamed_addr #1 {
Entry:
%result = alloca i16, align 2
%options = alloca %std.fmt.FormatOptions, align 8
%1 = alloca i16, align 2
%2 = bitcast %std.fmt.FormatOptions* %options to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %2, i8* align 8 bitcast ({ %"?usize", %"?usize", i2, <{ i8, [6 x i8] }> }* @48 to i8*), i64 40, i1 false)
%3 = call fastcc i16 @"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeAll"(%"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %0, %"[]u8"* @50)
store i16 %3, i16* %1, align 2
%4 = icmp ne i16 %3, 0
br i1 %4, label %ErrRetReturn, label %ErrRetContinue
ErrRetReturn: ; preds = %Entry
%5 = load i16, i16* %1, align 2
store i16 %5, i16* %result, align 2
ret i16 %5
ErrRetContinue: ; preds = %Entry
store i16 0, i16* %result, align 2
ret i16 0
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i16 @std.fmt.formatType.11(i64 %0, %std.fmt.FormatOptions* nonnull readonly align 8 %1, %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* nonnull readonly align 4 %2, i64 %3) unnamed_addr #1 {
Entry:
%result = alloca i16, align 2
%4 = alloca i64, align 8
%5 = alloca %std.fmt.FormatOptions, align 8
%6 = alloca %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)", align 4
%value = alloca i64, align 8
%max_depth = alloca i64, align 8
store i64 %0, i64* %value, align 8
store i64 %3, i64* %max_depth, align 8
%7 = load i64, i64* %value, align 8
store i64 %7, i64* %4, align 8
%8 = bitcast %std.fmt.FormatOptions* %1 to i8*
%9 = bitcast %std.fmt.FormatOptions* %5 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %9, i8* align 8 %8, i64 40, i1 false)
%10 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2 to i8*
%11 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %6 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %11, i8* align 4 %10, i64 4, i1 false)
%12 = call fastcc i16 @std.fmt.formatValue(i64 %7, %std.fmt.FormatOptions* %1, %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2)
store i16 %12, i16* %result, align 2
%13 = load i16, i16* %result, align 2
ret i16 %13
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i16 @std.fmt.formatValue(i64 %0, %std.fmt.FormatOptions* nonnull readonly align 8 %1, %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* nonnull readonly align 4 %2) unnamed_addr #1 {
Entry:
%result = alloca i16, align 2
%3 = alloca i64, align 8
%4 = alloca %std.fmt.FormatOptions, align 8
%5 = alloca %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)", align 4
%value = alloca i64, align 8
store i64 %0, i64* %value, align 8
%6 = load i64, i64* %value, align 8
store i64 %6, i64* %3, align 8
%7 = bitcast %std.fmt.FormatOptions* %1 to i8*
%8 = bitcast %std.fmt.FormatOptions* %4 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %8, i8* align 8 %7, i64 40, i1 false)
%9 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2 to i8*
%10 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %5 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %10, i8* align 4 %9, i64 4, i1 false)
%11 = call fastcc i16 @std.fmt.formatIntValue(i64 %6, %std.fmt.FormatOptions* %1, %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2)
store i16 %11, i16* %result, align 2
%12 = load i16, i16* %result, align 2
ret i16 %12
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i16 @std.fmt.formatIntValue(i64 %0, %std.fmt.FormatOptions* nonnull readonly align 8 %1, %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* nonnull readonly align 4 %2) unnamed_addr #1 {
Entry:
%result = alloca i16, align 2
%int_value = alloca i64, align 8
%3 = alloca i64, align 8
%4 = alloca %std.fmt.FormatOptions, align 8
%5 = alloca %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)", align 4
%value = alloca i64, align 8
store i64 %0, i64* %value, align 8
%6 = load i64, i64* %value, align 8
store i64 %6, i64* %int_value, align 8
%7 = load i64, i64* %int_value, align 8
store i64 %7, i64* %3, align 8
%8 = bitcast %std.fmt.FormatOptions* %1 to i8*
%9 = bitcast %std.fmt.FormatOptions* %4 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %9, i8* align 8 %8, i64 40, i1 false)
%10 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2 to i8*
%11 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %5 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %11, i8* align 4 %10, i64 4, i1 false)
%12 = call fastcc i16 @std.fmt.formatInt(i64 %7, i8 10, i1 false, %std.fmt.FormatOptions* %1, %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %2)
store i16 %12, i16* %result, align 2
%13 = load i16, i16* %result, align 2
ret i16 %13
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i16 @std.fmt.formatInt(i64 %0, i8 %1, i1 %2, %std.fmt.FormatOptions* nonnull readonly align 8 %3, %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* nonnull readonly align 4 %4) unnamed_addr #1 {
Entry:
%5 = alloca [6 x i64], align 8
%result = alloca i16, align 2
%int_value = alloca i64, align 8
%6 = alloca i64, align 8
%abs_value = alloca i64, align 8
%buf = alloca [65 x i8], align 1
%a = alloca i64, align 8
%index = alloca i64, align 8
%digit = alloca i64, align 8
%7 = alloca %"[]u8", align 8
%8 = alloca %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)", align 4
%value = alloca i64, align 8
%base = alloca i8, align 1
%uppercase = alloca i1, align 1
store i64 %0, i64* %value, align 8
store i8 %1, i8* %base, align 1
store i1 %2, i1* %uppercase, align 1
%9 = load i8, i8* %base, align 1
%10 = icmp uge i8 %9, 2
call fastcc void @std.debug.assert(i1 %10)
%11 = load i64, i64* %value, align 8
store i64 %11, i64* %int_value, align 8
%12 = load i64, i64* %int_value, align 8
store i64 %12, i64* %6, align 8
%13 = call fastcc i64 @std.math.absCast(i64 %12)
store i64 %13, i64* %abs_value, align 8
%14 = bitcast [65 x i8]* %buf to i8*
call void @llvm.memset.p0i8.i64(i8* align 1 %14, i8 -86, i64 65, i1 false)
%15 = ptrtoint i8* %14 to i64
%16 = getelementptr inbounds [6 x i64], [6 x i64]* %5, i64 0, i64 0
store i64 1296236545, i64* %16, align 8
%17 = getelementptr inbounds [6 x i64], [6 x i64]* %5, i64 0, i64 1
store i64 %15, i64* %17, align 8
%18 = getelementptr inbounds [6 x i64], [6 x i64]* %5, i64 0, i64 2
store i64 65, i64* %18, align 8
%19 = getelementptr inbounds [6 x i64], [6 x i64]* %5, i64 0, i64 3
store i64 0, i64* %19, align 8
%20 = getelementptr inbounds [6 x i64], [6 x i64]* %5, i64 0, i64 4
store i64 0, i64* %20, align 8
%21 = getelementptr inbounds [6 x i64], [6 x i64]* %5, i64 0, i64 5
store i64 0, i64* %21, align 8
%22 = ptrtoint [6 x i64]* %5 to i64
%23 = call i64 asm sideeffect "rolq $$3, %rdi ; rolq $$13, %rdi\0Arolq $$61, %rdi ; rolq $$51, %rdi\0Axchgq %rbx,%rbx\0A", "={rdx},{rax},0,~{cc},~{memory}"(i64 %22, i64 0)
%24 = load i64, i64* %abs_value, align 8
store i64 %24, i64* %a, align 8
store i64 65, i64* %index, align 8
br label %WhileCond
WhileCond: ; preds = %EndIf, %Entry
br label %WhileBody
WhileBody: ; preds = %WhileCond
%25 = load i64, i64* %a, align 8
%26 = load i8, i8* %base, align 1
%27 = zext i8 %26 to i64
%28 = icmp eq i64 %27, 0
br i1 %28, label %RemZeroFail, label %RemZeroOk
Then: ; preds = %DivZeroOk
br label %WhileEnd
Else: ; preds = %DivZeroOk
br label %EndIf
EndIf: ; preds = %Else
br label %WhileCond
WhileEnd: ; preds = %Then
%29 = load i64, i64* %index, align 8
%30 = icmp ule i64 %29, 65
br i1 %30, label %BoundsCheckOk2, label %BoundsCheckFail1
RemZeroOk: ; preds = %WhileBody
%31 = urem i64 %25, %27
store i64 %31, i64* %digit, align 8
%32 = load i64, i64* %index, align 8
%33 = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %32, i64 1)
%34 = extractvalue { i64, i1 } %33, 0
%35 = extractvalue { i64, i1 } %33, 1
br i1 %35, label %OverflowFail, label %OverflowOk
RemZeroFail: ; preds = %WhileBody
call fastcc void @panic(%"[]u8"* @11, %std.builtin.StackTrace* null)
unreachable
OverflowFail: ; preds = %RemZeroOk
call fastcc void @panic(%"[]u8"* @32, %std.builtin.StackTrace* null)
unreachable
OverflowOk: ; preds = %RemZeroOk
store i64 %34, i64* %index, align 8
%36 = load i64, i64* %index, align 8
%37 = icmp ult i64 %36, 65
br i1 %37, label %BoundsCheckOk, label %BoundsCheckFail
BoundsCheckFail: ; preds = %OverflowOk
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk: ; preds = %OverflowOk
%38 = getelementptr inbounds [65 x i8], [65 x i8]* %buf, i64 0, i64 %36
%39 = load i64, i64* %digit, align 8
%40 = trunc i64 %39 to i8
%41 = zext i8 %40 to i64
%42 = icmp eq i64 %39, %41
br i1 %42, label %CastShortenOk, label %CastShortenFail
CastShortenOk: ; preds = %BoundsCheckOk
%43 = load i1, i1* %uppercase, align 1
%44 = call fastcc i8 @std.fmt.digitToChar(i8 %40, i1 %43)
store i8 %44, i8* %38, align 1
%45 = load i64, i64* %a, align 8
%46 = load i8, i8* %base, align 1
%47 = zext i8 %46 to i64
%48 = icmp eq i64 %47, 0
br i1 %48, label %DivZeroFail, label %DivZeroOk
CastShortenFail: ; preds = %BoundsCheckOk
call fastcc void @panic(%"[]u8"* @13, %std.builtin.StackTrace* null)
unreachable
DivZeroFail: ; preds = %CastShortenOk
call fastcc void @panic(%"[]u8"* @9, %std.builtin.StackTrace* null)
unreachable
DivZeroOk: ; preds = %CastShortenOk
%49 = udiv i64 %45, %47
store i64 %49, i64* %a, align 8
%50 = load i64, i64* %a, align 8
%51 = icmp eq i64 %50, 0
br i1 %51, label %Then, label %Else
BoundsCheckFail1: ; preds = %WhileEnd
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk2: ; preds = %WhileEnd
br i1 true, label %BoundsCheckOk4, label %BoundsCheckFail3
BoundsCheckFail3: ; preds = %BoundsCheckOk2
call fastcc void @panic(%"[]u8"* @15, %std.builtin.StackTrace* null)
unreachable
BoundsCheckOk4: ; preds = %BoundsCheckOk2
%52 = getelementptr inbounds [65 x i8], [65 x i8]* %buf, i64 0, i64 %29
%53 = sub nuw i64 65, %29
%54 = getelementptr inbounds %"[]u8", %"[]u8"* %7, i32 0, i32 0
store i8* %52, i8** %54, align 8
%55 = getelementptr inbounds %"[]u8", %"[]u8"* %7, i32 0, i32 1
store i64 %53, i64* %55, align 8
%56 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %4 to i8*
%57 = bitcast %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %8 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %57, i8* align 4 %56, i64 4, i1 false)
%58 = call fastcc i16 @std.fmt.formatBuf(%"[]u8"* %7, %std.fmt.FormatOptions* %3, %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %4)
store i16 %58, i16* %result, align 2
%59 = load i16, i16* %result, align 2
ret i16 %59
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i64 @std.math.absCast(i64 %0) unnamed_addr #1 {
Entry:
%result = alloca i64, align 8
%x = alloca i64, align 8
store i64 %0, i64* %x, align 8
%1 = load i64, i64* %x, align 8
store i64 %1, i64* %result, align 8
%2 = load i64, i64* %result, align 8
ret i64 %2
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i8 @std.fmt.digitToChar(i8 %0, i1 %1) unnamed_addr #1 {
Entry:
%result = alloca i8, align 1
%2 = alloca i8, align 1
%digit = alloca i8, align 1
%uppercase = alloca i1, align 1
store i8 %0, i8* %digit, align 1
store i1 %1, i1* %uppercase, align 1
%3 = load i8, i8* %digit, align 1
%4 = icmp ule i8 %3, 9
%5 = and i1 true, %4
br i1 %5, label %SwitchRangeYes, label %SwitchRangeNo
SwitchRangeYes: ; preds = %Entry
%6 = load i8, i8* %digit, align 1
%7 = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %6, i8 48)
%8 = extractvalue { i8, i1 } %7, 0
%9 = extractvalue { i8, i1 } %7, 1
br i1 %9, label %OverflowFail, label %OverflowOk
SwitchRangeNo: ; preds = %Entry
%10 = icmp uge i8 %3, 10
%11 = icmp ule i8 %3, 35
%12 = and i1 %10, %11
br i1 %12, label %SwitchRangeYes1, label %SwitchRangeNo2
SwitchRangeYes1: ; preds = %SwitchRangeNo
%13 = load i8, i8* %digit, align 1
%14 = load i1, i1* %uppercase, align 1
br i1 %14, label %Then, label %Else
Then: ; preds = %SwitchRangeYes1
store i8 65, i8* %2, align 1
store i8 65, i8* %2, align 1
br label %EndIf
Else: ; preds = %SwitchRangeYes1
store i8 97, i8* %2, align 1
store i8 97, i8* %2, align 1
br label %EndIf
EndIf: ; preds = %Else, %Then
%15 = phi i8 [ 65, %Then ], [ 97, %Else ]
%16 = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %15, i8 10)
%17 = extractvalue { i8, i1 } %16, 0
%18 = extractvalue { i8, i1 } %16, 1
br i1 %18, label %OverflowFail3, label %OverflowOk4
SwitchRangeNo2: ; preds = %SwitchRangeNo
br label %SwitchElse
SwitchElse: ; preds = %SwitchRangeNo2
call fastcc void @panic(%"[]u8"* @17, %std.builtin.StackTrace* null)
unreachable
SwitchEnd: ; preds = %OverflowOk6, %OverflowOk
%19 = load i8, i8* %result, align 1
ret i8 %19
OverflowFail: ; preds = %SwitchRangeYes
call fastcc void @panic(%"[]u8"* @32, %std.builtin.StackTrace* null)
unreachable
OverflowOk: ; preds = %SwitchRangeYes
store i8 %8, i8* %result, align 1
br label %SwitchEnd
OverflowFail3: ; preds = %EndIf
call fastcc void @panic(%"[]u8"* @32, %std.builtin.StackTrace* null)
unreachable
OverflowOk4: ; preds = %EndIf
%20 = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %13, i8 %17)
%21 = extractvalue { i8, i1 } %20, 0
%22 = extractvalue { i8, i1 } %20, 1
br i1 %22, label %OverflowFail5, label %OverflowOk6
OverflowFail5: ; preds = %OverflowOk4
call fastcc void @panic(%"[]u8"* @32, %std.builtin.StackTrace* null)
unreachable
OverflowOk6: ; preds = %OverflowOk4
store i8 %21, i8* %result, align 1
br label %SwitchEnd
}
; Function Attrs: nounwind readnone speculatable willreturn
declare { i8, i1 } @llvm.uadd.with.overflow.i8(i8, i8) #4
; Function Attrs: nounwind readnone speculatable willreturn
declare { i8, i1 } @llvm.usub.with.overflow.i8(i8, i8) #4
; Function Attrs: nounwind
declare void @llvm.stackprotector(i8*, i8**) #6
attributes #0 = { nobuiltin noreturn nounwind "frame-pointer"="all" "probe-stack"="__zig_probe_stack" }
attributes #1 = { nobuiltin nounwind "frame-pointer"="all" "probe-stack"="__zig_probe_stack" }
attributes #2 = { nobuiltin noinline nounwind alignstack=16 "frame-pointer"="all" "probe-stack"="__zig_probe_stack" }
attributes #3 = { argmemonly nounwind willreturn }
attributes #4 = { nounwind readnone speculatable willreturn }
attributes #5 = { argmemonly nounwind willreturn writeonly }
attributes #6 = { nounwind }
!llvm.module.flags = !{!0, !1}
!llvm.dbg.cu = !{!2}
!0 = !{i32 2, !"Debug Info Version", i32 3}
!1 = !{i32 2, !"Dwarf Version", i32 4}
!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "zig 0.7.0", isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug, enums: !4)
!3 = !DIFile(filename: "foo", directory: "/tmp")
!4 = !{!5, !12, !53, !73, !79, !133, !155, !161, !167, !173, !177, !182, !320, !341, !347}
!5 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "std.builtin.OutputMode", scope: !6, file: !6, line: 450, baseType: !7, size: 8, align: 8, elements: !8)
!6 = !DIFile(filename: "builtin.zig", directory: "/home/lemonboy/code/zig/lib/std")
!7 = !DIBasicType(name: "u2", size: 8, encoding: DW_ATE_unsigned)
!8 = !{!9, !10, !11}
!9 = !DIEnumerator(name: "Exe", value: 0)
!10 = !DIEnumerator(name: "Lib", value: 1)
!11 = !DIEnumerator(name: "Obj", value: 2)
!12 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "std.target.Tag", scope: !13, file: !13, line: 23, baseType: !14, size: 8, align: 8, elements: !15)
!13 = !DIFile(filename: "target.zig", directory: "/home/lemonboy/code/zig/lib/std")
!14 = !DIBasicType(name: "u6", size: 8, encoding: DW_ATE_unsigned)
!15 = !{!16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43, !44, !45, !46, !47, !48, !49, !50, !51, !52}
!16 = !DIEnumerator(name: "freestanding", value: 0)
!17 = !DIEnumerator(name: "ananas", value: 1)
!18 = !DIEnumerator(name: "cloudabi", value: 2)
!19 = !DIEnumerator(name: "dragonfly", value: 3)
!20 = !DIEnumerator(name: "freebsd", value: 4)
!21 = !DIEnumerator(name: "fuchsia", value: 5)
!22 = !DIEnumerator(name: "ios", value: 6)
!23 = !DIEnumerator(name: "kfreebsd", value: 7)
!24 = !DIEnumerator(name: "linux", value: 8)
!25 = !DIEnumerator(name: "lv2", value: 9)
!26 = !DIEnumerator(name: "macos", value: 10)
!27 = !DIEnumerator(name: "netbsd", value: 11)
!28 = !DIEnumerator(name: "openbsd", value: 12)
!29 = !DIEnumerator(name: "solaris", value: 13)
!30 = !DIEnumerator(name: "windows", value: 14)
!31 = !DIEnumerator(name: "haiku", value: 15)
!32 = !DIEnumerator(name: "minix", value: 16)
!33 = !DIEnumerator(name: "rtems", value: 17)
!34 = !DIEnumerator(name: "nacl", value: 18)
!35 = !DIEnumerator(name: "cnk", value: 19)
!36 = !DIEnumerator(name: "aix", value: 20)
!37 = !DIEnumerator(name: "cuda", value: 21)
!38 = !DIEnumerator(name: "nvcl", value: 22)
!39 = !DIEnumerator(name: "amdhsa", value: 23)
!40 = !DIEnumerator(name: "ps4", value: 24)
!41 = !DIEnumerator(name: "elfiamcu", value: 25)
!42 = !DIEnumerator(name: "tvos", value: 26)
!43 = !DIEnumerator(name: "watchos", value: 27)
!44 = !DIEnumerator(name: "mesa3d", value: 28)
!45 = !DIEnumerator(name: "contiki", value: 29)
!46 = !DIEnumerator(name: "amdpal", value: 30)
!47 = !DIEnumerator(name: "hermit", value: 31)
!48 = !DIEnumerator(name: "hurd", value: 32)
!49 = !DIEnumerator(name: "wasi", value: 33)
!50 = !DIEnumerator(name: "emscripten", value: 34)
!51 = !DIEnumerator(name: "uefi", value: 35)
!52 = !DIEnumerator(name: "other", value: 36)
!53 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "std.target.WindowsVersion", scope: !13, file: !13, line: 89, baseType: !54, size: 32, align: 32, elements: !55)
!54 = !DIBasicType(name: "u32", size: 32, encoding: DW_ATE_unsigned)
!55 = !{!56, !57, !58, !59, !60, !61, !62, !63, !64, !65, !66, !67, !68, !69, !70, !71, !72}
!56 = !DIEnumerator(name: "nt4", value: 67108864)
!57 = !DIEnumerator(name: "win2k", value: 83886080)
!58 = !DIEnumerator(name: "xp", value: 83951616)
!59 = !DIEnumerator(name: "ws2003", value: 84017152)
!60 = !DIEnumerator(name: "vista", value: 100663296)
!61 = !DIEnumerator(name: "win7", value: 100728832)
!62 = !DIEnumerator(name: "win8", value: 100794368)
!63 = !DIEnumerator(name: "win8_1", value: 100859904)
!64 = !DIEnumerator(name: "win10", value: 167772160)
!65 = !DIEnumerator(name: "win10_th2", value: 167772161)
!66 = !DIEnumerator(name: "win10_rs1", value: 167772162)
!67 = !DIEnumerator(name: "win10_rs2", value: 167772163)
!68 = !DIEnumerator(name: "win10_rs3", value: 167772164)
!69 = !DIEnumerator(name: "win10_rs4", value: 167772165)
!70 = !DIEnumerator(name: "win10_rs5", value: 167772166)
!71 = !DIEnumerator(name: "win10_19h1", value: 167772167)
!72 = !DIEnumerator(name: "win10_20h1", value: 167772168)
!73 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "@TagType(std.target.VersionRange)", scope: !13, file: !13, line: 192, baseType: !7, size: 8, align: 8, elements: !74)
!74 = !{!75, !76, !77, !78}
!75 = !DIEnumerator(name: "none", value: 0)
!76 = !DIEnumerator(name: "semver", value: 1)
!77 = !DIEnumerator(name: "linux", value: 2)
!78 = !DIEnumerator(name: "windows", value: 3)
!79 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "std.target.Arch", scope: !13, file: !13, line: 666, baseType: !14, size: 8, align: 8, elements: !80)
!80 = !{!81, !82, !83, !84, !85, !86, !87, !88, !89, !90, !91, !92, !93, !94, !95, !96, !97, !98, !99, !100, !101, !102, !103, !104, !105, !106, !107, !108, !109, !110, !111, !112, !113, !114, !115, !116, !117, !118, !119, !120, !121, !122, !123, !124, !125, !126, !127, !128, !129, !130, !131, !132}
!81 = !DIEnumerator(name: "arm", value: 0)
!82 = !DIEnumerator(name: "armeb", value: 1)
!83 = !DIEnumerator(name: "aarch64", value: 2)
!84 = !DIEnumerator(name: "aarch64_be", value: 3)
!85 = !DIEnumerator(name: "aarch64_32", value: 4)
!86 = !DIEnumerator(name: "arc", value: 5)
!87 = !DIEnumerator(name: "avr", value: 6)
!88 = !DIEnumerator(name: "bpfel", value: 7)
!89 = !DIEnumerator(name: "bpfeb", value: 8)
!90 = !DIEnumerator(name: "hexagon", value: 9)
!91 = !DIEnumerator(name: "mips", value: 10)
!92 = !DIEnumerator(name: "mipsel", value: 11)
!93 = !DIEnumerator(name: "mips64", value: 12)
!94 = !DIEnumerator(name: "mips64el", value: 13)
!95 = !DIEnumerator(name: "msp430", value: 14)
!96 = !DIEnumerator(name: "powerpc", value: 15)
!97 = !DIEnumerator(name: "powerpc64", value: 16)
!98 = !DIEnumerator(name: "powerpc64le", value: 17)
!99 = !DIEnumerator(name: "r600", value: 18)
!100 = !DIEnumerator(name: "amdgcn", value: 19)
!101 = !DIEnumerator(name: "riscv32", value: 20)
!102 = !DIEnumerator(name: "riscv64", value: 21)
!103 = !DIEnumerator(name: "sparc", value: 22)
!104 = !DIEnumerator(name: "sparcv9", value: 23)
!105 = !DIEnumerator(name: "sparcel", value: 24)
!106 = !DIEnumerator(name: "s390x", value: 25)
!107 = !DIEnumerator(name: "tce", value: 26)
!108 = !DIEnumerator(name: "tcele", value: 27)
!109 = !DIEnumerator(name: "thumb", value: 28)
!110 = !DIEnumerator(name: "thumbeb", value: 29)
!111 = !DIEnumerator(name: "i386", value: 30)
!112 = !DIEnumerator(name: "x86_64", value: 31)
!113 = !DIEnumerator(name: "xcore", value: 32)
!114 = !DIEnumerator(name: "nvptx", value: 33)
!115 = !DIEnumerator(name: "nvptx64", value: 34)
!116 = !DIEnumerator(name: "le32", value: 35)
!117 = !DIEnumerator(name: "le64", value: 36)
!118 = !DIEnumerator(name: "amdil", value: 37)
!119 = !DIEnumerator(name: "amdil64", value: 38)
!120 = !DIEnumerator(name: "hsail", value: 39)
!121 = !DIEnumerator(name: "hsail64", value: 40)
!122 = !DIEnumerator(name: "spir", value: 41)
!123 = !DIEnumerator(name: "spir64", value: 42)
!124 = !DIEnumerator(name: "kalimba", value: 43)
!125 = !DIEnumerator(name: "shave", value: 44)
!126 = !DIEnumerator(name: "lanai", value: 45)
!127 = !DIEnumerator(name: "wasm32", value: 46)
!128 = !DIEnumerator(name: "wasm64", value: 47)
!129 = !DIEnumerator(name: "renderscript32", value: 48)
!130 = !DIEnumerator(name: "renderscript64", value: 49)
!131 = !DIEnumerator(name: "ve", value: 50)
!132 = !DIEnumerator(name: "spu_2", value: 51)
!133 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "std.target.Abi", scope: !13, file: !13, line: 402, baseType: !134, size: 8, align: 8, elements: !135)
!134 = !DIBasicType(name: "u5", size: 8, encoding: DW_ATE_unsigned)
!135 = !{!75, !136, !137, !138, !139, !140, !141, !142, !143, !144, !145, !146, !147, !148, !149, !150, !151, !152, !153, !154}
!136 = !DIEnumerator(name: "gnu", value: 1)
!137 = !DIEnumerator(name: "gnuabin32", value: 2)
!138 = !DIEnumerator(name: "gnuabi64", value: 3)
!139 = !DIEnumerator(name: "gnueabi", value: 4)
!140 = !DIEnumerator(name: "gnueabihf", value: 5)
!141 = !DIEnumerator(name: "gnux32", value: 6)
!142 = !DIEnumerator(name: "code16", value: 7)
!143 = !DIEnumerator(name: "eabi", value: 8)
!144 = !DIEnumerator(name: "eabihf", value: 9)
!145 = !DIEnumerator(name: "android", value: 10)
!146 = !DIEnumerator(name: "musl", value: 11)
!147 = !DIEnumerator(name: "musleabi", value: 12)
!148 = !DIEnumerator(name: "musleabihf", value: 13)
!149 = !DIEnumerator(name: "msvc", value: 14)
!150 = !DIEnumerator(name: "itanium", value: 15)
!151 = !DIEnumerator(name: "cygnus", value: 16)
!152 = !DIEnumerator(name: "coreclr", value: 17)
!153 = !DIEnumerator(name: "simulator", value: 18)
!154 = !DIEnumerator(name: "macabi", value: 19)
!155 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "std.builtin.Mode", scope: !6, file: !6, line: 144, baseType: !7, size: 8, align: 8, elements: !156)
!156 = !{!157, !158, !159, !160}
!157 = !DIEnumerator(name: "Debug", value: 0)
!158 = !DIEnumerator(name: "ReleaseSafe", value: 1)
!159 = !DIEnumerator(name: "ReleaseFast", value: 2)
!160 = !DIEnumerator(name: "ReleaseSmall", value: 3)
!161 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "std.io.Mode", scope: !162, file: !162, line: 20, baseType: !163, size: 8, align: 8, elements: !164)
!162 = !DIFile(filename: "io.zig", directory: "/home/lemonboy/code/zig/lib/std")
!163 = !DIBasicType(name: "u1", size: 8, encoding: DW_ATE_unsigned)
!164 = !{!165, !166}
!165 = !DIEnumerator(name: "blocking", value: 0)
!166 = !DIEnumerator(name: "evented", value: 1)
!167 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "@TagType(ParamType)", scope: !168, file: !168, line: 13, baseType: !7, size: 8, align: 8, elements: !169)
!168 = !DIFile(filename: "foo.zig", directory: "/tmp")
!169 = !{!170, !171, !172}
!170 = !DIEnumerator(name: "boolean", value: 0)
!171 = !DIEnumerator(name: "buffer", value: 1)
!172 = !DIEnumerator(name: "one_of", value: 2)
!173 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "@TagType(Expression)", scope: !168, file: !168, line: 25, baseType: !163, size: 8, align: 8, elements: !174)
!174 = !{!175, !176}
!175 = !DIEnumerator(name: "literal_boolean", value: 0)
!176 = !DIEnumerator(name: "literal_enum_value", value: 1)
!177 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "@TagType(ExpressionResult)", scope: !168, file: !168, line: 34, baseType: !7, size: 8, align: 8, elements: !178)
!178 = !{!179, !180, !181}
!179 = !DIEnumerator(name: "temp_buffer", value: 0)
!180 = !DIEnumerator(name: "literal_boolean", value: 1)
!181 = !DIEnumerator(name: "literal_enum_value", value: 2)
!182 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "std.target.x86.Feature", scope: !183, file: !183, line: 10, baseType: !184, size: 8, align: 8, elements: !185)
!183 = !DIFile(filename: "x86.zig", directory: "/home/lemonboy/code/zig/lib/std/target")
!184 = !DIBasicType(name: "u8", size: 8, encoding: DW_ATE_unsigned_char)
!185 = !{!186, !187, !188, !189, !190, !191, !192, !193, !194, !195, !196, !197, !198, !199, !200, !201, !202, !203, !204, !205, !206, !207, !208, !209, !210, !211, !212, !213, !214, !215, !216, !217, !218, !219, !220, !221, !222, !223, !224, !225, !226, !227, !228, !229, !230, !231, !232, !233, !234, !235, !236, !237, !238, !239, !240, !241, !242, !243, !244, !245, !246, !247, !248, !249, !250, !251, !252, !253, !254, !255, !256, !257, !258, !259, !260, !261, !262, !263, !264, !265, !266, !267, !268, !269, !270, !271, !272, !273, !274, !275, !276, !277, !278, !279, !280, !281, !282, !283, !284, !285, !286, !287, !288, !289, !290, !291, !292, !293, !294, !295, !296, !297, !298, !299, !300, !301, !302, !303, !304, !305, !306, !307, !308, !309, !310, !311, !312, !313, !314, !315, !316, !317, !318, !319}
!186 = !DIEnumerator(name: "3dnow", value: 0)
!187 = !DIEnumerator(name: "3dnowa", value: 1)
!188 = !DIEnumerator(name: "64bit", value: 2)
!189 = !DIEnumerator(name: "adx", value: 3)
!190 = !DIEnumerator(name: "aes", value: 4)
!191 = !DIEnumerator(name: "amx_bf16", value: 5)
!192 = !DIEnumerator(name: "amx_int8", value: 6)
!193 = !DIEnumerator(name: "amx_tile", value: 7)
!194 = !DIEnumerator(name: "avx", value: 8)
!195 = !DIEnumerator(name: "avx2", value: 9)
!196 = !DIEnumerator(name: "avx512bf16", value: 10)
!197 = !DIEnumerator(name: "avx512bitalg", value: 11)
!198 = !DIEnumerator(name: "avx512bw", value: 12)
!199 = !DIEnumerator(name: "avx512cd", value: 13)
!200 = !DIEnumerator(name: "avx512dq", value: 14)
!201 = !DIEnumerator(name: "avx512er", value: 15)
!202 = !DIEnumerator(name: "avx512f", value: 16)
!203 = !DIEnumerator(name: "avx512ifma", value: 17)
!204 = !DIEnumerator(name: "avx512pf", value: 18)
!205 = !DIEnumerator(name: "avx512vbmi", value: 19)
!206 = !DIEnumerator(name: "avx512vbmi2", value: 20)
!207 = !DIEnumerator(name: "avx512vl", value: 21)
!208 = !DIEnumerator(name: "avx512vnni", value: 22)
!209 = !DIEnumerator(name: "avx512vp2intersect", value: 23)
!210 = !DIEnumerator(name: "avx512vpopcntdq", value: 24)
!211 = !DIEnumerator(name: "bmi", value: 25)
!212 = !DIEnumerator(name: "bmi2", value: 26)
!213 = !DIEnumerator(name: "branchfusion", value: 27)
!214 = !DIEnumerator(name: "cldemote", value: 28)
!215 = !DIEnumerator(name: "clflushopt", value: 29)
!216 = !DIEnumerator(name: "clwb", value: 30)
!217 = !DIEnumerator(name: "clzero", value: 31)
!218 = !DIEnumerator(name: "cmov", value: 32)
!219 = !DIEnumerator(name: "cx16", value: 33)
!220 = !DIEnumerator(name: "cx8", value: 34)
!221 = !DIEnumerator(name: "enqcmd", value: 35)
!222 = !DIEnumerator(name: "ermsb", value: 36)
!223 = !DIEnumerator(name: "f16c", value: 37)
!224 = !DIEnumerator(name: "false_deps_lzcnt_tzcnt", value: 38)
!225 = !DIEnumerator(name: "false_deps_popcnt", value: 39)
!226 = !DIEnumerator(name: "fast_11bytenop", value: 40)
!227 = !DIEnumerator(name: "fast_15bytenop", value: 41)
!228 = !DIEnumerator(name: "fast_7bytenop", value: 42)
!229 = !DIEnumerator(name: "fast_bextr", value: 43)
!230 = !DIEnumerator(name: "fast_gather", value: 44)
!231 = !DIEnumerator(name: "fast_hops", value: 45)
!232 = !DIEnumerator(name: "fast_lzcnt", value: 46)
!233 = !DIEnumerator(name: "fast_scalar_fsqrt", value: 47)
!234 = !DIEnumerator(name: "fast_scalar_shift_masks", value: 48)
!235 = !DIEnumerator(name: "fast_shld_rotate", value: 49)
!236 = !DIEnumerator(name: "fast_variable_shuffle", value: 50)
!237 = !DIEnumerator(name: "fast_vector_fsqrt", value: 51)
!238 = !DIEnumerator(name: "fast_vector_shift_masks", value: 52)
!239 = !DIEnumerator(name: "fma", value: 53)
!240 = !DIEnumerator(name: "fma4", value: 54)
!241 = !DIEnumerator(name: "fsgsbase", value: 55)
!242 = !DIEnumerator(name: "fxsr", value: 56)
!243 = !DIEnumerator(name: "gfni", value: 57)
!244 = !DIEnumerator(name: "idivl_to_divb", value: 58)
!245 = !DIEnumerator(name: "idivq_to_divl", value: 59)
!246 = !DIEnumerator(name: "invpcid", value: 60)
!247 = !DIEnumerator(name: "lea_sp", value: 61)
!248 = !DIEnumerator(name: "lea_uses_ag", value: 62)
!249 = !DIEnumerator(name: "lvi_cfi", value: 63)
!250 = !DIEnumerator(name: "lvi_load_hardening", value: 64)
!251 = !DIEnumerator(name: "lwp", value: 65)
!252 = !DIEnumerator(name: "lzcnt", value: 66)
!253 = !DIEnumerator(name: "macrofusion", value: 67)
!254 = !DIEnumerator(name: "merge_to_threeway_branch", value: 68)
!255 = !DIEnumerator(name: "mmx", value: 69)
!256 = !DIEnumerator(name: "movbe", value: 70)
!257 = !DIEnumerator(name: "movdir64b", value: 71)
!258 = !DIEnumerator(name: "movdiri", value: 72)
!259 = !DIEnumerator(name: "mpx", value: 73)
!260 = !DIEnumerator(name: "mwaitx", value: 74)
!261 = !DIEnumerator(name: "nopl", value: 75)
!262 = !DIEnumerator(name: "pad_short_functions", value: 76)
!263 = !DIEnumerator(name: "pclmul", value: 77)
!264 = !DIEnumerator(name: "pconfig", value: 78)
!265 = !DIEnumerator(name: "pku", value: 79)
!266 = !DIEnumerator(name: "popcnt", value: 80)
!267 = !DIEnumerator(name: "prefer_128_bit", value: 81)
!268 = !DIEnumerator(name: "prefer_256_bit", value: 82)
!269 = !DIEnumerator(name: "prefer_mask_registers", value: 83)
!270 = !DIEnumerator(name: "prefetchwt1", value: 84)
!271 = !DIEnumerator(name: "prfchw", value: 85)
!272 = !DIEnumerator(name: "ptwrite", value: 86)
!273 = !DIEnumerator(name: "rdpid", value: 87)
!274 = !DIEnumerator(name: "rdrnd", value: 88)
!275 = !DIEnumerator(name: "rdseed", value: 89)
!276 = !DIEnumerator(name: "retpoline", value: 90)
!277 = !DIEnumerator(name: "retpoline_external_thunk", value: 91)
!278 = !DIEnumerator(name: "retpoline_indirect_branches", value: 92)
!279 = !DIEnumerator(name: "retpoline_indirect_calls", value: 93)
!280 = !DIEnumerator(name: "rtm", value: 94)
!281 = !DIEnumerator(name: "sahf", value: 95)
!282 = !DIEnumerator(name: "serialize", value: 96)
!283 = !DIEnumerator(name: "seses", value: 97)
!284 = !DIEnumerator(name: "sgx", value: 98)
!285 = !DIEnumerator(name: "sha", value: 99)
!286 = !DIEnumerator(name: "shstk", value: 100)
!287 = !DIEnumerator(name: "slow_3ops_lea", value: 101)
!288 = !DIEnumerator(name: "slow_incdec", value: 102)
!289 = !DIEnumerator(name: "slow_lea", value: 103)
!290 = !DIEnumerator(name: "slow_pmaddwd", value: 104)
!291 = !DIEnumerator(name: "slow_pmulld", value: 105)
!292 = !DIEnumerator(name: "slow_shld", value: 106)
!293 = !DIEnumerator(name: "slow_two_mem_ops", value: 107)
!294 = !DIEnumerator(name: "slow_unaligned_mem_16", value: 108)
!295 = !DIEnumerator(name: "slow_unaligned_mem_32", value: 109)
!296 = !DIEnumerator(name: "soft_float", value: 110)
!297 = !DIEnumerator(name: "sse", value: 111)
!298 = !DIEnumerator(name: "sse_unaligned_mem", value: 112)
!299 = !DIEnumerator(name: "sse2", value: 113)
!300 = !DIEnumerator(name: "sse3", value: 114)
!301 = !DIEnumerator(name: "sse4_1", value: 115)
!302 = !DIEnumerator(name: "sse4_2", value: 116)
!303 = !DIEnumerator(name: "sse4a", value: 117)
!304 = !DIEnumerator(name: "ssse3", value: 118)
!305 = !DIEnumerator(name: "tbm", value: 119)
!306 = !DIEnumerator(name: "tsxldtrk", value: 120)
!307 = !DIEnumerator(name: "use_aa", value: 121)
!308 = !DIEnumerator(name: "use_glm_div_sqrt_costs", value: 122)
!309 = !DIEnumerator(name: "vaes", value: 123)
!310 = !DIEnumerator(name: "vpclmulqdq", value: 124)
!311 = !DIEnumerator(name: "vzeroupper", value: 125)
!312 = !DIEnumerator(name: "waitpkg", value: 126)
!313 = !DIEnumerator(name: "wbnoinvd", value: 127)
!314 = !DIEnumerator(name: "x87", value: 128)
!315 = !DIEnumerator(name: "xop", value: 129)
!316 = !DIEnumerator(name: "xsave", value: 130)
!317 = !DIEnumerator(name: "xsavec", value: 131)
!318 = !DIEnumerator(name: "xsaveopt", value: 132)
!319 = !DIEnumerator(name: "xsaves", value: 133)
!320 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "anyerror", baseType: !321, size: 16, align: 16, elements: !322)
!321 = !DIBasicType(name: "u16", size: 16, encoding: DW_ATE_unsigned)
!322 = !{!323, !324, !325, !326, !327, !328, !329, !330, !331, !332, !333, !334, !335, !336, !337, !338, !339, !340}
!323 = !DIEnumerator(name: "(none)", value: 0)
!324 = !DIEnumerator(name: "DiskQuota", value: 1)
!325 = !DIEnumerator(name: "FileTooBig", value: 2)
!326 = !DIEnumerator(name: "InputOutput", value: 3)
!327 = !DIEnumerator(name: "NoSpaceLeft", value: 4)
!328 = !DIEnumerator(name: "AccessDenied", value: 5)
!329 = !DIEnumerator(name: "BrokenPipe", value: 6)
!330 = !DIEnumerator(name: "SystemResources", value: 7)
!331 = !DIEnumerator(name: "OperationAborted", value: 8)
!332 = !DIEnumerator(name: "NotOpenForWriting", value: 9)
!333 = !DIEnumerator(name: "WouldBlock", value: 10)
!334 = !DIEnumerator(name: "Unexpected", value: 11)
!335 = !DIEnumerator(name: "Utf8InvalidStartByte", value: 12)
!336 = !DIEnumerator(name: "TruncatedInput", value: 13)
!337 = !DIEnumerator(name: "Utf8ExpectedContinuation", value: 14)
!338 = !DIEnumerator(name: "Utf8OverlongEncoding", value: 15)
!339 = !DIEnumerator(name: "Utf8EncodesSurrogateHalf", value: 16)
!340 = !DIEnumerator(name: "Utf8CodepointTooLarge", value: 17)
!341 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "std.fmt.Alignment", scope: !342, file: !342, line: 18, baseType: !7, size: 8, align: 8, elements: !343)
!342 = !DIFile(filename: "fmt.zig", directory: "/home/lemonboy/code/zig/lib/std")
!343 = !{!344, !345, !346}
!344 = !DIEnumerator(name: "Left", value: 0)
!345 = !DIEnumerator(name: "Center", value: 1)
!346 = !DIEnumerator(name: "Right", value: 2)
!347 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "std.os.bits.linux.x86_64.SYS", scope: !348, file: !348, line: 24, baseType: !349, size: 64, align: 64, elements: !350)
!348 = !DIFile(filename: "x86_64.zig", directory: "/home/lemonboy/code/zig/lib/std/os/bits/linux")
!349 = !DIBasicType(name: "usize", size: 64, encoding: DW_ATE_unsigned)
!350 = !{!351, !352, !353, !354, !355, !356, !357, !358, !359, !360, !361, !362, !363, !364, !365, !366, !367, !368, !369, !370, !371, !372, !373, !374, !375, !376, !377, !378, !379, !380, !381, !382, !383, !384, !385, !386, !387, !388, !389, !390, !391, !392, !393, !394, !395, !396, !397, !398, !399, !400, !401, !402, !403, !404, !405, !406, !407, !408, !409, !410, !411, !412, !413, !414, !415, !416, !417, !418, !419, !420, !421, !422, !423, !424, !425, !426, !427, !428, !429, !430, !431, !432, !433, !434, !435, !436, !437, !438, !439, !440, !441, !442, !443, !444, !445, !446, !447, !448, !449, !450, !451, !452, !453, !454, !455, !456, !457, !458, !459, !460, !461, !462, !463, !464, !465, !466, !467, !468, !469, !470, !471, !472, !473, !474, !475, !476, !477, !478, !479, !480, !481, !482, !483, !484, !485, !486, !487, !488, !489, !490, !491, !492, !493, !494, !495, !496, !497, !498, !499, !500, !501, !502, !503, !504, !505, !506, !507, !508, !509, !510, !511, !512, !513, !514, !515, !516, !517, !518, !519, !520, !521, !522, !523, !524, !525, !526, !527, !528, !529, !530, !531, !532, !533, !534, !535, !536, !537, !538, !539, !540, !541, !542, !543, !544, !545, !546, !547, !548, !549, !550, !551, !552, !553, !554, !555, !556, !557, !558, !559, !560, !561, !562, !563, !564, !565, !566, !567, !568, !569, !570, !571, !572, !573, !574, !575, !576, !577, !578, !579, !580, !581, !582, !583, !584, !585, !586, !587, !588, !589, !590, !591, !592, !593, !594, !595, !596, !597, !598, !599, !600, !601, !602, !603, !604, !605, !606, !607, !608, !609, !610, !611, !612, !613, !614, !615, !616, !617, !618, !619, !620, !621, !622, !623, !624, !625, !626, !627, !628, !629, !630, !631, !632, !633, !634, !635, !636, !637, !638, !639, !640, !641, !642, !643, !644, !645, !646, !647, !648, !649, !650, !651, !652, !653, !654, !655, !656, !657, !658, !659, !660, !661, !662, !663, !664, !665, !666, !667, !668, !669, !670, !671, !672, !673, !674, !675, !676, !677, !678, !679, !680, !681, !682, !683, !684, !685, !686, !687, !688, !689, !690, !691, !692, !693, !694, !695, !696, !697, !698, !699, !700}
!351 = !DIEnumerator(name: "read", value: 0)
!352 = !DIEnumerator(name: "write", value: 1)
!353 = !DIEnumerator(name: "open", value: 2)
!354 = !DIEnumerator(name: "close", value: 3)
!355 = !DIEnumerator(name: "stat", value: 4)
!356 = !DIEnumerator(name: "fstat", value: 5)
!357 = !DIEnumerator(name: "lstat", value: 6)
!358 = !DIEnumerator(name: "poll", value: 7)
!359 = !DIEnumerator(name: "lseek", value: 8)
!360 = !DIEnumerator(name: "mmap", value: 9)
!361 = !DIEnumerator(name: "mprotect", value: 10)
!362 = !DIEnumerator(name: "munmap", value: 11)
!363 = !DIEnumerator(name: "brk", value: 12)
!364 = !DIEnumerator(name: "rt_sigaction", value: 13)
!365 = !DIEnumerator(name: "rt_sigprocmask", value: 14)
!366 = !DIEnumerator(name: "rt_sigreturn", value: 15)
!367 = !DIEnumerator(name: "ioctl", value: 16)
!368 = !DIEnumerator(name: "pread", value: 17)
!369 = !DIEnumerator(name: "pwrite", value: 18)
!370 = !DIEnumerator(name: "readv", value: 19)
!371 = !DIEnumerator(name: "writev", value: 20)
!372 = !DIEnumerator(name: "access", value: 21)
!373 = !DIEnumerator(name: "pipe", value: 22)
!374 = !DIEnumerator(name: "select", value: 23)
!375 = !DIEnumerator(name: "sched_yield", value: 24)
!376 = !DIEnumerator(name: "mremap", value: 25)
!377 = !DIEnumerator(name: "msync", value: 26)
!378 = !DIEnumerator(name: "mincore", value: 27)
!379 = !DIEnumerator(name: "madvise", value: 28)
!380 = !DIEnumerator(name: "shmget", value: 29)
!381 = !DIEnumerator(name: "shmat", value: 30)
!382 = !DIEnumerator(name: "shmctl", value: 31)
!383 = !DIEnumerator(name: "dup", value: 32)
!384 = !DIEnumerator(name: "dup2", value: 33)
!385 = !DIEnumerator(name: "pause", value: 34)
!386 = !DIEnumerator(name: "nanosleep", value: 35)
!387 = !DIEnumerator(name: "getitimer", value: 36)
!388 = !DIEnumerator(name: "alarm", value: 37)
!389 = !DIEnumerator(name: "setitimer", value: 38)
!390 = !DIEnumerator(name: "getpid", value: 39)
!391 = !DIEnumerator(name: "sendfile", value: 40)
!392 = !DIEnumerator(name: "socket", value: 41)
!393 = !DIEnumerator(name: "connect", value: 42)
!394 = !DIEnumerator(name: "accept", value: 43)
!395 = !DIEnumerator(name: "sendto", value: 44)
!396 = !DIEnumerator(name: "recvfrom", value: 45)
!397 = !DIEnumerator(name: "sendmsg", value: 46)
!398 = !DIEnumerator(name: "recvmsg", value: 47)
!399 = !DIEnumerator(name: "shutdown", value: 48)
!400 = !DIEnumerator(name: "bind", value: 49)
!401 = !DIEnumerator(name: "listen", value: 50)
!402 = !DIEnumerator(name: "getsockname", value: 51)
!403 = !DIEnumerator(name: "getpeername", value: 52)
!404 = !DIEnumerator(name: "socketpair", value: 53)
!405 = !DIEnumerator(name: "setsockopt", value: 54)
!406 = !DIEnumerator(name: "getsockopt", value: 55)
!407 = !DIEnumerator(name: "clone", value: 56)
!408 = !DIEnumerator(name: "fork", value: 57)
!409 = !DIEnumerator(name: "vfork", value: 58)
!410 = !DIEnumerator(name: "execve", value: 59)
!411 = !DIEnumerator(name: "exit", value: 60)
!412 = !DIEnumerator(name: "wait4", value: 61)
!413 = !DIEnumerator(name: "kill", value: 62)
!414 = !DIEnumerator(name: "uname", value: 63)
!415 = !DIEnumerator(name: "semget", value: 64)
!416 = !DIEnumerator(name: "semop", value: 65)
!417 = !DIEnumerator(name: "semctl", value: 66)
!418 = !DIEnumerator(name: "shmdt", value: 67)
!419 = !DIEnumerator(name: "msgget", value: 68)
!420 = !DIEnumerator(name: "msgsnd", value: 69)
!421 = !DIEnumerator(name: "msgrcv", value: 70)
!422 = !DIEnumerator(name: "msgctl", value: 71)
!423 = !DIEnumerator(name: "fcntl", value: 72)
!424 = !DIEnumerator(name: "flock", value: 73)
!425 = !DIEnumerator(name: "fsync", value: 74)
!426 = !DIEnumerator(name: "fdatasync", value: 75)
!427 = !DIEnumerator(name: "truncate", value: 76)
!428 = !DIEnumerator(name: "ftruncate", value: 77)
!429 = !DIEnumerator(name: "getdents", value: 78)
!430 = !DIEnumerator(name: "getcwd", value: 79)
!431 = !DIEnumerator(name: "chdir", value: 80)
!432 = !DIEnumerator(name: "fchdir", value: 81)
!433 = !DIEnumerator(name: "rename", value: 82)
!434 = !DIEnumerator(name: "mkdir", value: 83)
!435 = !DIEnumerator(name: "rmdir", value: 84)
!436 = !DIEnumerator(name: "creat", value: 85)
!437 = !DIEnumerator(name: "link", value: 86)
!438 = !DIEnumerator(name: "unlink", value: 87)
!439 = !DIEnumerator(name: "symlink", value: 88)
!440 = !DIEnumerator(name: "readlink", value: 89)
!441 = !DIEnumerator(name: "chmod", value: 90)
!442 = !DIEnumerator(name: "fchmod", value: 91)
!443 = !DIEnumerator(name: "chown", value: 92)
!444 = !DIEnumerator(name: "fchown", value: 93)
!445 = !DIEnumerator(name: "lchown", value: 94)
!446 = !DIEnumerator(name: "umask", value: 95)
!447 = !DIEnumerator(name: "gettimeofday", value: 96)
!448 = !DIEnumerator(name: "getrlimit", value: 97)
!449 = !DIEnumerator(name: "getrusage", value: 98)
!450 = !DIEnumerator(name: "sysinfo", value: 99)
!451 = !DIEnumerator(name: "times", value: 100)
!452 = !DIEnumerator(name: "ptrace", value: 101)
!453 = !DIEnumerator(name: "getuid", value: 102)
!454 = !DIEnumerator(name: "syslog", value: 103)
!455 = !DIEnumerator(name: "getgid", value: 104)
!456 = !DIEnumerator(name: "setuid", value: 105)
!457 = !DIEnumerator(name: "setgid", value: 106)
!458 = !DIEnumerator(name: "geteuid", value: 107)
!459 = !DIEnumerator(name: "getegid", value: 108)
!460 = !DIEnumerator(name: "setpgid", value: 109)
!461 = !DIEnumerator(name: "getppid", value: 110)
!462 = !DIEnumerator(name: "getpgrp", value: 111)
!463 = !DIEnumerator(name: "setsid", value: 112)
!464 = !DIEnumerator(name: "setreuid", value: 113)
!465 = !DIEnumerator(name: "setregid", value: 114)
!466 = !DIEnumerator(name: "getgroups", value: 115)
!467 = !DIEnumerator(name: "setgroups", value: 116)
!468 = !DIEnumerator(name: "setresuid", value: 117)
!469 = !DIEnumerator(name: "getresuid", value: 118)
!470 = !DIEnumerator(name: "setresgid", value: 119)
!471 = !DIEnumerator(name: "getresgid", value: 120)
!472 = !DIEnumerator(name: "getpgid", value: 121)
!473 = !DIEnumerator(name: "setfsuid", value: 122)
!474 = !DIEnumerator(name: "setfsgid", value: 123)
!475 = !DIEnumerator(name: "getsid", value: 124)
!476 = !DIEnumerator(name: "capget", value: 125)
!477 = !DIEnumerator(name: "capset", value: 126)
!478 = !DIEnumerator(name: "rt_sigpending", value: 127)
!479 = !DIEnumerator(name: "rt_sigtimedwait", value: 128)
!480 = !DIEnumerator(name: "rt_sigqueueinfo", value: 129)
!481 = !DIEnumerator(name: "rt_sigsuspend", value: 130)
!482 = !DIEnumerator(name: "sigaltstack", value: 131)
!483 = !DIEnumerator(name: "utime", value: 132)
!484 = !DIEnumerator(name: "mknod", value: 133)
!485 = !DIEnumerator(name: "uselib", value: 134)
!486 = !DIEnumerator(name: "personality", value: 135)
!487 = !DIEnumerator(name: "ustat", value: 136)
!488 = !DIEnumerator(name: "statfs", value: 137)
!489 = !DIEnumerator(name: "fstatfs", value: 138)
!490 = !DIEnumerator(name: "sysfs", value: 139)
!491 = !DIEnumerator(name: "getpriority", value: 140)
!492 = !DIEnumerator(name: "setpriority", value: 141)
!493 = !DIEnumerator(name: "sched_setparam", value: 142)
!494 = !DIEnumerator(name: "sched_getparam", value: 143)
!495 = !DIEnumerator(name: "sched_setscheduler", value: 144)
!496 = !DIEnumerator(name: "sched_getscheduler", value: 145)
!497 = !DIEnumerator(name: "sched_get_priority_max", value: 146)
!498 = !DIEnumerator(name: "sched_get_priority_min", value: 147)
!499 = !DIEnumerator(name: "sched_rr_get_interval", value: 148)
!500 = !DIEnumerator(name: "mlock", value: 149)
!501 = !DIEnumerator(name: "munlock", value: 150)
!502 = !DIEnumerator(name: "mlockall", value: 151)
!503 = !DIEnumerator(name: "munlockall", value: 152)
!504 = !DIEnumerator(name: "vhangup", value: 153)
!505 = !DIEnumerator(name: "modify_ldt", value: 154)
!506 = !DIEnumerator(name: "pivot_root", value: 155)
!507 = !DIEnumerator(name: "_sysctl", value: 156)
!508 = !DIEnumerator(name: "prctl", value: 157)
!509 = !DIEnumerator(name: "arch_prctl", value: 158)
!510 = !DIEnumerator(name: "adjtimex", value: 159)
!511 = !DIEnumerator(name: "setrlimit", value: 160)
!512 = !DIEnumerator(name: "chroot", value: 161)
!513 = !DIEnumerator(name: "sync", value: 162)
!514 = !DIEnumerator(name: "acct", value: 163)
!515 = !DIEnumerator(name: "settimeofday", value: 164)
!516 = !DIEnumerator(name: "mount", value: 165)
!517 = !DIEnumerator(name: "umount2", value: 166)
!518 = !DIEnumerator(name: "swapon", value: 167)
!519 = !DIEnumerator(name: "swapoff", value: 168)
!520 = !DIEnumerator(name: "reboot", value: 169)
!521 = !DIEnumerator(name: "sethostname", value: 170)
!522 = !DIEnumerator(name: "setdomainname", value: 171)
!523 = !DIEnumerator(name: "iopl", value: 172)
!524 = !DIEnumerator(name: "ioperm", value: 173)
!525 = !DIEnumerator(name: "create_module", value: 174)
!526 = !DIEnumerator(name: "init_module", value: 175)
!527 = !DIEnumerator(name: "delete_module", value: 176)
!528 = !DIEnumerator(name: "get_kernel_syms", value: 177)
!529 = !DIEnumerator(name: "query_module", value: 178)
!530 = !DIEnumerator(name: "quotactl", value: 179)
!531 = !DIEnumerator(name: "nfsservctl", value: 180)
!532 = !DIEnumerator(name: "getpmsg", value: 181)
!533 = !DIEnumerator(name: "putpmsg", value: 182)
!534 = !DIEnumerator(name: "afs_syscall", value: 183)
!535 = !DIEnumerator(name: "tuxcall", value: 184)
!536 = !DIEnumerator(name: "security", value: 185)
!537 = !DIEnumerator(name: "gettid", value: 186)
!538 = !DIEnumerator(name: "readahead", value: 187)
!539 = !DIEnumerator(name: "setxattr", value: 188)
!540 = !DIEnumerator(name: "lsetxattr", value: 189)
!541 = !DIEnumerator(name: "fsetxattr", value: 190)
!542 = !DIEnumerator(name: "getxattr", value: 191)
!543 = !DIEnumerator(name: "lgetxattr", value: 192)
!544 = !DIEnumerator(name: "fgetxattr", value: 193)
!545 = !DIEnumerator(name: "listxattr", value: 194)
!546 = !DIEnumerator(name: "llistxattr", value: 195)
!547 = !DIEnumerator(name: "flistxattr", value: 196)
!548 = !DIEnumerator(name: "removexattr", value: 197)
!549 = !DIEnumerator(name: "lremovexattr", value: 198)
!550 = !DIEnumerator(name: "fremovexattr", value: 199)
!551 = !DIEnumerator(name: "tkill", value: 200)
!552 = !DIEnumerator(name: "time", value: 201)
!553 = !DIEnumerator(name: "futex", value: 202)
!554 = !DIEnumerator(name: "sched_setaffinity", value: 203)
!555 = !DIEnumerator(name: "sched_getaffinity", value: 204)
!556 = !DIEnumerator(name: "set_thread_area", value: 205)
!557 = !DIEnumerator(name: "io_setup", value: 206)
!558 = !DIEnumerator(name: "io_destroy", value: 207)
!559 = !DIEnumerator(name: "io_getevents", value: 208)
!560 = !DIEnumerator(name: "io_submit", value: 209)
!561 = !DIEnumerator(name: "io_cancel", value: 210)
!562 = !DIEnumerator(name: "get_thread_area", value: 211)
!563 = !DIEnumerator(name: "lookup_dcookie", value: 212)
!564 = !DIEnumerator(name: "epoll_create", value: 213)
!565 = !DIEnumerator(name: "epoll_ctl_old", value: 214)
!566 = !DIEnumerator(name: "epoll_wait_old", value: 215)
!567 = !DIEnumerator(name: "remap_file_pages", value: 216)
!568 = !DIEnumerator(name: "getdents64", value: 217)
!569 = !DIEnumerator(name: "set_tid_address", value: 218)
!570 = !DIEnumerator(name: "restart_syscall", value: 219)
!571 = !DIEnumerator(name: "semtimedop", value: 220)
!572 = !DIEnumerator(name: "fadvise64", value: 221)
!573 = !DIEnumerator(name: "timer_create", value: 222)
!574 = !DIEnumerator(name: "timer_settime", value: 223)
!575 = !DIEnumerator(name: "timer_gettime", value: 224)
!576 = !DIEnumerator(name: "timer_getoverrun", value: 225)
!577 = !DIEnumerator(name: "timer_delete", value: 226)
!578 = !DIEnumerator(name: "clock_settime", value: 227)
!579 = !DIEnumerator(name: "clock_gettime", value: 228)
!580 = !DIEnumerator(name: "clock_getres", value: 229)
!581 = !DIEnumerator(name: "clock_nanosleep", value: 230)
!582 = !DIEnumerator(name: "exit_group", value: 231)
!583 = !DIEnumerator(name: "epoll_wait", value: 232)
!584 = !DIEnumerator(name: "epoll_ctl", value: 233)
!585 = !DIEnumerator(name: "tgkill", value: 234)
!586 = !DIEnumerator(name: "utimes", value: 235)
!587 = !DIEnumerator(name: "vserver", value: 236)
!588 = !DIEnumerator(name: "mbind", value: 237)
!589 = !DIEnumerator(name: "set_mempolicy", value: 238)
!590 = !DIEnumerator(name: "get_mempolicy", value: 239)
!591 = !DIEnumerator(name: "mq_open", value: 240)
!592 = !DIEnumerator(name: "mq_unlink", value: 241)
!593 = !DIEnumerator(name: "mq_timedsend", value: 242)
!594 = !DIEnumerator(name: "mq_timedreceive", value: 243)
!595 = !DIEnumerator(name: "mq_notify", value: 244)
!596 = !DIEnumerator(name: "mq_getsetattr", value: 245)
!597 = !DIEnumerator(name: "kexec_load", value: 246)
!598 = !DIEnumerator(name: "waitid", value: 247)
!599 = !DIEnumerator(name: "add_key", value: 248)
!600 = !DIEnumerator(name: "request_key", value: 249)
!601 = !DIEnumerator(name: "keyctl", value: 250)
!602 = !DIEnumerator(name: "ioprio_set", value: 251)
!603 = !DIEnumerator(name: "ioprio_get", value: 252)
!604 = !DIEnumerator(name: "inotify_init", value: 253)
!605 = !DIEnumerator(name: "inotify_add_watch", value: 254)
!606 = !DIEnumerator(name: "inotify_rm_watch", value: 255)
!607 = !DIEnumerator(name: "migrate_pages", value: 256)
!608 = !DIEnumerator(name: "openat", value: 257)
!609 = !DIEnumerator(name: "mkdirat", value: 258)
!610 = !DIEnumerator(name: "mknodat", value: 259)
!611 = !DIEnumerator(name: "fchownat", value: 260)
!612 = !DIEnumerator(name: "futimesat", value: 261)
!613 = !DIEnumerator(name: "newfstatat", value: 262)
!614 = !DIEnumerator(name: "fstatat", value: 262)
!615 = !DIEnumerator(name: "unlinkat", value: 263)
!616 = !DIEnumerator(name: "renameat", value: 264)
!617 = !DIEnumerator(name: "linkat", value: 265)
!618 = !DIEnumerator(name: "symlinkat", value: 266)
!619 = !DIEnumerator(name: "readlinkat", value: 267)
!620 = !DIEnumerator(name: "fchmodat", value: 268)
!621 = !DIEnumerator(name: "faccessat", value: 269)
!622 = !DIEnumerator(name: "pselect6", value: 270)
!623 = !DIEnumerator(name: "ppoll", value: 271)
!624 = !DIEnumerator(name: "unshare", value: 272)
!625 = !DIEnumerator(name: "set_robust_list", value: 273)
!626 = !DIEnumerator(name: "get_robust_list", value: 274)
!627 = !DIEnumerator(name: "splice", value: 275)
!628 = !DIEnumerator(name: "tee", value: 276)
!629 = !DIEnumerator(name: "sync_file_range", value: 277)
!630 = !DIEnumerator(name: "vmsplice", value: 278)
!631 = !DIEnumerator(name: "move_pages", value: 279)
!632 = !DIEnumerator(name: "utimensat", value: 280)
!633 = !DIEnumerator(name: "epoll_pwait", value: 281)
!634 = !DIEnumerator(name: "signalfd", value: 282)
!635 = !DIEnumerator(name: "timerfd_create", value: 283)
!636 = !DIEnumerator(name: "eventfd", value: 284)
!637 = !DIEnumerator(name: "fallocate", value: 285)
!638 = !DIEnumerator(name: "timerfd_settime", value: 286)
!639 = !DIEnumerator(name: "timerfd_gettime", value: 287)
!640 = !DIEnumerator(name: "accept4", value: 288)
!641 = !DIEnumerator(name: "signalfd4", value: 289)
!642 = !DIEnumerator(name: "eventfd2", value: 290)
!643 = !DIEnumerator(name: "epoll_create1", value: 291)
!644 = !DIEnumerator(name: "dup3", value: 292)
!645 = !DIEnumerator(name: "pipe2", value: 293)
!646 = !DIEnumerator(name: "inotify_init1", value: 294)
!647 = !DIEnumerator(name: "preadv", value: 295)
!648 = !DIEnumerator(name: "pwritev", value: 296)
!649 = !DIEnumerator(name: "rt_tgsigqueueinfo", value: 297)
!650 = !DIEnumerator(name: "perf_event_open", value: 298)
!651 = !DIEnumerator(name: "recvmmsg", value: 299)
!652 = !DIEnumerator(name: "fanotify_init", value: 300)
!653 = !DIEnumerator(name: "fanotify_mark", value: 301)
!654 = !DIEnumerator(name: "prlimit64", value: 302)
!655 = !DIEnumerator(name: "name_to_handle_at", value: 303)
!656 = !DIEnumerator(name: "open_by_handle_at", value: 304)
!657 = !DIEnumerator(name: "clock_adjtime", value: 305)
!658 = !DIEnumerator(name: "syncfs", value: 306)
!659 = !DIEnumerator(name: "sendmmsg", value: 307)
!660 = !DIEnumerator(name: "setns", value: 308)
!661 = !DIEnumerator(name: "getcpu", value: 309)
!662 = !DIEnumerator(name: "process_vm_readv", value: 310)
!663 = !DIEnumerator(name: "process_vm_writev", value: 311)
!664 = !DIEnumerator(name: "kcmp", value: 312)
!665 = !DIEnumerator(name: "finit_module", value: 313)
!666 = !DIEnumerator(name: "sched_setattr", value: 314)
!667 = !DIEnumerator(name: "sched_getattr", value: 315)
!668 = !DIEnumerator(name: "renameat2", value: 316)
!669 = !DIEnumerator(name: "seccomp", value: 317)
!670 = !DIEnumerator(name: "getrandom", value: 318)
!671 = !DIEnumerator(name: "memfd_create", value: 319)
!672 = !DIEnumerator(name: "kexec_file_load", value: 320)
!673 = !DIEnumerator(name: "bpf", value: 321)
!674 = !DIEnumerator(name: "execveat", value: 322)
!675 = !DIEnumerator(name: "userfaultfd", value: 323)
!676 = !DIEnumerator(name: "membarrier", value: 324)
!677 = !DIEnumerator(name: "mlock2", value: 325)
!678 = !DIEnumerator(name: "copy_file_range", value: 326)
!679 = !DIEnumerator(name: "preadv2", value: 327)
!680 = !DIEnumerator(name: "pwritev2", value: 328)
!681 = !DIEnumerator(name: "pkey_mprotect", value: 329)
!682 = !DIEnumerator(name: "pkey_alloc", value: 330)
!683 = !DIEnumerator(name: "pkey_free", value: 331)
!684 = !DIEnumerator(name: "statx", value: 332)
!685 = !DIEnumerator(name: "io_pgetevents", value: 333)
!686 = !DIEnumerator(name: "rseq", value: 334)
!687 = !DIEnumerator(name: "pidfd_send_signal", value: 424)
!688 = !DIEnumerator(name: "io_uring_setup", value: 425)
!689 = !DIEnumerator(name: "io_uring_enter", value: 426)
!690 = !DIEnumerator(name: "io_uring_register", value: 427)
!691 = !DIEnumerator(name: "open_tree", value: 428)
!692 = !DIEnumerator(name: "move_mount", value: 429)
!693 = !DIEnumerator(name: "fsopen", value: 430)
!694 = !DIEnumerator(name: "fsconfig", value: 431)
!695 = !DIEnumerator(name: "fsmount", value: 432)
!696 = !DIEnumerator(name: "fspick", value: 433)
!697 = !DIEnumerator(name: "pidfd_open", value: 434)
!698 = !DIEnumerator(name: "clone3", value: 435)
!699 = !DIEnumerator(name: "openat2", value: 437)
!700 = !DIEnumerator(name: "pidfd_getfd", value: 438)
%0 = alloca %"struct:96:29", align 8
%old.sroa.2.0.sroa_cast = bitcast i8* %old.sroa.2 to i1*
store i1 true, i1* %old.sroa.2.0.sroa_cast, align 8
%result.sroa.0.0..sroa_cast = bitcast %"struct:96:29"* %0 to i64*
store i64 or (i64 shl (i64 zext (i56 trunc (i64 lshr (i64 ptrtoint ([20 x i8]* @0 to i64), i64 8) to i56) to i64), i64 8), i64 zext (i8 ptrtoint ([20 x i8]* @0 to i8) to i64)), i64* %result.sroa.0.0..sroa_cast, align 8
; This is where the `len` parameter is smashed
%result.sroa.6.0..sroa_idx21 = getelementptr inbounds %"struct:96:29", %"struct:96:29"* %0, i64 0, i32 0, i32 1
%result.sroa.6.0..sroa_cast = bitcast i64* %result.sroa.6.0..sroa_idx21 to i1*
store i1 true, i1* %result.sroa.6.0..sroa_cast, align 8
; ..snip..
%7 = bitcast %"struct:96:29"* %0 to %"[]u8"*
call void @llvm.memset.p0i8.i64(i8* nonnull align 8 dereferenceable(32) %4, i8 0, i64 32, i1 false) #7
; This is where things go south, the ptr part of the slice is fine while the length becomes 1
%8 = call fastcc i16 @std.fmt.formatType(%"[]u8"* %7, %std.fmt.FormatOptions* %options.i.i.i, %"std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)"* %stderr.i) #7
Having someone from the LLVM team confirm this hypotesis and have a look would be helpful.
0.9.0 milestone, haha, ouch.
LemonBoy are you saying that this is an LLVM bug, not a Zig compiler bug?
0.9.0 milestone, haha, ouch.
LemonBoy are you saying that this is an LLVM bug, not a Zig compiler bug?
It really sounds like one, you can (hopefully) work around it by making is_weak a u8.
You're right, my project is "fixed" by changing that field from a bool to a u8. It doesn't give me a lot of confidence though.
Do you think the problem is specific to boolean struct fields getting returned through (possibly multiple layers of) result locations?
Do you think the problem is specific to boolean struct fields getting returned through (possibly multiple layers of) result locations?
Hard to tell, the problem disappears if you touch any part of it. You've managed to line-up all the pieces in perfect order to let the over-eager optimization pass kick in.
Hard to tell, the problem disappears if you touch any part of it. You've managed to line-up all the pieces in perfect order to let the over-eager optimization pass kick in.

Good news (?), I've managed to pin-point the bad code generation to an unfortunate interaction between the inliner pass and the SROA one. The bad news is that I don't have enough time to dig into the pass implementation, it's better to punt this bug to the LLVM developers.
Here's a nice not-so-reduced test case, I've already run it trough opt -inline.
You can observe the bug by running:
opt-11 -sroa <.ll file> | lli-11 # The output is corrupted
lli-11 <.ll file> # The output is fine
I managed to shrink the test case down to ~200LoC (from ~7k), this is now ready to be reported upstream (@andrewrk can you open a ticket for this?).
LLVM IR source:
; ModuleID = '/tmp/foo.inl.ll'
source_filename = "foo"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
%CallArg = type { %Expression }
%Expression = type { %EnumLiteral, i1 }
%EnumLiteral = type { %"[]u8" }
%"[]u8" = type { i8*, i64 }
%ExpressionResult = type { %TempRef, i2 }
%TempRef = type { i64, i1 }
%"struct:78:50" = type { %"[]u8" }
%"struct:132:52" = type { %"[]u8" }
@0 = internal unnamed_addr constant [20 x i8] c"what happened to me\00", align 1
@1 = internal unnamed_addr constant %CallArg { %Expression { %EnumLiteral { %"[]u8" { i8* getelementptr inbounds ([20 x i8], [20 x i8]* @0, i64 0, i64 0), i64 19 } }, i1 true } }, align 8
; Function Attrs: argmemonly nofree nosync nounwind willreturn
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #0
; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
declare { i64, i1 } @llvm.uadd.with.overflow.i64(i64, i64) #1
; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
declare { i64, i1 } @llvm.ssub.with.overflow.i64(i64, i64) #1
define internal fastcc void @main() unnamed_addr {
Entry:
%v.i = alloca %EnumLiteral, align 8
%result.i = alloca %ExpressionResult, align 8
%w.i = alloca %"[]u8", align 8
%0 = alloca %"struct:78:50", align 8
%arg = alloca %CallArg, align 8
%result = alloca %ExpressionResult, align 8
%w = alloca %"[]u8", align 8
%1 = alloca %"struct:132:52", align 8
%derp = alloca %ExpressionResult, align 8
%2 = bitcast %CallArg* %arg to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* bitcast (%CallArg* @1 to i8*), i64 24, i1 false)
%3 = getelementptr inbounds %CallArg, %CallArg* %arg, i32 0, i32 0
%4 = getelementptr inbounds %Expression, %Expression* %3, i32 0, i32 1
%5 = load i1, i1* %4, align 1
switch i1 %5, label %SwitchElse3.i [
i1 true, label %SwitchProng1.i
]
SwitchProng1.i: ; preds = %Entry
%6 = getelementptr inbounds %Expression, %Expression* %3, i32 0, i32 0
%7 = bitcast %EnumLiteral* %6 to i8*
%8 = bitcast %EnumLiteral* %v.i to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %8, i8* %7, i64 16, i1 false)
%9 = getelementptr inbounds %ExpressionResult, %ExpressionResult* %result.i, i32 0, i32 1
store i2 -2, i2* %9, align 1
%10 = getelementptr inbounds %ExpressionResult, %ExpressionResult* %result.i, i32 0, i32 0
%11 = bitcast %TempRef* %10 to %"[]u8"*
%12 = getelementptr inbounds %EnumLiteral, %EnumLiteral* %v.i, i32 0, i32 0
%13 = bitcast %"[]u8"* %12 to i8*
%14 = bitcast %"[]u8"* %11 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %14, i8* %13, i64 16, i1 false)
br label %SwitchProng2.i
SwitchProng2.i: ; preds = %SwitchProng1.i
%15 = getelementptr inbounds %ExpressionResult, %ExpressionResult* %result.i, i32 0, i32 0
%16 = bitcast %TempRef* %15 to %"[]u8"*
%17 = bitcast %"[]u8"* %16 to i8*
%18 = bitcast %"[]u8"* %w.i to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %18, i8* %17, i64 16, i1 false)
%19 = getelementptr inbounds %"struct:78:50", %"struct:78:50"* %0, i32 0, i32 0
%20 = bitcast %"[]u8"* %w.i to i8*
%21 = bitcast %"[]u8"* %19 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %21, i8* %20, i64 16, i1 false)
%22 = getelementptr inbounds %"struct:78:50", %"struct:78:50"* %0, i32 0, i32 0
call fastcc void @std.os.write(i32 1, %"[]u8"* %22)
br label %ErrRetContinue.i.i.i
ErrRetContinue.i.i.i: ; preds = %SwitchProng2.i
br label %f.exit.i.i
f.exit.i.i: ; preds = %ErrRetContinue.i.i.i
br label %UnwrapErrError.i.i
UnwrapErrError.i.i: ; preds = %f.exit.i.i
br label %print.18.exit.i
print.18.exit.i: ; preds = %UnwrapErrError.i.i
br label %SwitchEnd.i
SwitchEnd.i: ; preds = %print.18.exit.i
%23 = bitcast %ExpressionResult* %result.i to i8*
%24 = bitcast %ExpressionResult* %result to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %24, i8* %23, i64 24, i1 false)
br label %genExpression.exit
SwitchElse3.i: ; preds = %Entry
ret void
genExpression.exit: ; preds = %SwitchEnd.i
%25 = getelementptr inbounds %ExpressionResult, %ExpressionResult* %result, i32 0, i32 1
%26 = load i2, i2* %25, align 1
switch i2 %26, label %SwitchElse [
i2 -2, label %SwitchProng
]
SwitchElse: ; preds = %genExpression.exit
ret void
SwitchProng: ; preds = %genExpression.exit
%27 = getelementptr inbounds %ExpressionResult, %ExpressionResult* %result, i32 0, i32 0
%28 = bitcast %TempRef* %27 to %"[]u8"*
%29 = bitcast %"[]u8"* %28 to i8*
%30 = bitcast %"[]u8"* %w to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %30, i8* %29, i64 16, i1 false)
%31 = getelementptr inbounds %"struct:132:52", %"struct:132:52"* %1, i32 0, i32 0
%32 = bitcast %"[]u8"* %w to i8*
%33 = bitcast %"[]u8"* %31 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %33, i8* %32, i64 16, i1 false)
%34 = getelementptr inbounds %"struct:132:52", %"struct:132:52"* %1, i32 0, i32 0
call fastcc void @std.os.write(i32 1, %"[]u8"* %34)
ret void
SwitchProng1.i3: ; No predecessors!
%35 = getelementptr inbounds %ExpressionResult, %ExpressionResult* %derp, i32 0, i32 0
%36 = getelementptr inbounds %TempRef, %TempRef* %35, i32 0, i32 1
store i1 false, i1* %36, align 1
ret void
SwitchProng2.i4: ; No predecessors!
%37 = bitcast %ExpressionResult* %result to i8*
%38 = bitcast %ExpressionResult* %derp to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %38, i8* %37, i64 24, i1 false)
ret void
}
define internal fastcc void @std.os.write(i32 %0, %"[]u8"* %1) unnamed_addr {
Entry:
%result.i8 = alloca i64, align 8
%y.i = alloca i64, align 8
%number.i.i = alloca i64, align 8
%arg2.i.i = alloca i64, align 8
%arg3.i.i = alloca i64, align 8
%buf.i = alloca i8*, align 8
%count.i = alloca i64, align 8
%adjusted_len = alloca i64, align 8
%2 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 1
%3 = load i64, i64* %2, align 8
store i64 %3, i64* %y.i, align 8
br label %Else.i10
Else.i10: ; preds = %Entry
%4 = load i64, i64* %y.i, align 8
store i64 %4, i64* %result.i8, align 8
%5 = load i64, i64* %result.i8, align 8
br label %std.math.min.exit
std.math.min.exit: ; preds = %Else.i10
store i64 %5, i64* %adjusted_len, align 8
br label %WhileCond
WhileCond: ; preds = %std.math.min.exit
br label %WhileBody
WhileBody: ; preds = %WhileCond
%6 = getelementptr inbounds %"[]u8", %"[]u8"* %1, i32 0, i32 0
%7 = load i8*, i8** %6, align 8
%8 = load i64, i64* %adjusted_len, align 8
store i8* %7, i8** %buf.i, align 8
store i64 %8, i64* %count.i, align 8
%9 = load i8*, i8** %buf.i, align 8
%10 = ptrtoint i8* %9 to i64
%11 = load i64, i64* %count.i, align 8
store i64 1, i64* %number.i.i, align 8
store i64 %10, i64* %arg2.i.i, align 8
store i64 %11, i64* %arg3.i.i, align 8
%12 = load i64, i64* %number.i.i, align 8
%13 = load i64, i64* %arg2.i.i, align 8
%14 = load i64, i64* %arg3.i.i, align 8
%15 = call i64 asm sideeffect "syscall", "={rax},{rax},{rdi},{rsi},{rdx},~{rcx},~{r11},~{memory},~{dirflag},~{fpsr},~{flags}"(i64 %12, i64 undef, i64 %13, i64 %14)
ret void
}
attributes #0 = { argmemonly nofree nosync nounwind willreturn }
attributes #1 = { nofree nosync nounwind readnone speculatable willreturn }
The different behaviour can be observed by running
opt-11 -sroa <.ll file> | lli-11 # The output is corrupted
lli-11 <.ll file> # The output is fine
I managed to shrink the test case down to ~200LoC (from ~7k), this is now ready to be reported upstream (@andrewrk can you open a ticket for this?).
LLVM IR source:
<...>
This is either over-reduced, or the original IR is already broken, because alive2 says that the transformation is valid:
$ /repositories/alive2/build-Clang-release/alive-tv input.ll output.ll
----------------------------------------
@1 = constant 24 bytes, align 8
@0 = constant 20 bytes, align 1
define void @main() {
#init:
%__constexpr_1 = gep inbounds * @0, 20 x i64 0, 1 x i64 0
%__copy_0 = {*, i64} { %__constexpr_1, 19 }
%__copy_1 = {{*, i64}} { %__copy_0 }
%__copy_2 = {{{*, i64}}, i1, i56} { %__copy_1, 1, [padding] }
%__copy_3 = {{{{*, i64}}, i1, i56}} { %__copy_2 }
store [20 x i8] { 119, 104, 97, 116, 32, 104, 97, 112, 112, 101, 110, 101, 100, 32, 116, 111, 32, 109, 101, 0 }, * @0, align 1
store {{{{*, i64}}, i1, i56}} %__copy_3, * @1, align 8
br label %Entry
%Entry:
%v.i = alloca i64 16, align 8
%result.i = alloca i64 24, align 8
%w.i = alloca i64 16, align 8
%0 = alloca i64 16, align 8
%arg = alloca i64 24, align 8
%result = alloca i64 24, align 8
%w = alloca i64 16, align 8
%1 = alloca i64 16, align 8
%derp = alloca i64 24, align 8
%2 = bitcast * %arg to *
%__constexpr_0 = bitcast * @1 to *
memcpy * %2 align 1, * %__constexpr_0 align 1, i64 24
%3 = gep inbounds * %arg, 24 x i32 0, 1 x i64 0
%4 = gep inbounds * %3, 24 x i32 0, 1 x i64 16
%5 = load i1, * %4, align 1
switch i1 %5, label %SwitchElse3.i [
i1 1, label %SwitchProng1.i
]
%SwitchProng1.i:
%10 = gep inbounds * %3, 24 x i32 0, 1 x i64 0
%11 = bitcast * %10 to *
%12 = bitcast * %v.i to *
memcpy * %12 align 1, * %11 align 1, i64 16
%13 = gep inbounds * %result.i, 24 x i32 0, 1 x i64 16
store i2 2, * %13, align 1
%14 = gep inbounds * %result.i, 24 x i32 0, 1 x i64 0
%15 = bitcast * %14 to *
%16 = gep inbounds * %v.i, 16 x i32 0, 1 x i64 0
%17 = bitcast * %16 to *
%18 = bitcast * %15 to *
memcpy * %18 align 1, * %17 align 1, i64 16
br label %SwitchProng2.i
%SwitchProng2.i:
%19 = gep inbounds * %result.i, 24 x i32 0, 1 x i64 0
%20 = bitcast * %19 to *
%21 = bitcast * %20 to *
%22 = bitcast * %w.i to *
memcpy * %22 align 1, * %21 align 1, i64 16
%23 = gep inbounds * %0, 16 x i32 0, 1 x i64 0
%24 = bitcast * %w.i to *
%25 = bitcast * %23 to *
memcpy * %25 align 1, * %24 align 1, i64 16
%26 = gep inbounds * %0, 16 x i32 0, 1 x i64 0
call void @std.os.write(i32 1, * %26)
br label %ErrRetContinue.i.i.i
%ErrRetContinue.i.i.i:
br label %f.exit.i.i
%f.exit.i.i:
br label %UnwrapErrError.i.i
%UnwrapErrError.i.i:
br label %print.18.exit.i
%print.18.exit.i:
br label %SwitchEnd.i
%SwitchEnd.i:
%27 = bitcast * %result.i to *
%28 = bitcast * %result to *
memcpy * %28 align 1, * %27 align 1, i64 24
br label %genExpression.exit
%genExpression.exit:
%29 = gep inbounds * %result, 24 x i32 0, 1 x i64 16
%30 = load i2, * %29, align 1
switch i2 %30, label %SwitchElse [
i2 2, label %SwitchProng
]
%SwitchElse:
ret void
%SwitchProng:
%31 = gep inbounds * %result, 24 x i32 0, 1 x i64 0
%32 = bitcast * %31 to *
%33 = bitcast * %32 to *
%34 = bitcast * %w to *
memcpy * %34 align 1, * %33 align 1, i64 16
%35 = gep inbounds * %1, 16 x i32 0, 1 x i64 0
%36 = bitcast * %w to *
%37 = bitcast * %35 to *
memcpy * %37 align 1, * %36 align 1, i64 16
%38 = gep inbounds * %1, 16 x i32 0, 1 x i64 0
call void @std.os.write(i32 1, * %38)
ret void
%SwitchElse3.i:
ret void
}
=>
@1 = constant 24 bytes, align 8
@0 = constant 20 bytes, align 1
define void @main() {
#init:
%__constexpr_8 = gep inbounds * @0, 20 x i64 0, 1 x i64 0
%__copy_0 = {*, i64} { %__constexpr_8, 19 }
%__copy_1 = {{*, i64}} { %__copy_0 }
%__copy_2 = {{{*, i64}}, i1, i56} { %__copy_1, 1, [padding] }
%__copy_3 = {{{{*, i64}}, i1, i56}} { %__copy_2 }
store [20 x i8] { 119, 104, 97, 116, 32, 104, 97, 112, 112, 101, 110, 101, 100, 32, 116, 111, 32, 109, 101, 0 }, * @0, align 1
store {{{{*, i64}}, i1, i56}} %__copy_3, * @1, align 8
br label %Entry
%Entry:
%v.i.sroa.2 = alloca i64 1, align 8
%v.i.sroa.3 = alloca i64 7, align 1
%result.i.sroa.4 = alloca i64 7, align 1
%result.i.sroa.7 = alloca i64 7, align 1
%w.i.sroa.2 = alloca i64 1, align 8
%w.i.sroa.3 = alloca i64 7, align 1
%0 = alloca i64 16, align 8
%arg.sroa.0.sroa.3 = alloca i64 7, align 1
%arg.sroa.3 = alloca i64 7, align 1
%result.sroa.4 = alloca i64 7, align 1
%result.sroa.6 = alloca i64 7, align 1
%w.sroa.2 = alloca i64 1, align 8
%w.sroa.3 = alloca i64 7, align 1
%1 = alloca i64 16, align 8
%derp.sroa.2.sroa.0 = alloca i64 7, align 1
%derp.sroa.2.sroa.1 = alloca i64 1, align 1
%derp.sroa.2.sroa.2 = alloca i64 7, align 1
%__constexpr_0 = bitcast * @1 to *
%arg.sroa.0.sroa.0.0.copyload = load i64, * %__constexpr_0, align 1
%__constexpr_2 = gep inbounds * @1, 24 x i64 0, 1 x i64 0, 1 x i64 0, 1 x i64 0, 1 x i64 8
%__constexpr_1 = bitcast * %__constexpr_2 to *
%arg.sroa.0.sroa.2.0.copyload = load i8, * %__constexpr_1, align 1
%arg.sroa.0.sroa.3.0..sroa_idx = gep inbounds * %arg.sroa.0.sroa.3, 7 x i64 0, 1 x i64 0
%__constexpr_4 = bitcast * @1 to *
%__constexpr_3 = gep inbounds * %__constexpr_4, 1 x i64 9
memcpy * %arg.sroa.0.sroa.3.0..sroa_idx align 1, * %__constexpr_3 align 1, i64 7
%__constexpr_5 = gep inbounds * @1, 24 x i64 0, 1 x i64 0, 1 x i64 16
%arg.sroa.2.0.copyload = load i1, * %__constexpr_5, align 1
%arg.sroa.3.0..sroa_idx = gep inbounds * %arg.sroa.3, 7 x i64 0, 1 x i64 0
%__constexpr_7 = bitcast * @1 to *
%__constexpr_6 = gep inbounds * %__constexpr_7, 1 x i64 17
memcpy * %arg.sroa.3.0..sroa_idx align 1, * %__constexpr_6 align 1, i64 7
switch i1 %arg.sroa.2.0.copyload, label %SwitchElse3.i [
i1 1, label %SwitchProng1.i
]
%SwitchProng1.i:
store i8 %arg.sroa.0.sroa.2.0.copyload, * %v.i.sroa.2, align 8
%arg.sroa.0.sroa.3.9.v.i.sroa.3.0..sroa_idx.sroa_idx = gep inbounds * %v.i.sroa.3, 7 x i64 0, 1 x i64 0
%arg.sroa.0.sroa.3.9..sroa_idx = gep inbounds * %arg.sroa.0.sroa.3, 7 x i64 0, 1 x i64 0
memcpy * %arg.sroa.0.sroa.3.9.v.i.sroa.3.0..sroa_idx.sroa_idx align 1, * %arg.sroa.0.sroa.3.9..sroa_idx align 1, i64 7
%v.i.sroa.2.0..sroa_cast = bitcast * %v.i.sroa.2 to *
%v.i.sroa.2.0.v.i.sroa.2.8.result.i.sroa.3.0.copyload = load i1, * %v.i.sroa.2.0..sroa_cast, align 8
%v.i.sroa.3.9.result.i.sroa.4.0..sroa_idx.sroa_idx = gep inbounds * %result.i.sroa.4, 7 x i64 0, 1 x i64 0
%v.i.sroa.3.9..sroa_idx = gep inbounds * %v.i.sroa.3, 7 x i64 0, 1 x i64 0
memcpy * %v.i.sroa.3.9.result.i.sroa.4.0..sroa_idx.sroa_idx align 1, * %v.i.sroa.3.9..sroa_idx align 1, i64 7
br label %SwitchProng2.i
%SwitchProng2.i:
%w.i.sroa.2.0..sroa_cast22 = bitcast * %w.i.sroa.2 to *
store i1 %v.i.sroa.2.0.v.i.sroa.2.8.result.i.sroa.3.0.copyload, * %w.i.sroa.2.0..sroa_cast22, align 8
%w.i.sroa.3.9.result.i.sroa.4.0..sroa_idx21.sroa_idx = gep inbounds * %result.i.sroa.4, 7 x i64 0, 1 x i64 0
%w.i.sroa.3.9..sroa_idx = gep inbounds * %w.i.sroa.3, 7 x i64 0, 1 x i64 0
memcpy * %w.i.sroa.3.9..sroa_idx align 1, * %w.i.sroa.3.9.result.i.sroa.4.0..sroa_idx21.sroa_idx align 1, i64 7
%w.i.sroa.0.0..sroa_cast = bitcast * %0 to *
store i64 %arg.sroa.0.sroa.0.0.copyload, * %w.i.sroa.0.0..sroa_cast, align 1
%w.i.sroa.2.0..sroa_idx = gep inbounds * %0, 16 x i64 0, 1 x i64 0, 1 x i64 8
%w.i.sroa.2.0..sroa_cast = bitcast * %w.i.sroa.2.0..sroa_idx to *
%w.i.sroa.2.0.w.i.sroa.2.0.copyload = load i8, * %w.i.sroa.2, align 8
store i8 %w.i.sroa.2.0.w.i.sroa.2.0.copyload, * %w.i.sroa.2.0..sroa_cast, align 1
%w.i.sroa.3.0..sroa_raw_cast = bitcast * %0 to *
%w.i.sroa.3.0..sroa_raw_idx = gep inbounds * %w.i.sroa.3.0..sroa_raw_cast, 1 x i64 9
%w.i.sroa.3.0..sroa_idx = gep inbounds * %w.i.sroa.3, 7 x i64 0, 1 x i64 0
memcpy * %w.i.sroa.3.0..sroa_raw_idx align 1, * %w.i.sroa.3.0..sroa_idx align 1, i64 7
%2 = gep inbounds * %0, 16 x i32 0, 1 x i64 0
call void @std.os.write(i32 1, * %2)
br label %ErrRetContinue.i.i.i
%ErrRetContinue.i.i.i:
br label %f.exit.i.i
%f.exit.i.i:
br label %UnwrapErrError.i.i
%UnwrapErrError.i.i:
br label %print.18.exit.i
%print.18.exit.i:
br label %SwitchEnd.i
%SwitchEnd.i:
%result.i.sroa.4.9.result.sroa.4.0..sroa_idx.sroa_idx = gep inbounds * %result.sroa.4, 7 x i64 0, 1 x i64 0
%result.i.sroa.4.9..sroa_idx = gep inbounds * %result.i.sroa.4, 7 x i64 0, 1 x i64 0
memcpy * %result.i.sroa.4.9.result.sroa.4.0..sroa_idx.sroa_idx align 1, * %result.i.sroa.4.9..sroa_idx align 1, i64 7
%result.i.sroa.7.17.result.sroa.6.0..sroa_idx.sroa_idx = gep inbounds * %result.sroa.6, 7 x i64 0, 1 x i64 0
%result.i.sroa.7.17..sroa_idx = gep inbounds * %result.i.sroa.7, 7 x i64 0, 1 x i64 0
memcpy * %result.i.sroa.7.17.result.sroa.6.0..sroa_idx.sroa_idx align 1, * %result.i.sroa.7.17..sroa_idx align 1, i64 7
br label %genExpression.exit
%genExpression.exit:
switch i2 2, label %SwitchElse [
i2 2, label %SwitchProng
]
%SwitchElse:
ret void
%SwitchProng:
%w.sroa.2.0..sroa_cast10 = bitcast * %w.sroa.2 to *
store i1 %v.i.sroa.2.0.v.i.sroa.2.8.result.i.sroa.3.0.copyload, * %w.sroa.2.0..sroa_cast10, align 8
%w.sroa.3.9.result.sroa.4.0..sroa_idx8.sroa_idx = gep inbounds * %result.sroa.4, 7 x i64 0, 1 x i64 0
%w.sroa.3.9..sroa_idx = gep inbounds * %w.sroa.3, 7 x i64 0, 1 x i64 0
memcpy * %w.sroa.3.9..sroa_idx align 1, * %w.sroa.3.9.result.sroa.4.0..sroa_idx8.sroa_idx align 1, i64 7
%w.sroa.0.0..sroa_cast = bitcast * %1 to *
store i64 %arg.sroa.0.sroa.0.0.copyload, * %w.sroa.0.0..sroa_cast, align 1
%w.sroa.2.0..sroa_idx = gep inbounds * %1, 16 x i64 0, 1 x i64 0, 1 x i64 8
%w.sroa.2.0..sroa_cast = bitcast * %w.sroa.2.0..sroa_idx to *
%w.sroa.2.0.w.sroa.2.0.copyload = load i8, * %w.sroa.2, align 8
store i8 %w.sroa.2.0.w.sroa.2.0.copyload, * %w.sroa.2.0..sroa_cast, align 1
%w.sroa.3.0..sroa_raw_cast = bitcast * %1 to *
%w.sroa.3.0..sroa_raw_idx = gep inbounds * %w.sroa.3.0..sroa_raw_cast, 1 x i64 9
%w.sroa.3.0..sroa_idx = gep inbounds * %w.sroa.3, 7 x i64 0, 1 x i64 0
memcpy * %w.sroa.3.0..sroa_raw_idx align 1, * %w.sroa.3.0..sroa_idx align 1, i64 7
%3 = gep inbounds * %1, 16 x i32 0, 1 x i64 0
call void @std.os.write(i32 1, * %3)
ret void
%SwitchElse3.i:
ret void
}
Transformation seems to be correct!
ERROR: Unsupported instruction: %15 = call i64 asm sideeffect "syscall", "={rax},{rax},{rdi},{rsi},{rdx},~{rcx},~{r11},~{memory},~{dirflag},~{fpsr},~{flags}"(i64 %12, i64 undef, i64 %13, i64 %14)
ERROR: Could not translate 'std.os.write' to Alive IR
Summary:
1 correct transformations
0 incorrect transformations
1 Alive2 errors
Good news (?), I've managed to pin-point the bad code generation to an unfortunate interaction between the inliner pass and the SROA one. The bad news is that I don't have enough time to dig into the pass implementation, it's better to punt this bug to the LLVM developers.
Here's a nice not-so-reduced test case, I've already run it trough
opt -inline.You can observe the bug by running:
opt-11 -sroa <.ll file> | lli-11 # The output is corrupted lli-11 <.ll file> # The output is fine
It is hard to say whether the original input also exibits the same problems, it's pretty big :) With increased timeout limits, alive2 still doesn't pinpoint any miscompiles in it, which usually means that there aren't any, because usually it comes up with them real fast. full-log.txt
Just for completeness, if i disable poison/undef input in alive2, it starts complaining about @std.os.unexpectedErrno:
----------------------------------------
@stderr_mutex = global 1 bytes, align 1
@63 = constant 16 bytes, align 8
@99 = constant 40 bytes, align 8
@101 = constant 16 bytes, align 8
@102 = constant 16 bytes, align 8
@103 = constant 16 bytes, align 8
@104 = constant 16 bytes, align 8
@105 = constant 16 bytes, align 8
@106 = constant 16 bytes, align 8
@86 = constant 40 bytes, align 8
@87 = constant 16 bytes, align 8
@19 = constant 16 bytes, align 8
@100 = constant 22 bytes, align 1
@84 = constant 49 bytes, align 1
@18 = constant 18 bytes, align 1
define i16 @std.os.unexpectedErrno(i64 %0) {
#init:
%__copy_0 = {{i64, i1, i56}, {i64, i1, i56}, i2, {i8, [6 x i8]}} { { undef, 0, [padding] }, { undef, 0, [padding] }, 2, { 32, undef } }
%__copy_3 = {{i64, i1, i56}, {i64, i1, i56}, i2, {i8, [6 x i8]}} { { undef, 0, [padding] }, { undef, 0, [padding] }, 2, { 32, undef } }
store [22 x i8] { 117, 110, 101, 120, 112, 101, 99, 116, 101, 100, 32, 101, 114, 114, 110, 111, 58, 32, 123, 125, 10, 0 }, * @100, align 1
store {i64, i1, i56} { undef, 0, [padding] }, * @102, align 8
store {i64, i1, i56} { undef, 0, [padding] }, * @103, align 8
store {i64, i1, i56} { undef, 0, [padding] }, * @104, align 8
store {i64, i1, i56} { undef, 0, [padding] }, * @105, align 8
store [18 x i8] { 100, 101, 97, 100, 108, 111, 99, 107, 32, 100, 101, 116, 101, 99, 116, 101, 100, 0 }, * @18, align 1
store {{*}, i1, i56} { undef, 0, [padding] }, * @63, align 8
store [49 x i8] { 85, 110, 97, 98, 108, 101, 32, 116, 111, 32, 100, 117, 109, 112, 32, 115, 116, 97, 99, 107, 32, 116, 114, 97, 99, 101, 58, 32, 100, 101, 98, 117, 103, 32, 105, 110, 102, 111, 32, 115, 116, 114, 105, 112, 112, 101, 100, 10, 0 }, * @84, align 1
store {{i64, i1, i56}, {i64, i1, i56}, i2, {i8, [6 x i8]}} %__copy_3, * @86, align 8
store {{i64, i1, i56}, {i64, i1, i56}, i2, {i8, [6 x i8]}} %__copy_0, * @99, align 8
br label %Entry
%Entry:
%result.i.i1.i1 = alloca i64 2, align 2
%options.i.i.i2 = alloca i64 40, align 8
%1 = alloca i64 2, align 2
%result.i.i3 = alloca i64 2, align 2
%2 = alloca i64 4, align 4
%result.i.i.i4 = alloca i64 4, align 4
%3 = alloca i64 4, align 4
%stderr.i5 = alloca i64 4, align 4
%4 = alloca i64 2, align 2
%result.i.i.i.i.i.i = alloca i64 2, align 2
%int_value.i.i.i.i.i.i = alloca i64 8, align 8
%5 = alloca i64 8, align 8
%6 = alloca i64 40, align 8
%7 = alloca i64 4, align 4
%value.i.i.i.i.i.i = alloca i64 8, align 8
%result.i.i.i.i.i = alloca i64 2, align 2
%8 = alloca i64 8, align 8
%9 = alloca i64 40, align 8
%10 = alloca i64 4, align 4
%value.i.i.i.i.i = alloca i64 8, align 8
%result.i.i.i.i = alloca i64 2, align 2
%11 = alloca i64 8, align 8
%12 = alloca i64 40, align 8
%13 = alloca i64 4, align 4
%value.i.i.i.i = alloca i64 8, align 8
%max_depth.i.i.i.i = alloca i64 8, align 8
%result.i.i1.i = alloca i64 2, align 2
%options.i.i.i = alloca i64 40, align 8
%14 = alloca i64 2, align 2
%15 = alloca i64 8, align 8
%16 = alloca i64 40, align 8
%17 = alloca i64 4, align 4
%18 = alloca i64 2, align 2
%19 = alloca i64 2, align 2
%result.i.i = alloca i64 2, align 2
%20 = alloca i64 4, align 4
%21 = alloca i64 8, align 8
%self.i.i.i = alloca i64 8, align 8
%22 = alloca i64 16, align 8
%self.i.i = alloca i64 8, align 8
%result.i.i.i = alloca i64 4, align 4
%held.i = alloca i64 8, align 8
%23 = alloca i64 4, align 4
%stderr.i = alloca i64 4, align 4
%24 = alloca i64 8, align 8
%25 = alloca i64 2, align 2
%result = alloca i64 2, align 2
%26 = alloca i64 8, align 8
%err = alloca i64 8, align 8
store i64 %0, * %err, align 8
%27 = load i64, * %err, align 8
%28 = gep inbounds * %26, 8 x i32 0, 1 x i64 0
store i64 %27, * %28, align 8
store * @stderr_mutex, * %self.i.i, align 8
%36 = load *, * %self.i.i, align 8
store * %36, * %self.i.i.i, align 8
%38 = load *, * %self.i.i.i, align 8
%39 = gep inbounds * %38, 1 x i32 0, 1 x i64 0
%40 = load i1, * %39, align 1
br i1 %40, label %Then.i.i.i, label %Else.i.i.i
%Else.i.i.i:
%41 = load *, * %self.i.i.i, align 8
%42 = gep inbounds * %41, 1 x i32 0, 1 x i64 0
store i1 1, * %42, align 1
%43 = gep inbounds * %22, 16 x i32 0, 1 x i64 8
store i1 1, * %43, align 1
%44 = gep inbounds * %22, 16 x i32 0, 1 x i64 0
%45 = gep inbounds * %44, 8 x i32 0, 1 x i64 0
%46 = load *, * %self.i.i.i, align 8
store * %46, * %45, align 8
%47 = gep inbounds * %22, 16 x i32 0, 1 x i64 8
store i1 1, * %47, align 1
%48 = gep inbounds * %22, 16 x i32 0, 1 x i64 0
%49 = bitcast * %44 to *
%50 = bitcast * %48 to *
memcpy * %50 align 8, * %49 align 8, i64 8
br label %std.mutex.Dummy.tryAcquire.exit.i.i
%Then.i.i.i:
%52 = bitcast * %22 to *
%__constexpr_0 = bitcast * @63 to *
memcpy * %52 align 8, * %__constexpr_0 align 8, i64 16
br label %std.mutex.Dummy.tryAcquire.exit.i.i
%std.mutex.Dummy.tryAcquire.exit.i.i:
%54 = gep inbounds * %22, 16 x i32 0, 1 x i64 8
%55 = load i1, * %54, align 1
br i1 %55, label %std.mutex.Dummy.acquire.exit.i, label %OptionalNull.i.i
%std.mutex.Dummy.acquire.exit.i:
%56 = gep inbounds * %22, 16 x i32 0, 1 x i64 0
%57 = bitcast * %56 to *
%58 = bitcast * %held.i to *
memcpy * %58 align 8, * %57 align 8, i64 8
%61 = gep inbounds * %23, 4 x i32 0, 1 x i64 0
store i32 2, * %result.i.i.i, align 4
%63 = load i32, * %result.i.i.i, align 4
store i32 %63, * %61, align 4
%65 = gep inbounds * %stderr.i, 4 x i32 0, 1 x i64 0
%66 = bitcast * %23 to *
%67 = bitcast * %65 to *
memcpy * %67 align 4, * %66 align 4, i64 4
%68 = bitcast * %26 to *
%69 = bitcast * %24 to *
memcpy * %69 align 8, * %68 align 8, i64 8
%73 = bitcast * %stderr.i to *
%74 = bitcast * %20 to *
memcpy * %74 align 4, * %73 align 4, i64 4
%75 = bitcast * %26 to *
%76 = bitcast * %21 to *
memcpy * %76 align 8, * %75 align 8, i64 8
%85 = bitcast * %options.i.i.i to *
%__constexpr_1 = bitcast * @99 to *
memcpy * %85 align 8, * %__constexpr_1 align 8, i64 40
%86 = call i16 @std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeAll(nonnull align(4) * %stderr.i, nonnull align(8) * @101)
store i16 %86, * %14, align 2
%87 = icmp ne i16 %86, 0
br i1 %87, label %ErrRetReturn.i.i.i, label %ErrRetContinue.i.i.i
%ErrRetReturn.i.i.i:
%88 = load i16, * %14, align 2
store i16 %88, * %result.i.i1.i, align 2
br label %std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print.15.exit.i
%ErrRetContinue.i.i.i:
%97 = gep inbounds * %options.i.i.i, 40 x i32 0, 1 x i64 0
%98 = bitcast * %97 to *
%__constexpr_2 = bitcast * @102 to *
memcpy * %98 align 8, * %__constexpr_2 align 8, i64 16
%99 = gep inbounds * %options.i.i.i, 40 x i32 0, 1 x i64 16
%100 = bitcast * %99 to *
%__constexpr_3 = bitcast * @103 to *
memcpy * %100 align 8, * %__constexpr_3 align 8, i64 16
%101 = gep inbounds * %options.i.i.i, 40 x i32 0, 1 x i64 32
store i2 2, * %101, align 1
%102 = gep inbounds * %options.i.i.i, 40 x i32 0, 1 x i64 33
store i8 32, * %102, align 1
%103 = gep inbounds * %options.i.i.i, 40 x i32 0, 1 x i64 16
%104 = bitcast * %103 to *
%__constexpr_4 = bitcast * @104 to *
memcpy * %104 align 8, * %__constexpr_4 align 8, i64 16
%105 = gep inbounds * %options.i.i.i, 40 x i32 0, 1 x i64 0
%106 = bitcast * %105 to *
%__constexpr_5 = bitcast * @105 to *
memcpy * %106 align 8, * %__constexpr_5 align 8, i64 16
%107 = gep inbounds * %26, 8 x i32 0, 1 x i64 0
%108 = load i64, * %107, align 8
store i64 %108, * %15, align 8
%109 = bitcast * %options.i.i.i to *
%110 = bitcast * %16 to *
memcpy * %110 align 8, * %109 align 8, i64 40
%111 = bitcast * %stderr.i to *
%112 = bitcast * %17 to *
memcpy * %112 align 4, * %111 align 4, i64 4
store i64 %108, * %value.i.i.i.i, align 8
store i64 3, * %max_depth.i.i.i.i, align 8
%119 = load i64, * %value.i.i.i.i, align 8
store i64 %119, * %11, align 8
%120 = bitcast * %options.i.i.i to *
%121 = bitcast * %12 to *
memcpy * %121 align 8, * %120 align 8, i64 40
%122 = bitcast * %stderr.i to *
%123 = bitcast * %13 to *
memcpy * %123 align 4, * %122 align 4, i64 4
store i64 %119, * %value.i.i.i.i.i, align 8
%129 = load i64, * %value.i.i.i.i.i, align 8
store i64 %129, * %8, align 8
%130 = bitcast * %options.i.i.i to *
%131 = bitcast * %9 to *
memcpy * %131 align 8, * %130 align 8, i64 40
%132 = bitcast * %stderr.i to *
%133 = bitcast * %10 to *
memcpy * %133 align 4, * %132 align 4, i64 4
store i64 %129, * %value.i.i.i.i.i.i, align 8
%140 = load i64, * %value.i.i.i.i.i.i, align 8
store i64 %140, * %int_value.i.i.i.i.i.i, align 8
%141 = load i64, * %int_value.i.i.i.i.i.i, align 8
store i64 %141, * %5, align 8
%142 = bitcast * %options.i.i.i to *
%143 = bitcast * %6 to *
memcpy * %143 align 8, * %142 align 8, i64 40
%144 = bitcast * %stderr.i to *
%145 = bitcast * %7 to *
memcpy * %145 align 4, * %144 align 4, i64 4
%146 = call i16 @std.fmt.formatInt(i64 %141, i8 10, i1 0, nonnull align(8) * %options.i.i.i, nonnull align(4) * %stderr.i)
store i16 %146, * %result.i.i.i.i.i.i, align 2
%147 = load i16, * %result.i.i.i.i.i.i, align 2
store i16 %147, * %result.i.i.i.i.i, align 2
%154 = load i16, * %result.i.i.i.i.i, align 2
store i16 %154, * %result.i.i.i.i, align 2
%160 = load i16, * %result.i.i.i.i, align 2
store i16 %160, * %18, align 2
%167 = icmp ne i16 %160, 0
br i1 %167, label %ErrRetReturn2.i.i.i, label %ErrRetContinue3.i.i.i
%ErrRetReturn2.i.i.i:
%168 = load i16, * %18, align 2
store i16 %168, * %result.i.i1.i, align 2
br label %std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print.15.exit.i
%ErrRetContinue3.i.i.i:
%177 = call i16 @std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeAll(nonnull align(4) * %stderr.i, nonnull align(8) * @106)
store i16 %177, * %19, align 2
%178 = icmp ne i16 %177, 0
br i1 %178, label %ErrRetReturn4.i.i.i, label %ErrRetContinue5.i.i.i
%ErrRetReturn4.i.i.i:
%179 = load i16, * %19, align 2
store i16 %179, * %result.i.i1.i, align 2
br label %std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print.15.exit.i
%ErrRetContinue5.i.i.i:
store i16 0, * %result.i.i1.i, align 2
br label %std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print.15.exit.i
%std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print.15.exit.i:
%196 = phi i16 [ %88, %ErrRetReturn.i.i.i ], [ %168, %ErrRetReturn2.i.i.i ], [ %179, %ErrRetReturn4.i.i.i ], [ 0, %ErrRetContinue5.i.i.i ]
store i16 %196, * %result.i.i, align 2
%197 = load i16, * %result.i.i, align 2
store i16 %197, * %25, align 2
%201 = icmp ne i16 %197, 0
br i1 %201, label %UnwrapErrError.i, label %UnwrapErrOk.i
%UnwrapErrError.i:
%202 = gep inbounds * %held.i, 8 x i32 0, 1 x i64 0
%203 = load *, * %202, align 8
%204 = gep inbounds * %203, 1 x i32 0, 1 x i64 0
store i1 0, * %204, align 1
br label %std.debug.print.exit
%UnwrapErrOk.i:
%210 = gep inbounds * %held.i, 8 x i32 0, 1 x i64 0
%211 = load *, * %210, align 8
%212 = gep inbounds * %211, 1 x i32 0, 1 x i64 0
store i1 0, * %212, align 1
br label %std.debug.print.exit
%std.debug.print.exit:
%221 = gep inbounds * %3, 4 x i32 0, 1 x i64 0
store i32 2, * %result.i.i.i4, align 4
%223 = load i32, * %result.i.i.i4, align 4
store i32 %223, * %221, align 4
%225 = gep inbounds * %stderr.i5, 4 x i32 0, 1 x i64 0
%226 = bitcast * %3 to *
%227 = bitcast * %225 to *
memcpy * %227 align 4, * %226 align 4, i64 4
%230 = bitcast * %stderr.i5 to *
%231 = bitcast * %2 to *
memcpy * %231 align 4, * %230 align 4, i64 4
%235 = bitcast * %options.i.i.i2 to *
%__constexpr_6 = bitcast * @86 to *
memcpy * %235 align 8, * %__constexpr_6 align 8, i64 40
%236 = call i16 @std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeAll(nonnull align(4) * %stderr.i5, nonnull align(8) * @87)
store i16 %236, * %1, align 2
%237 = icmp ne i16 %236, 0
br i1 %237, label %ErrRetReturn.i.i.i6, label %ErrRetContinue.i.i.i7
%ErrRetReturn.i.i.i6:
%238 = load i16, * %1, align 2
store i16 %238, * %result.i.i1.i1, align 2
br label %std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print.9.exit.i
%ErrRetContinue.i.i.i7:
store i16 0, * %result.i.i1.i1, align 2
br label %std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print.9.exit.i
%std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print.9.exit.i:
%245 = phi i16 [ %238, %ErrRetReturn.i.i.i6 ], [ 0, %ErrRetContinue.i.i.i7 ]
store i16 %245, * %result.i.i3, align 2
%246 = load i16, * %result.i.i3, align 2
store i16 %246, * %4, align 2
%249 = icmp ne i16 %246, 0
br i1 %249, label %UnwrapErrError.i8, label %UnwrapErrOk.i9
%UnwrapErrError.i8:
br label %std.debug.dumpCurrentStackTrace.exit
%UnwrapErrOk.i9:
br label %std.debug.dumpCurrentStackTrace.exit
%std.debug.dumpCurrentStackTrace.exit:
store i16 11, * %result, align 2
%256 = load i16, * %result, align 2
ret i16 %256
%OptionalNull.i.i:
call void @std.builtin.default_panic(nonnull align(8) * @19, align(8) * null) noreturn
assume i1 0
}
=>
@stderr_mutex = global 1 bytes, align 1
@63 = constant 16 bytes, align 8
@99 = constant 40 bytes, align 8
@101 = constant 16 bytes, align 8
@102 = constant 16 bytes, align 8
@103 = constant 16 bytes, align 8
@104 = constant 16 bytes, align 8
@105 = constant 16 bytes, align 8
@106 = constant 16 bytes, align 8
@86 = constant 40 bytes, align 8
@87 = constant 16 bytes, align 8
@19 = constant 16 bytes, align 8
@100 = constant 22 bytes, align 1
@84 = constant 49 bytes, align 1
@18 = constant 18 bytes, align 1
define i16 @std.os.unexpectedErrno(i64 %0) {
#init:
%__copy_0 = {{i64, i1, i56}, {i64, i1, i56}, i2, {i8, [6 x i8]}} { { undef, 0, [padding] }, { undef, 0, [padding] }, 2, { 32, undef } }
%__copy_3 = {{i64, i1, i56}, {i64, i1, i56}, i2, {i8, [6 x i8]}} { { undef, 0, [padding] }, { undef, 0, [padding] }, 2, { 32, undef } }
store [22 x i8] { 117, 110, 101, 120, 112, 101, 99, 116, 101, 100, 32, 101, 114, 114, 110, 111, 58, 32, 123, 125, 10, 0 }, * @100, align 1
store {i64, i1, i56} { undef, 0, [padding] }, * @102, align 8
store {i64, i1, i56} { undef, 0, [padding] }, * @103, align 8
store {i64, i1, i56} { undef, 0, [padding] }, * @104, align 8
store {i64, i1, i56} { undef, 0, [padding] }, * @105, align 8
store [18 x i8] { 100, 101, 97, 100, 108, 111, 99, 107, 32, 100, 101, 116, 101, 99, 116, 101, 100, 0 }, * @18, align 1
store {{*}, i1, i56} { undef, 0, [padding] }, * @63, align 8
store [49 x i8] { 85, 110, 97, 98, 108, 101, 32, 116, 111, 32, 100, 117, 109, 112, 32, 115, 116, 97, 99, 107, 32, 116, 114, 97, 99, 101, 58, 32, 100, 101, 98, 117, 103, 32, 105, 110, 102, 111, 32, 115, 116, 114, 105, 112, 112, 101, 100, 10, 0 }, * @84, align 1
store {{i64, i1, i56}, {i64, i1, i56}, i2, {i8, [6 x i8]}} %__copy_3, * @86, align 8
store {{i64, i1, i56}, {i64, i1, i56}, i2, {i8, [6 x i8]}} %__copy_0, * @99, align 8
br label %Entry
%Entry:
%options.i.i.i2 = alloca i64 40, align 8
%stderr.i5 = alloca i64 4, align 4
%1 = alloca i64 40, align 8
%2 = alloca i64 40, align 8
%3 = alloca i64 40, align 8
%options.i.i.i = alloca i64 40, align 8
%4 = alloca i64 40, align 8
%.sroa.6 = alloca i64 7, align 1
%stderr.i = alloca i64 4, align 4
%6 = gep inbounds * @stderr_mutex, 1 x i32 0, 1 x i64 0
%7 = load i1, * %6, align 1
br i1 %7, label %Then.i.i.i, label %Else.i.i.i
%Else.i.i.i:
%8 = gep inbounds * @stderr_mutex, 1 x i32 0, 1 x i64 0
store i1 1, * %8, align 1
br label %std.mutex.Dummy.tryAcquire.exit.i.i
%Then.i.i.i:
%__constexpr_0 = gep inbounds * @63, 16 x i64 0, 1 x i64 0, 1 x i64 0
%.sroa.06.0.copyload = load *, * %__constexpr_0, align 8
%__constexpr_1 = gep inbounds * @63, 16 x i64 0, 1 x i64 8
%.sroa.3.0.copyload = load i1, * %__constexpr_1, align 8
%.sroa.6.0..sroa_idx = gep inbounds * %.sroa.6, 7 x i64 0, 1 x i64 0
%__constexpr_3 = bitcast * @63 to *
%__constexpr_2 = gep inbounds * %__constexpr_3, 1 x i64 9
memcpy * %.sroa.6.0..sroa_idx align 1, * %__constexpr_2 align 1, i64 7
br label %std.mutex.Dummy.tryAcquire.exit.i.i
%std.mutex.Dummy.tryAcquire.exit.i.i:
%.sroa.06.0 = phi * [ %.sroa.06.0.copyload, %Then.i.i.i ], [ @stderr_mutex, %Else.i.i.i ]
%.sroa.3.0 = phi i1 [ %.sroa.3.0.copyload, %Then.i.i.i ], [ 1, %Else.i.i.i ]
br i1 %.sroa.3.0, label %std.mutex.Dummy.acquire.exit.i, label %OptionalNull.i.i
%std.mutex.Dummy.acquire.exit.i:
%.sroa.04.0..sroa_idx = gep inbounds * %stderr.i, 4 x i64 0, 1 x i64 0, 1 x i64 0
store i32 2, * %.sroa.04.0..sroa_idx, align 4
%.sroa.010.0..sroa_idx = gep inbounds * %stderr.i, 4 x i64 0, 1 x i64 0, 1 x i64 0
%.sroa.010.0.copyload = load i32, * %.sroa.010.0..sroa_idx, align 4
%10 = bitcast * %options.i.i.i to *
%__constexpr_4 = bitcast * @99 to *
memcpy * %10 align 8, * %__constexpr_4 align 8, i64 40
%11 = call i16 @std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeAll(nonnull align(4) * %stderr.i, nonnull align(8) * @101)
%12 = icmp ne i16 %11, 0
br i1 %12, label %ErrRetReturn.i.i.i, label %ErrRetContinue.i.i.i
%ErrRetReturn.i.i.i:
br label %std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print.15.exit.i
%ErrRetContinue.i.i.i:
%14 = gep inbounds * %options.i.i.i, 40 x i32 0, 1 x i64 0
%15 = bitcast * %14 to *
%__constexpr_5 = bitcast * @102 to *
memcpy * %15 align 8, * %__constexpr_5 align 8, i64 16
%16 = gep inbounds * %options.i.i.i, 40 x i32 0, 1 x i64 16
%17 = bitcast * %16 to *
%__constexpr_6 = bitcast * @103 to *
memcpy * %17 align 8, * %__constexpr_6 align 8, i64 16
%18 = gep inbounds * %options.i.i.i, 40 x i32 0, 1 x i64 32
store i2 2, * %18, align 1
%19 = gep inbounds * %options.i.i.i, 40 x i32 0, 1 x i64 33
store i8 32, * %19, align 1
%20 = gep inbounds * %options.i.i.i, 40 x i32 0, 1 x i64 16
%21 = bitcast * %20 to *
%__constexpr_7 = bitcast * @104 to *
memcpy * %21 align 8, * %__constexpr_7 align 8, i64 16
%22 = gep inbounds * %options.i.i.i, 40 x i32 0, 1 x i64 0
%23 = bitcast * %22 to *
%__constexpr_8 = bitcast * @105 to *
memcpy * %23 align 8, * %__constexpr_8 align 8, i64 16
%24 = bitcast * %options.i.i.i to *
%25 = bitcast * %4 to *
memcpy * %25 align 8, * %24 align 8, i64 40
%.sroa.012.0..sroa_idx = gep inbounds * %stderr.i, 4 x i64 0, 1 x i64 0, 1 x i64 0
%.sroa.012.0.copyload = load i32, * %.sroa.012.0..sroa_idx, align 4
%26 = bitcast * %options.i.i.i to *
%27 = bitcast * %3 to *
memcpy * %27 align 8, * %26 align 8, i64 40
%.sroa.014.0..sroa_idx = gep inbounds * %stderr.i, 4 x i64 0, 1 x i64 0, 1 x i64 0
%.sroa.014.0.copyload = load i32, * %.sroa.014.0..sroa_idx, align 4
%28 = bitcast * %options.i.i.i to *
%29 = bitcast * %2 to *
memcpy * %29 align 8, * %28 align 8, i64 40
%.sroa.015.0..sroa_idx = gep inbounds * %stderr.i, 4 x i64 0, 1 x i64 0, 1 x i64 0
%.sroa.015.0.copyload = load i32, * %.sroa.015.0..sroa_idx, align 4
%30 = bitcast * %options.i.i.i to *
%31 = bitcast * %1 to *
memcpy * %31 align 8, * %30 align 8, i64 40
%.sroa.016.0..sroa_idx = gep inbounds * %stderr.i, 4 x i64 0, 1 x i64 0, 1 x i64 0
%.sroa.016.0.copyload = load i32, * %.sroa.016.0..sroa_idx, align 4
%32 = call i16 @std.fmt.formatInt(i64 %0, i8 10, i1 0, nonnull align(8) * %options.i.i.i, nonnull align(4) * %stderr.i)
%33 = icmp ne i16 %32, 0
br i1 %33, label %ErrRetReturn2.i.i.i, label %ErrRetContinue3.i.i.i
%ErrRetReturn2.i.i.i:
br label %std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print.15.exit.i
%ErrRetContinue3.i.i.i:
%35 = call i16 @std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeAll(nonnull align(4) * %stderr.i, nonnull align(8) * @106)
%36 = icmp ne i16 %35, 0
br i1 %36, label %ErrRetReturn4.i.i.i, label %ErrRetContinue5.i.i.i
%ErrRetReturn4.i.i.i:
br label %std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print.15.exit.i
%ErrRetContinue5.i.i.i:
br label %std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print.15.exit.i
%std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print.15.exit.i:
%39 = phi i16 [ %11, %ErrRetReturn.i.i.i ], [ %32, %ErrRetReturn2.i.i.i ], [ %35, %ErrRetReturn4.i.i.i ], [ 0, %ErrRetContinue5.i.i.i ]
%40 = icmp ne i16 %39, 0
br i1 %40, label %UnwrapErrError.i, label %UnwrapErrOk.i
%UnwrapErrError.i:
%41 = gep inbounds * %.sroa.06.0, 1 x i32 0, 1 x i64 0
store i1 0, * %41, align 1
br label %std.debug.print.exit
%UnwrapErrOk.i:
%43 = gep inbounds * %.sroa.06.0, 1 x i32 0, 1 x i64 0
store i1 0, * %43, align 1
br label %std.debug.print.exit
%std.debug.print.exit:
%.sroa.017.0..sroa_idx = gep inbounds * %stderr.i5, 4 x i64 0, 1 x i64 0, 1 x i64 0
store i32 2, * %.sroa.017.0..sroa_idx, align 4
%.sroa.018.0..sroa_idx = gep inbounds * %stderr.i5, 4 x i64 0, 1 x i64 0, 1 x i64 0
%.sroa.018.0.copyload = load i32, * %.sroa.018.0..sroa_idx, align 4
%46 = bitcast * %options.i.i.i2 to *
%__constexpr_9 = bitcast * @86 to *
memcpy * %46 align 8, * %__constexpr_9 align 8, i64 40
%47 = call i16 @std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).writeAll(nonnull align(4) * %stderr.i5, nonnull align(8) * @87)
%48 = icmp ne i16 %47, 0
br i1 %48, label %ErrRetReturn.i.i.i6, label %ErrRetContinue.i.i.i7
%ErrRetReturn.i.i.i6:
br label %std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print.9.exit.i
%ErrRetContinue.i.i.i7:
br label %std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print.9.exit.i
%std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write).print.9.exit.i:
%49 = phi i16 [ %47, %ErrRetReturn.i.i.i6 ], [ 0, %ErrRetContinue.i.i.i7 ]
%50 = icmp ne i16 %49, 0
br i1 %50, label %UnwrapErrError.i8, label %UnwrapErrOk.i9
%UnwrapErrError.i8:
br label %std.debug.dumpCurrentStackTrace.exit
%UnwrapErrOk.i9:
br label %std.debug.dumpCurrentStackTrace.exit
%std.debug.dumpCurrentStackTrace.exit:
ret i16 11
%OptionalNull.i.i:
call void @std.builtin.default_panic(nonnull align(8) * @19, align(8) * null) noreturn
assume i1 0
}
Transformation doesn't verify!
ERROR: Mismatch in memory
Example:
i64 %0 = any
Source:
{{i64, i1, i56}, {i64, i1, i56}, i2, {i8, [6 x i8]}} %__copy_0 = { { any, #x0 (0), poison }, { any, #x0 (0), poison }, #x2 (2, -2), { #x20 (32), < any, any, any, any, any, any > } }
{{i64, i1, i56}, {i64, i1, i56}, i2, {i8, [6 x i8]}} %__copy_3 = { { any, #x0 (0), poison }, { any, #x0 (0), poison }, #x2 (2, -2), { #x20 (32), < any, any, any, any, any, any > } }
* %result.i.i1.i1 = pointer(local, block_id=64, offset=0)
* %options.i.i.i2 = pointer(local, block_id=65, offset=0)
* %1 = pointer(local, block_id=66, offset=0)
* %result.i.i3 = pointer(local, block_id=67, offset=0)
* %2 = pointer(local, block_id=68, offset=0)
* %result.i.i.i4 = pointer(local, block_id=69, offset=0)
* %3 = pointer(local, block_id=70, offset=0)
* %stderr.i5 = pointer(local, block_id=71, offset=0)
* %4 = pointer(local, block_id=72, offset=0)
* %result.i.i.i.i.i.i = pointer(local, block_id=73, offset=0)
* %int_value.i.i.i.i.i.i = pointer(local, block_id=74, offset=0)
* %5 = pointer(local, block_id=75, offset=0)
* %6 = pointer(local, block_id=76, offset=0)
* %7 = pointer(local, block_id=77, offset=0)
* %value.i.i.i.i.i.i = pointer(local, block_id=78, offset=0)
* %result.i.i.i.i.i = pointer(local, block_id=79, offset=0)
* %8 = pointer(local, block_id=80, offset=0)
* %9 = pointer(local, block_id=81, offset=0)
* %10 = pointer(local, block_id=82, offset=0)
* %value.i.i.i.i.i = pointer(local, block_id=83, offset=0)
* %result.i.i.i.i = pointer(local, block_id=84, offset=0)
* %11 = pointer(local, block_id=85, offset=0)
* %12 = pointer(local, block_id=86, offset=0)
* %13 = pointer(local, block_id=87, offset=0)
* %value.i.i.i.i = pointer(local, block_id=88, offset=0)
* %max_depth.i.i.i.i = pointer(local, block_id=89, offset=0)
* %result.i.i1.i = pointer(local, block_id=90, offset=0)
* %options.i.i.i = pointer(local, block_id=91, offset=0)
* %14 = pointer(local, block_id=92, offset=0)
* %15 = pointer(local, block_id=93, offset=0)
* %16 = pointer(local, block_id=94, offset=0)
* %17 = pointer(local, block_id=95, offset=0)
* %18 = pointer(local, block_id=96, offset=0)
* %19 = pointer(local, block_id=97, offset=0)
* %result.i.i = pointer(local, block_id=98, offset=0)
* %20 = pointer(local, block_id=99, offset=0)
* %21 = pointer(local, block_id=100, offset=0)
* %self.i.i.i = pointer(local, block_id=101, offset=0)
* %22 = pointer(local, block_id=102, offset=0)
* %self.i.i = pointer(local, block_id=103, offset=0)
* %result.i.i.i = pointer(local, block_id=104, offset=0)
* %held.i = pointer(local, block_id=105, offset=0)
* %23 = pointer(local, block_id=106, offset=0)
* %stderr.i = pointer(local, block_id=107, offset=0)
* %24 = pointer(local, block_id=108, offset=0)
* %25 = pointer(local, block_id=109, offset=0)
* %result = pointer(local, block_id=110, offset=0)
* %26 = pointer(local, block_id=111, offset=0)
* %err = pointer(local, block_id=112, offset=0)
i64 %27 = any
* %28 = pointer(local, block_id=111, offset=0)
* %36 = pointer(non-local, block_id=15, offset=0)
* %38 = pointer(non-local, block_id=15, offset=0)
* %39 = pointer(non-local, block_id=15, offset=0)
i1 %40 = #x0 (0)
* %41 = pointer(non-local, block_id=15, offset=0)
* %42 = pointer(non-local, block_id=15, offset=0)
* %43 = pointer(local, block_id=102, offset=8)
* %44 = pointer(local, block_id=102, offset=0)
* %45 = pointer(local, block_id=102, offset=0)
* %46 = pointer(non-local, block_id=15, offset=0)
* %47 = pointer(local, block_id=102, offset=8)
* %48 = pointer(local, block_id=102, offset=0)
* %49 = pointer(local, block_id=102, offset=0)
* %50 = pointer(local, block_id=102, offset=0)
* %52 = pointer(local, block_id=102, offset=0)
* %__constexpr_0 = pointer(non-local, block_id=1, offset=0)
* %54 = pointer(local, block_id=102, offset=8)
i1 %55 = #x1 (1)
* %56 = pointer(local, block_id=102, offset=0)
* %57 = pointer(local, block_id=102, offset=0)
* %58 = pointer(local, block_id=105, offset=0)
* %61 = pointer(local, block_id=106, offset=0)
i32 %63 = #x00000002 (2)
* %65 = pointer(local, block_id=107, offset=0)
* %66 = pointer(local, block_id=106, offset=0)
* %67 = pointer(local, block_id=107, offset=0)
* %68 = pointer(local, block_id=111, offset=0)
* %69 = pointer(local, block_id=108, offset=0)
* %73 = pointer(local, block_id=107, offset=0)
* %74 = pointer(local, block_id=99, offset=0)
* %75 = pointer(local, block_id=111, offset=0)
* %76 = pointer(local, block_id=100, offset=0)
* %85 = pointer(local, block_id=91, offset=0)
* %__constexpr_1 = pointer(non-local, block_id=2, offset=0)
i16 %86 = #x0000 (0)
i1 %87 = #x0 (0)
i16 %88 = #x0000 (0)
* %97 = pointer(local, block_id=91, offset=0)
* %98 = pointer(local, block_id=91, offset=0)
* %__constexpr_2 = pointer(non-local, block_id=4, offset=0)
* %99 = pointer(local, block_id=91, offset=16)
* %100 = pointer(local, block_id=91, offset=16)
* %__constexpr_3 = pointer(non-local, block_id=5, offset=0)
* %101 = pointer(local, block_id=91, offset=32)
* %102 = pointer(local, block_id=91, offset=33)
* %103 = pointer(local, block_id=91, offset=16)
* %104 = pointer(local, block_id=91, offset=16)
* %__constexpr_4 = pointer(non-local, block_id=6, offset=0)
* %105 = pointer(local, block_id=91, offset=0)
* %106 = pointer(local, block_id=91, offset=0)
* %__constexpr_5 = pointer(non-local, block_id=7, offset=0)
* %107 = pointer(local, block_id=111, offset=0)
i64 %108 = any
* %109 = pointer(local, block_id=91, offset=0)
* %110 = pointer(local, block_id=94, offset=0)
* %111 = pointer(local, block_id=107, offset=0)
* %112 = pointer(local, block_id=95, offset=0)
i64 %119 = any
* %120 = pointer(local, block_id=91, offset=0)
* %121 = pointer(local, block_id=86, offset=0)
* %122 = pointer(local, block_id=107, offset=0)
* %123 = pointer(local, block_id=87, offset=0)
i64 %129 = any
* %130 = pointer(local, block_id=91, offset=0)
* %131 = pointer(local, block_id=81, offset=0)
* %132 = pointer(local, block_id=107, offset=0)
* %133 = pointer(local, block_id=82, offset=0)
i64 %140 = any
i64 %141 = any
* %142 = pointer(local, block_id=91, offset=0)
* %143 = pointer(local, block_id=76, offset=0)
* %144 = pointer(local, block_id=107, offset=0)
* %145 = pointer(local, block_id=77, offset=0)
i16 %146 = #x0000 (0)
i16 %147 = #x0000 (0)
i16 %154 = #x0000 (0)
i16 %160 = #x0000 (0)
i1 %167 = #x0 (0)
i16 %168 = #x0000 (0)
i16 %177 = #x0000 (0)
i1 %178 = #x0 (0)
i16 %179 = #x0000 (0)
i16 %196 = #x0000 (0)
i16 %197 = #x0000 (0)
i1 %201 = #x0 (0)
* %202 = pointer(local, block_id=105, offset=0)
* %203 = pointer(non-local, block_id=15, offset=0)
* %204 = pointer(non-local, block_id=15, offset=0)
* %210 = pointer(local, block_id=105, offset=0)
* %211 = pointer(non-local, block_id=15, offset=0)
* %212 = pointer(non-local, block_id=15, offset=0)
* %221 = pointer(local, block_id=70, offset=0)
i32 %223 = #x00000002 (2)
* %225 = pointer(local, block_id=71, offset=0)
* %226 = pointer(local, block_id=70, offset=0)
* %227 = pointer(local, block_id=71, offset=0)
* %230 = pointer(local, block_id=71, offset=0)
* %231 = pointer(local, block_id=68, offset=0)
* %235 = pointer(local, block_id=65, offset=0)
* %__constexpr_6 = pointer(non-local, block_id=9, offset=0)
i16 %236 = #xffff (65535, -1)
i1 %237 = #x1 (1)
i16 %238 = #xffff (65535, -1)
i16 %245 = #xffff (65535, -1)
i16 %246 = #xffff (65535, -1)
i1 %249 = #x1 (1)
i16 %256 = #x000b (11)
SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 > size: 0 align: 1 alloc type: 0
Block 1 > size: 16 align: 8 alloc type: 0
Block 2 > size: 40 align: 8 alloc type: 0
Block 3 > size: 16 align: 8 alloc type: 0
Block 4 > size: 16 align: 8 alloc type: 0
Block 5 > size: 16 align: 8 alloc type: 0
Block 6 > size: 16 align: 8 alloc type: 0
Block 7 > size: 16 align: 8 alloc type: 0
Block 8 > size: 16 align: 8 alloc type: 0
Block 9 > size: 40 align: 8 alloc type: 0
Block 10 > size: 16 align: 8 alloc type: 0
Block 11 > size: 16 align: 8 alloc type: 0
Block 12 > size: 22 align: 1 alloc type: 0
Block 13 > size: 49 align: 1 alloc type: 0
Block 14 > size: 18 align: 1 alloc type: 0
Block 15 > size: 1 align: 1 alloc type: 0
Block 16 > size: 22 align: 8 alloc type: 2
LOCAL BLOCKS:
Block 64 > size: 2 align: 2 alloc type: 1
Block 65 > size: 40 align: 8 alloc type: 1
Block 66 > size: 2 align: 2 alloc type: 1
Block 67 > size: 2 align: 2 alloc type: 1
Block 68 > size: 4 align: 4 alloc type: 1
Block 69 > size: 4 align: 4 alloc type: 1
Block 70 > size: 4 align: 4 alloc type: 1
Block 71 > size: 4 align: 4 alloc type: 1
Block 72 > size: 2 align: 2 alloc type: 1
Block 73 > size: 2 align: 2 alloc type: 1
Block 74 > size: 8 align: 8 alloc type: 1
Block 75 > size: 8 align: 8 alloc type: 1
Block 76 > size: 40 align: 8 alloc type: 1
Block 77 > size: 4 align: 4 alloc type: 1
Block 78 > size: 8 align: 8 alloc type: 1
Block 79 > size: 2 align: 2 alloc type: 1
Block 80 > size: 8 align: 8 alloc type: 1
Block 81 > size: 40 align: 8 alloc type: 1
Block 82 > size: 4 align: 4 alloc type: 1
Block 83 > size: 8 align: 8 alloc type: 1
Block 84 > size: 2 align: 2 alloc type: 1
Block 85 > size: 8 align: 8 alloc type: 1
Block 86 > size: 40 align: 8 alloc type: 1
Block 87 > size: 4 align: 4 alloc type: 1
Block 88 > size: 8 align: 8 alloc type: 1
Block 89 > size: 8 align: 8 alloc type: 1
Block 90 > size: 2 align: 2 alloc type: 1
Block 91 > size: 40 align: 8 alloc type: 1
Block 92 > size: 2 align: 2 alloc type: 1
Block 93 > size: 8 align: 8 alloc type: 1
Block 94 > size: 40 align: 8 alloc type: 1
Block 95 > size: 4 align: 4 alloc type: 1
Block 96 > size: 2 align: 2 alloc type: 1
Block 97 > size: 2 align: 2 alloc type: 1
Block 98 > size: 2 align: 2 alloc type: 1
Block 99 > size: 4 align: 4 alloc type: 1
Block 100 > size: 8 align: 8 alloc type: 1
Block 101 > size: 8 align: 8 alloc type: 1
Block 102 > size: 16 align: 8 alloc type: 1
Block 103 > size: 8 align: 8 alloc type: 1
Block 104 > size: 4 align: 4 alloc type: 1
Block 105 > size: 8 align: 8 alloc type: 1
Block 106 > size: 4 align: 4 alloc type: 1
Block 107 > size: 4 align: 4 alloc type: 1
Block 108 > size: 8 align: 8 alloc type: 1
Block 109 > size: 2 align: 2 alloc type: 1
Block 110 > size: 2 align: 2 alloc type: 1
Block 111 > size: 8 align: 8 alloc type: 1
Block 112 > size: 8 align: 8 alloc type: 1
Target:
{{i64, i1, i56}, {i64, i1, i56}, i2, {i8, [6 x i8]}} %__copy_0 = { { #x0000000000000000 (0), #x0 (0), poison }, { any, #x0 (0), poison }, #x2 (2, -2), { #x20 (32), < any, any, any, any, any, any > } }
{{i64, i1, i56}, {i64, i1, i56}, i2, {i8, [6 x i8]}} %__copy_3 = { { #x0000000000000000 (0), #x0 (0), poison }, { any, #x0 (0), poison }, #x2 (2, -2), { #x20 (32), < any, any, any, any, any, any > } }
* %options.i.i.i2 = pointer(local, block_id=64, offset=0)
* %stderr.i5 = pointer(local, block_id=65, offset=0)
* %1 = pointer(local, block_id=66, offset=0)
* %2 = pointer(local, block_id=67, offset=0)
* %3 = pointer(local, block_id=68, offset=0)
* %options.i.i.i = pointer(local, block_id=69, offset=0)
* %4 = pointer(local, block_id=70, offset=0)
* %.sroa.6 = pointer(local, block_id=71, offset=0)
* %stderr.i = pointer(local, block_id=72, offset=0)
* %6 = pointer(non-local, block_id=15, offset=0)
i1 %7 = #x0 (0)
* %8 = pointer(non-local, block_id=15, offset=0)
* %__constexpr_0 = pointer(non-local, block_id=1, offset=0)
* %.sroa.06.0.copyload = any
* %__constexpr_1 = pointer(non-local, block_id=1, offset=8)
i1 %.sroa.3.0.copyload = #x0 (0)
* %.sroa.6.0..sroa_idx = pointer(local, block_id=71, offset=0)
* %__constexpr_3 = pointer(non-local, block_id=1, offset=0)
* %__constexpr_2 = pointer(non-local, block_id=1, offset=9)
* %.sroa.06.0 = pointer(non-local, block_id=15, offset=0)
i1 %.sroa.3.0 = #x1 (1)
* %.sroa.04.0..sroa_idx = pointer(local, block_id=72, offset=0)
* %.sroa.010.0..sroa_idx = pointer(local, block_id=72, offset=0)
i32 %.sroa.010.0.copyload = #x00000002 (2)
* %10 = pointer(local, block_id=69, offset=0)
* %__constexpr_4 = pointer(non-local, block_id=2, offset=0)
i16 %11 = #x0000 (0)
i1 %12 = #x0 (0)
* %14 = pointer(local, block_id=69, offset=0)
* %15 = pointer(local, block_id=69, offset=0)
* %__constexpr_5 = pointer(non-local, block_id=4, offset=0)
* %16 = pointer(local, block_id=69, offset=16)
* %17 = pointer(local, block_id=69, offset=16)
* %__constexpr_6 = pointer(non-local, block_id=5, offset=0)
* %18 = pointer(local, block_id=69, offset=32)
* %19 = pointer(local, block_id=69, offset=33)
* %20 = pointer(local, block_id=69, offset=16)
* %21 = pointer(local, block_id=69, offset=16)
* %__constexpr_7 = pointer(non-local, block_id=6, offset=0)
* %22 = pointer(local, block_id=69, offset=0)
* %23 = pointer(local, block_id=69, offset=0)
* %__constexpr_8 = pointer(non-local, block_id=7, offset=0)
* %24 = pointer(local, block_id=69, offset=0)
* %25 = pointer(local, block_id=70, offset=0)
* %.sroa.012.0..sroa_idx = pointer(local, block_id=72, offset=0)
i32 %.sroa.012.0.copyload = #x00000002 (2)
* %26 = pointer(local, block_id=69, offset=0)
* %27 = pointer(local, block_id=68, offset=0)
* %.sroa.014.0..sroa_idx = pointer(local, block_id=72, offset=0)
i32 %.sroa.014.0.copyload = #x00000002 (2)
* %28 = pointer(local, block_id=69, offset=0)
* %29 = pointer(local, block_id=67, offset=0)
* %.sroa.015.0..sroa_idx = pointer(local, block_id=72, offset=0)
i32 %.sroa.015.0.copyload = #x00000002 (2)
* %30 = pointer(local, block_id=69, offset=0)
* %31 = pointer(local, block_id=66, offset=0)
* %.sroa.016.0..sroa_idx = pointer(local, block_id=72, offset=0)
i32 %.sroa.016.0.copyload = #x00000002 (2)
i16 %32 = #x0000 (0)
i1 %33 = #x0 (0)
i16 %35 = #x0000 (0)
i1 %36 = #x0 (0)
i16 %39 = #x0000 (0)
i1 %40 = #x0 (0)
* %41 = pointer(non-local, block_id=15, offset=0)
* %43 = pointer(non-local, block_id=15, offset=0)
* %.sroa.017.0..sroa_idx = pointer(local, block_id=65, offset=0)
* %.sroa.018.0..sroa_idx = pointer(local, block_id=65, offset=0)
i32 %.sroa.018.0.copyload = #x00000002 (2)
* %46 = pointer(local, block_id=64, offset=0)
* %__constexpr_9 = pointer(non-local, block_id=9, offset=0)
i16 %47 = #xffff (65535, -1)
i1 %48 = #x1 (1)
i16 %49 = #xffff (65535, -1)
i1 %50 = #x1 (1)
TARGET MEMORY STATE
===================
LOCAL BLOCKS:
Block 64 > size: 40 align: 8 alloc type: 1
Block 65 > size: 4 align: 4 alloc type: 1
Block 66 > size: 40 align: 8 alloc type: 1
Block 67 > size: 40 align: 8 alloc type: 1
Block 68 > size: 40 align: 8 alloc type: 1
Block 69 > size: 40 align: 8 alloc type: 1
Block 70 > size: 40 align: 8 alloc type: 1
Block 71 > size: 7 align: 1 alloc type: 1
Block 72 > size: 4 align: 4 alloc type: 1
Mismatch in pointer(non-local, block_id=1, offset=0)
Source value: null, byte offset=0
Target value: pointer(local, block_id=96, offset=0), byte offset=0
But i'm not sure if that is the problem you're seeing (cc @nunoplopes)
Thank you LemonBoy for your work on tracking this down!
This is either over-reduced, or the original IR is already broken, because alive2 says that the transformation is valid:
That's weird, running it with lli prints two different strings when the sroa is enabled/disabled.
The transform looks ok, alive2 confirms that and so does the lack of assertions being triggered in LLVM, but the problem is only noticeable at runtime: instead of printing what happened to me you only get a w, for some reason the optimized code stomps over the length field for the string slice.
Changing %TempRef = type { i64, i1 } into %TempRef = type { i64, i8 } makes the problem disappear, it seems to me that the presence of a non-byte-sized field there confuses the pass (or simply hides the error).
You need to be careful when reducing test cases to avoid introducing UB. If that happens, anything goes 😀 I'll have a look at the report to see if I spot smth.
Ok, I've checked the report posted by @LebedevRI: it's a bug in Alive2 😎 Alive2 isn't doing the right thing for global constants initialized with undef pointers. I changed those to poison and the report goes away. So Alive2 can't find any bug in the repro (the big one). It means one of 3 things:
- The miscompilation happens in one of the functions with inline asm; Alive2 skips those ATM
- The input has UB and therefore LLVM is free to print whatever. We have
alive-execwhich can run an LLVM IR function and tell you if it runs into UB. But it's very limited for now: functions can't have arguments and can't call other functions. So not very useful here. - Or Alive2 misses the bug. Possible as the input has loops.
So I send the ball back to you guys: it's not clear it's a bug in LLVM. It might just be UB on your side. Someone has to dig in.
@nunoplopes thank you for taking a look!
Ok, I tracked this down as I was wondering if it was a bug in Alive2 or not. There's no bug in LLVM or Alive2. It's a bug in Zig!
TL;DR: You copy a structure with type { i8*, i64 } to a temporary with type { i64, i1 }. The string size gets truncated to 1, hence you only see 1 character being printed when using SROA.
Reduced test case:
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
%CallArg = type { %"[]u8" }
%"[]u8" = type { i8*, i64 }
%ExpressionResult = type { i64, i1 }
@0 = internal unnamed_addr constant [20 x i8] c"what happened to me\00", align 1
@1 = internal unnamed_addr constant %CallArg { %"[]u8" { i8* getelementptr inbounds ([20 x i8], [20 x i8]* @0, i64 0, i64 0), i64 19 } }, align 8
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #0
define void @main() {
%v.i = alloca %"[]u8", align 8
%w.i = alloca %"[]u8", align 8
%result = alloca %ExpressionResult, align 8
%derp = alloca %ExpressionResult, align 8
; copy @1 -> %v.1 ([]u8 -> []u8)
%x3 = getelementptr inbounds %CallArg, %CallArg* @1, i32 0, i32 0
%x7 = bitcast %"[]u8"* %x3 to i8*
%x8 = bitcast %"[]u8"* %v.i to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %x8, i8* %x7, i64 16, i1 false)
; copy %v.1 -> %result ([]u8 -> ExpressionResult) BUG!
%x14 = bitcast %ExpressionResult* %result to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %x14, i8* %x8, i64 16, i1 false)
; copy %result -> %w.i
%x18 = bitcast %"[]u8"* %w.i to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %x18, i8* %x14, i64 16, i1 false)
; output %w.i
call void @std.os.write(i32 1, %"[]u8"* %w.i)
ret void
SwitchProng1.i3: ; No predecessors!
%x35 = getelementptr inbounds %ExpressionResult, %ExpressionResult* %derp, i32 0, i32 1
store i1 false, i1* %x35, align 1
ret void
SwitchProng2.i4: ; No predecessors!
%x37 = bitcast %ExpressionResult* %result to i8*
%x38 = bitcast %ExpressionResult* %derp to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %x38, i8* %x37, i64 24, i1 false)
ret void
}
define void @std.os.write(i32 %x0, %"[]u8"* %x1) {
; size
%x2 = getelementptr inbounds %"[]u8", %"[]u8"* %x1, i32 0, i32 1
%x3 = load i64, i64* %x2, align 8
; ptr
%x6 = getelementptr inbounds %"[]u8", %"[]u8"* %x1, i32 0, i32 0
%x7 = load i8*, i8** %x6, align 8
%x10 = ptrtoint i8* %x7 to i64
%x15 = call i64 asm sideeffect "syscall", "={rax},{rax},{rdi},{rsi},{rdx},~{rcx},~{r11},~{memory},~{dirflag},~{fpsr},~{flags}"(i64 1, i64 0, i64 %x10, i64 %x3)
ret void
}
It's a bug in Zig!
:scream:
Thank you for pinpointing the problem, the tagged enum representation in the IR assumes there's always enough padding after { i64, i1 } so that it has the same shape in memory as { i8*, i64 }, this also explains why the SROA made the problem surface.
it's a bug in Alive2
Talk about killing two birds with one stone! :D
This bug left me thinking.. It's debatable whether there's a bug in SROA or not. For load/store instructions, we (LLVM's LangRef) explicitly rules out reading/writing padding bits. But there's no similar wording for memcpy. I guess we need to patch either the documentation or SROA.
This is no longer happening. Could it be possible to have a small test which covers this case to add it to the behavior tests?