stage2 codegen: re-allocate result register in finishAir

In some cases (such as bitcast), an operand may be the same MCValue as
the result. If that operand died and was a register, it was freed by
processDeath. We have to "re-allocate" the register.
This commit is contained in:
joachimschmidt557 2021-08-17 11:06:55 +02:00 committed by Andrew Kelley
parent e48d7bbb99
commit 5806c386eb
2 changed files with 30 additions and 0 deletions

View File

@ -973,6 +973,20 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
log.debug("%{d} => {}", .{ inst, result });
const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
branch.inst_table.putAssumeCapacityNoClobber(inst, result);
switch (result) {
.register => |reg| {
// In some cases (such as bitcast), an operand
// may be the same MCValue as the result. If
// that operand died and was a register, it
// was freed by processDeath. We have to
// "re-allocate" the register.
if (self.register_manager.isRegFree(reg)) {
self.register_manager.getRegAssumeFree(reg, inst);
}
},
else => {},
}
}
self.finishAirBookkeeping();
}

View File

@ -361,6 +361,22 @@ pub fn addCases(ctx: *TestContext) !void {
,
"",
);
case.addCompareOutput(
\\const Number = enum { one, two, three };
\\
\\pub fn main() void {
\\ var x: Number = .one;
\\ var y = Number.two;
\\ assert(@enumToInt(x) < @enumToInt(y));
\\}
\\
\\fn assert(ok: bool) void {
\\ if (!ok) unreachable; // assertion failure
\\}
,
"",
);
}
{