zig icon indicating copy to clipboard operation
zig copied to clipboard

Sema: strange Air emitted by `test "result location with inferred type ends up being pointer to comptime_int"`

Open jacobly0 opened this issue 2 years ago • 1 comments

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.

jacobly0 avatar Nov 02 '22 07:11 jacobly0

Appears to be related to the inferred_alloc. Both of the mentioned problems go away if using var c: u32 = ...

topolarity avatar Nov 02 '22 11:11 topolarity