| ... | @@ -4291,9 +4291,13 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4291,9 +4291,13 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4291 | } | 4291 | } |
| 4292 | | 4292 | |
| 4293 | try f.object.indent_writer.insertNewline(); | 4293 | try f.object.indent_writer.insertNewline(); |
| 4294 | // label might be unused, add a dummy goto | 4294 | |
| 4295 | // label must be followed by an expression, add an empty one. | 4295 | // noreturn blocks have no `br` instructions reaching them, so we don't want a label |
| 4296 | try writer.print("goto zig_block_{d};\nzig_block_{d}: (void)0;\n", .{ block_id, block_id }); | 4296 | if (!f.air.typeOfIndex(inst).isNoReturn()) { |
| | 4297 | // label must be followed by an expression, include an empty one. |
| | 4298 | try writer.print("zig_block_{d}:;\n", .{block_id}); |
| | 4299 | } |
| | 4300 | |
| 4297 | return result; | 4301 | return result; |
| 4298 | } | 4302 | } |
| 4299 | | 4303 | |
| ... | @@ -4345,7 +4349,7 @@ fn lowerTry( | ... | @@ -4345,7 +4349,7 @@ fn lowerTry( |
| 4345 | else | 4349 | else |
| 4346 | try f.writeCValueMember(writer, err_union, .{ .identifier = "error" }); | 4350 | try f.writeCValueMember(writer, err_union, .{ .identifier = "error" }); |
| 4347 | } | 4351 | } |
| 4348 | try writer.writeByte(')'); | 4352 | try writer.writeAll(") "); |
| 4349 | | 4353 | |
| 4350 | try genBodyResolveState(f, inst, liveness_condbr.else_deaths, body, false); | 4354 | try genBodyResolveState(f, inst, liveness_condbr.else_deaths, body, false); |
| 4351 | try f.object.indent_writer.insertNewline(); | 4355 | try f.object.indent_writer.insertNewline(); |
| ... | @@ -4417,7 +4421,11 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4417,7 +4421,11 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4417 | | 4421 | |
| 4418 | const local = try f.allocLocal(inst, dest_ty); | 4422 | const local = try f.allocLocal(inst, dest_ty); |
| 4419 | | 4423 | |
| | 4424 | // If the assignment looks like 'x = x', we don't need it |
| | 4425 | const can_elide = operand == .local and operand.local == local.new_local; |
| | 4426 | |
| 4420 | if (operand_ty.isAbiInt() and dest_ty.isAbiInt()) { | 4427 | if (operand_ty.isAbiInt() and dest_ty.isAbiInt()) { |
| | 4428 | if (can_elide) return local; |
| 4421 | const src_info = dest_ty.intInfo(target); | 4429 | const src_info = dest_ty.intInfo(target); |
| 4422 | const dest_info = operand_ty.intInfo(target); | 4430 | const dest_info = operand_ty.intInfo(target); |
| 4423 | if (src_info.signedness == dest_info.signedness and | 4431 | if (src_info.signedness == dest_info.signedness and |
| ... | @@ -4432,6 +4440,7 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4432,6 +4440,7 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4432 | } | 4440 | } |
| 4433 | | 4441 | |
| 4434 | if (dest_ty.isPtrAtRuntime() and operand_ty.isPtrAtRuntime()) { | 4442 | if (dest_ty.isPtrAtRuntime() and operand_ty.isPtrAtRuntime()) { |
| | 4443 | if (can_elide) return local; |
| 4435 | try f.writeCValue(writer, local, .Other); | 4444 | try f.writeCValue(writer, local, .Other); |
| 4436 | try writer.writeAll(" = ("); | 4445 | try writer.writeAll(" = ("); |
| 4437 | try f.renderType(writer, dest_ty); | 4446 | try f.renderType(writer, dest_ty); |
| ... | @@ -5463,6 +5472,12 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5463,6 +5472,12 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5463 | const error_ty = error_union_ty.errorUnionSet(); | 5472 | const error_ty = error_union_ty.errorUnionSet(); |
| 5464 | const payload_ty = error_union_ty.errorUnionPayload(); | 5473 | const payload_ty = error_union_ty.errorUnionPayload(); |
| 5465 | const local = try f.allocLocal(inst, inst_ty); | 5474 | const local = try f.allocLocal(inst, inst_ty); |
| | 5475 | |
| | 5476 | if (!payload_ty.hasRuntimeBits() and operand == .local and operand.local == local.new_local) { |
| | 5477 | // The store will be 'x = x'; elide it. |
| | 5478 | return local; |
| | 5479 | } |
| | 5480 | |
| 5466 | const writer = f.object.writer(); | 5481 | const writer = f.object.writer(); |
| 5467 | try f.writeCValue(writer, local, .Other); | 5482 | try f.writeCValue(writer, local, .Other); |
| 5468 | try writer.writeAll(" = "); | 5483 | try writer.writeAll(" = "); |
| ... | @@ -5560,6 +5575,12 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5560,6 +5575,12 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5560 | | 5575 | |
| 5561 | const writer = f.object.writer(); | 5576 | const writer = f.object.writer(); |
| 5562 | const local = try f.allocLocal(inst, inst_ty); | 5577 | const local = try f.allocLocal(inst, inst_ty); |
| | 5578 | |
| | 5579 | if (repr_is_err and err == .local and err.local == local.new_local) { |
| | 5580 | // The store will be 'x = x'; elide it. |
| | 5581 | return local; |
| | 5582 | } |
| | 5583 | |
| 5563 | if (!repr_is_err) { | 5584 | if (!repr_is_err) { |
| 5564 | const a = try Assignment.start(f, writer, payload_ty); | 5585 | const a = try Assignment.start(f, writer, payload_ty); |
| 5565 | try f.writeCValueMember(writer, local, .{ .identifier = "payload" }); | 5586 | try f.writeCValueMember(writer, local, .{ .identifier = "payload" }); |