Skip to content

Illegal IR decl deduplication #15

@48cf

Description

@48cf

The following code causes the optimizer to perform an illegal deduplication:

fn inc(foo: *u32) void {
    foo.* += 1;
}

fn main() noreturn {
    var foo: u32 = 0;

    loop {
        if (foo < 10) {
            inc(foo.&);
        }

        inc(foo.&);
    }
}

Block 1 is the function's entry block, block 5 is the loop's first body block, which does the if comparison and jumps to block 5, which is the if's taken branch, or block 7, which is the continuation of block 3. In block 5 the decl $13 is the addr_of instruction that is used in both calls to the function inc. You can see that the later call does not take the address of the local variable taken again, instead, it uses a decl $13 which it shouldn't have access to. That generates bad code which won't actually load the right value into the register rdi

Block#1:
  $1 = enter_function(16)
  $5 = stack(4)
  $6 = store($5, #0)
  $7 = goto(Block#3)

Block#3:
  $10 = u64 less($5, #10)
  $11 = if($10, Block#5, Block#7)

Block#5:
  $13 (rbx) = u64 addr_of($5)
  $18 (rdi) = u64 copy($13)
  $15 (rax) = u64 call(inc, $18)
  $19 (rax) = u64 copy($15)
  $16 = goto(Block#7)

Block#7:
  $37 (rdi) = u64 copy($13)
  $21 (rax) = u64 call(inc, $37)
  $36 (rax) = u64 copy($21)
  $22 = goto(Block#3)
.text:0000000000100008 main            proc near
.text:0000000000100008
.text:0000000000100008 var_4           = dword ptr -4
.text:0000000000100008
.text:0000000000100008                 push    rbx
.text:0000000000100009                 push    rbp
.text:000000000010000A                 mov     rbp, rsp
.text:000000000010000D                 sub     rsp, 10h
.text:0000000000100011                 mov     [rbp+var_4], 0
.text:0000000000100018
.text:0000000000100018 loc_100018:                             ; CODE XREF: main+2F↓j
.text:0000000000100018                 cmp     qword ptr [rbp+var_4], 0Ah
.text:000000000010001D                 jnb     loc_10002F
.text:0000000000100023                 lea     rbx, [rbp+var_4]
.text:0000000000100027                 mov     rdi, rbx
.text:000000000010002A                 call    inc
.text:000000000010002F
.text:000000000010002F loc_10002F:                             ; CODE XREF: main+15↑j
.text:000000000010002F                 mov     rdi, rbx        ; The value of rbx is invalid here, if the branch wasn't taken
.text:0000000000100032                 call    inc
.text:0000000000100037                 jmp     short loc_100018
.text:0000000000100037 main            endp

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions