| ... | @@ -4296,9 +4296,13 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4296,9 +4296,13 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4296 | } | 4296 | } |
| 4297 | | 4297 | |
| 4298 | try f.object.indent_writer.insertNewline(); | 4298 | try f.object.indent_writer.insertNewline(); |
| 4299 | // label might be unused, add a dummy goto | 4299 | |
| 4300 | // label must be followed by an expression, add an empty one. | 4300 | // noreturn blocks have no `br` instructions reaching them, so we don't want a label |
| 4301 | try writer.print("goto zig_block_{d};\nzig_block_{d}: (void)0;\n", .{ block_id, block_id }); | 4301 | if (!f.air.typeOfIndex(inst).isNoReturn()) { |
| | 4302 | // label must be followed by an expression, include an empty one. |
| | 4303 | try writer.print("zig_block_{d}:;\n", .{block_id}); |
| | 4304 | } |
| | 4305 | |
| 4302 | return result; | 4306 | return result; |
| 4303 | } | 4307 | } |
| 4304 | | 4308 | |
| ... | @@ -4350,7 +4354,7 @@ fn lowerTry( | ... | @@ -4350,7 +4354,7 @@ fn lowerTry( |
| 4350 | else | 4354 | else |
| 4351 | try f.writeCValueMember(writer, err_union, .{ .identifier = "error" }); | 4355 | try f.writeCValueMember(writer, err_union, .{ .identifier = "error" }); |
| 4352 | } | 4356 | } |
| 4353 | try writer.writeByte(')'); | 4357 | try writer.writeAll(") "); |
| 4354 | | 4358 | |
| 4355 | try genBodyResolveState(f, inst, liveness_condbr.else_deaths, body, false); | 4359 | try genBodyResolveState(f, inst, liveness_condbr.else_deaths, body, false); |
| 4356 | try f.object.indent_writer.insertNewline(); | 4360 | try f.object.indent_writer.insertNewline(); |
| ... | @@ -4422,7 +4426,11 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4422,7 +4426,11 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4422 | | 4426 | |
| 4423 | const local = try f.allocLocal(inst, dest_ty); | 4427 | const local = try f.allocLocal(inst, dest_ty); |
| 4424 | | 4428 | |
| | 4429 | // If the assignment looks like 'x = x', we don't need it |
| | 4430 | const can_elide = operand == .local and operand.local == local.new_local; |
| | 4431 | |
| 4425 | if (operand_ty.isAbiInt() and dest_ty.isAbiInt()) { | 4432 | if (operand_ty.isAbiInt() and dest_ty.isAbiInt()) { |
| | 4433 | if (can_elide) return local; |
| 4426 | const src_info = dest_ty.intInfo(target); | 4434 | const src_info = dest_ty.intInfo(target); |
| 4427 | const dest_info = operand_ty.intInfo(target); | 4435 | const dest_info = operand_ty.intInfo(target); |
| 4428 | if (src_info.signedness == dest_info.signedness and | 4436 | if (src_info.signedness == dest_info.signedness and |
| ... | @@ -4437,6 +4445,7 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4437,6 +4445,7 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4437 | } | 4445 | } |
| 4438 | | 4446 | |
| 4439 | if (dest_ty.isPtrAtRuntime() and operand_ty.isPtrAtRuntime()) { | 4447 | if (dest_ty.isPtrAtRuntime() and operand_ty.isPtrAtRuntime()) { |
| | 4448 | if (can_elide) return local; |
| 4440 | try f.writeCValue(writer, local, .Other); | 4449 | try f.writeCValue(writer, local, .Other); |
| 4441 | try writer.writeAll(" = ("); | 4450 | try writer.writeAll(" = ("); |
| 4442 | try f.renderType(writer, dest_ty); | 4451 | try f.renderType(writer, dest_ty); |
| ... | @@ -5468,6 +5477,12 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5468,6 +5477,12 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5468 | const error_ty = error_union_ty.errorUnionSet(); | 5477 | const error_ty = error_union_ty.errorUnionSet(); |
| 5469 | const payload_ty = error_union_ty.errorUnionPayload(); | 5478 | const payload_ty = error_union_ty.errorUnionPayload(); |
| 5470 | const local = try f.allocLocal(inst, inst_ty); | 5479 | const local = try f.allocLocal(inst, inst_ty); |
| | 5480 | |
| | 5481 | if (!payload_ty.hasRuntimeBits() and operand == .local and operand.local == local.new_local) { |
| | 5482 | // The store will be 'x = x'; elide it. |
| | 5483 | return local; |
| | 5484 | } |
| | 5485 | |
| 5471 | const writer = f.object.writer(); | 5486 | const writer = f.object.writer(); |
| 5472 | try f.writeCValue(writer, local, .Other); | 5487 | try f.writeCValue(writer, local, .Other); |
| 5473 | try writer.writeAll(" = "); | 5488 | try writer.writeAll(" = "); |
| ... | @@ -5565,6 +5580,12 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5565,6 +5580,12 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5565 | | 5580 | |
| 5566 | const writer = f.object.writer(); | 5581 | const writer = f.object.writer(); |
| 5567 | const local = try f.allocLocal(inst, inst_ty); | 5582 | const local = try f.allocLocal(inst, inst_ty); |
| | 5583 | |
| | 5584 | if (repr_is_err and err == .local and err.local == local.new_local) { |
| | 5585 | // The store will be 'x = x'; elide it. |
| | 5586 | return local; |
| | 5587 | } |
| | 5588 | |
| 5568 | if (!repr_is_err) { | 5589 | if (!repr_is_err) { |
| 5569 | const a = try Assignment.start(f, writer, payload_ty); | 5590 | const a = try Assignment.start(f, writer, payload_ty); |
| 5570 | try f.writeCValueMember(writer, local, .{ .identifier = "payload" }); | 5591 | try f.writeCValueMember(writer, local, .{ .identifier = "payload" }); |