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
The following code causes the optimizer to perform an illegal deduplication:
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_ofinstruction that is used in both calls to the functioninc. 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 registerrdi