zig
zig copied to clipboard
Sema: strange Air emitted by `test "result location with inferred type ends up being pointer to comptime_int"`
Zig Version
0.11.0-dev.12+ebf9ffd34
Steps to Reproduce
export fn entry() void {
var a: ?u32 = 1234;
var b: u32 = 2000;
var c = if (a) |d| blk: {
if (d < b) break :blk @as(u32, 1);
break :blk 0;
} else @as(u32, 0);
_ = c;
}
Observed vs Expected Behavior
$ zig build-obj repro.zig --verbose-air
AST Lowering [463] # Begin Function AIR: repro.entry:
# Total AIR+Liveness bytes: 1.2958984375KiB
# AIR Instructions: 83 (747B)
# AIR Extra Data: 63 (252B)
# AIR Values Bytes: 14 (112B)
# Liveness tomb_bits: 48B
# Liveness Extra Data: 10 (40B)
# Liveness special table: 2 (16B)
%0 = const_ty(*const type)
%1 = constant(*const type, builtin)
%2 = constant(type, builtin)
%3 = const_ty(*const type)
%4 = constant(*const type, builtin.StackTrace)
%5 = constant(type, builtin.StackTrace)
%6 = const_ty(builtin.StackTrace)
%11 = const_ty(?u32)
%12 = const_ty(?u32)
%14 = constant(comptime_int, 1234)
%15 = constant(u32, 1234)
%16 = const_ty(?u32)
%17 = constant(?u32, 1234)
%18 = const_ty(?u32)
%20 = const_ty(*?u32)
%24 = constant(comptime_int, 2000)
%25 = constant(u32, 2000)
%27 = const_ty(*u32)
%30 = const_ty((inferred_alloc_mut))
%34 = const_ty(?u32)
%47 = constant(u32, 1)
%48 = const_ty(*u32)
%56 = const_ty(*comptime_int)
%61 = constant(u32, 0)
%65 = constant(u32, 0)
%69 = const_ty(*u32)
%73 = constant(u32, 0)
%74 = const_ty(*comptime_int)
%76 = const_ty(*u32)
%7!= save_err_return_trace_index()
%9!= dbg_block_begin()
%10!= dbg_stmt(2:5)
%13 = alloc(*?u32)
%19!= store(%13, %17!)
%21!= dbg_var_ptr(%13, a)
%22!= dbg_stmt(3:5)
%23 = alloc(*u32)
%26!= store(%23, %25!)
%28!= dbg_var_ptr(%23, b)
%29!= dbg_stmt(4:5)
%31 = alloc(*u32)
%32 = block(u32, {
%33!= dbg_stmt(4:17)
%35 = load(?u32, %13!)
%36 = is_non_null(%35)
%68!= cond_br(%36!, {
%65!
%37!= dbg_block_begin()
%38 = optional_payload(u32, %35!)
%39!= dbg_var_val(%38, d)
%40 = block(u32, {
%41!= dbg_block_begin()
%42!= dbg_stmt(5:13)
%43!= block(void, {
%44 = load(u32, %23!)
%45 = cmp_lt(%38!, %44!)
%54!= cond_br(%45!, {
%46!= dbg_block_begin()
- %49 = bitcast(*u32, %31)
- %50!= store(%49!, %47)
%51!= dbg_block_end()
%52!= br(%40, %47!)
}, {
%47!
%53!= br(%43, @Zir.Inst.Ref.void_value)
})
})
%55!= dbg_stmt(6:9)
- %57 = bitcast(*comptime_int, %31)
- %58!= store(%57!, @Zir.Inst.Ref.zero)
%59!= dbg_block_end()
%60!= br(%40, %61!)
})
%62!= dbg_block_end()
%63!= br(%32, %40!)
}, {
%47! %35! %23! %61!
%64!= dbg_block_begin()
%66!= dbg_block_end()
%67!= br(%32, %65!)
})
})
%70 = bitcast(*u32, %31)
%71!= store(%70!, %32!)
%77!= dbg_var_ptr(%31, c)
%78!= dbg_stmt(8:5)
%79!= load(u32, %31!)
%80!= dbg_block_end()
%82!= ret(@Zir.Inst.Ref.void_value)
# End Function AIR: repro.entry
The result location for c
, %31
, is stored to in each branch and again with the block result. The Air should only do one or the other. Additionally, the %57
and %58
instructions make absolutely no sense.
Appears to be related to the inferred_alloc. Both of the mentioned problems go away if using var c: u32 = ...