authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2021-08-17 11:06:55+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-08-20 19:06:30-04:00
log5806c386eb640247f6aa8983132c6b193195ea4a
tree08c05374dc59894c46f7578894a1f4c6af7d9489
parente48d7bbb99a81d9e6058aa764266dcc3dbe71644

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.

2 files changed, 30 insertions(+), 0 deletions(-)

src/codegen.zig+14
......@@ -973,6 +973,20 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
973973 log.debug("%{d} => {}", .{ inst, result });
974974 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
975975 branch.inst_table.putAssumeCapacityNoClobber(inst, result);
976
977 switch (result) {
978 .register => |reg| {
979 // In some cases (such as bitcast), an operand
980 // may be the same MCValue as the result. If
981 // that operand died and was a register, it
982 // was freed by processDeath. We have to
983 // "re-allocate" the register.
984 if (self.register_manager.isRegFree(reg)) {
985 self.register_manager.getRegAssumeFree(reg, inst);
986 }
987 },
988 else => {},
989 }
976990 }
977991 self.finishAirBookkeeping();
978992 }
test/stage2/arm.zig+16
......@@ -361,6 +361,22 @@ pub fn addCases(ctx: *TestContext) !void {
361361 ,
362362 "",
363363 );
364
365 case.addCompareOutput(
366 \\const Number = enum { one, two, three };
367 \\
368 \\pub fn main() void {
369 \\ var x: Number = .one;
370 \\ var y = Number.two;
371 \\ assert(@enumToInt(x) < @enumToInt(y));
372 \\}
373 \\
374 \\fn assert(ok: bool) void {
375 \\ if (!ok) unreachable; // assertion failure
376 \\}
377 ,
378 "",
379 );
364380 }
365381
366382 {