authorgravatar for adria.arrufat@gmail.comAdrià Arrufat <adria.arrufat@gmail.com> 2026-03-20 21:27:38+09:00
committergravatar for adria.arrufat@gmail.comAdrià Arrufat <adria.arrufat@gmail.com> 2026-03-20 21:27:38+09:00
logc10cb4470172f9c5db2a503af7608b2f784780dd
treeac04e14a28fadda3a52d66a85a1d17a1c78e8c7a
parentfeba59acf35fcb7dd6005b67b518872aa1039e83

Zir: unify float rounding instructions into round_op


5 files changed, 38 insertions(+), 36 deletions(-)

lib/std/zig/AstGen.zig+6-6
...@@ -9795,14 +9795,14 @@ fn floatRoundOp(...@@ -9795,14 +9795,14 @@ fn floatRoundOp(
9795 const operand = try expr(gz, scope, .{ .rl = .{ .coerced_ty = operand_ty_inst } }, operand_node);9795 const operand = try expr(gz, scope, .{ .rl = .{ .coerced_ty = operand_ty_inst } }, operand_node);
97969796
9797 try emitDbgStmt(gz, cursor);9797 try emitDbgStmt(gz, cursor);
9798 const cast_tag: Zir.Inst.Extended = switch (float_tag) {9798 const round_op: Zir.Inst.RoundOp = switch (float_tag) {
9799 .round => .round_cast,9799 .round => .round,
9800 .floor => .floor_cast,9800 .floor => .floor,
9801 .ceil => .ceil_cast,9801 .ceil => .ceil,
9802 .trunc => .trunc_cast,9802 .trunc => .trunc,
9803 else => unreachable,9803 else => unreachable,
9804 };9804 };
9805 const result = try gz.addExtendedPayload(cast_tag, Zir.Inst.BinNode{9805 const result = try gz.addExtendedPayloadSmall(.round_op, @intFromEnum(round_op), Zir.Inst.BinNode{
9806 .node = gz.nodeIndexToRelative(node),9806 .node = gz.nodeIndexToRelative(node),
9807 .lhs = dest_type,9807 .lhs = dest_type,
9808 .rhs = operand,9808 .rhs = operand,
lib/std/zig/Zir.zig+12-20
...@@ -2009,22 +2009,10 @@ pub const Inst = struct {...@@ -2009,22 +2009,10 @@ pub const Inst = struct {
2009 /// `operand` is payload index to `BinNode`.2009 /// `operand` is payload index to `BinNode`.
2010 /// `small` is unused.2010 /// `small` is unused.
2011 shl_with_overflow,2011 shl_with_overflow,
2012 /// Explicit rounding cast.2012 /// `@round`, `@floor`, `@ceil`, or `@trunc`, with a result type.
2013 /// `operand` is payload index to `Bin`.2013 /// `operand` is payload index to `BinNode`.
2014 /// `small` is unused.2014 /// `small` is a `RoundOp` representing the specific operation being performed.
2015 round_cast,2015 round_op,
2016 /// Explicit floor cast.
2017 /// `operand` is payload index to `Bin`.
2018 /// `small` is unused.
2019 floor_cast,
2020 /// Explicit ceil cast.
2021 /// `operand` is payload index to `Bin`.
2022 /// `small` is unused.
2023 ceil_cast,
2024 /// Explicit trunc cast.
2025 /// `operand` is payload index to `Bin`.
2026 /// `small` is unused.
2027 trunc_cast,
2028 /// Returns the type for the operand of a rounding op.2016 /// Returns the type for the operand of a rounding op.
2029 /// `operand` is `UnNode`.2017 /// `operand` is `UnNode`.
2030 /// `small` is unused.2018 /// `small` is unused.
...@@ -3253,6 +3241,13 @@ pub const Inst = struct {...@@ -3253,6 +3241,13 @@ pub const Inst = struct {
3253 string_to_union_field_attrs,3241 string_to_union_field_attrs,
3254 };3242 };
32553243
3244 pub const RoundOp = enum(u16) {
3245 round,
3246 floor,
3247 ceil,
3248 trunc,
3249 };
3250
3256 pub const UnNode = struct {3251 pub const UnNode = struct {
3257 node: Ast.Node.Offset,3252 node: Ast.Node.Offset,
3258 operand: Ref,3253 operand: Ref,
...@@ -4364,10 +4359,7 @@ fn findTrackableInner(...@@ -4364,10 +4359,7 @@ fn findTrackableInner(
4364 .sub_with_overflow,4359 .sub_with_overflow,
4365 .mul_with_overflow,4360 .mul_with_overflow,
4366 .shl_with_overflow,4361 .shl_with_overflow,
4367 .round_cast,4362 .round_op,
4368 .floor_cast,
4369 .ceil_cast,
4370 .trunc_cast,
4371 .c_undef,4363 .c_undef,
4372 .c_include,4364 .c_include,
4373 .c_define,4365 .c_define,
src/Sema.zig+9-5
...@@ -1405,10 +1405,7 @@ fn analyzeBodyInner(...@@ -1405,10 +1405,7 @@ fn analyzeBodyInner(
1405 .@"asm" => try sema.zirAsm( block, extended, false),1405 .@"asm" => try sema.zirAsm( block, extended, false),
1406 .asm_expr => try sema.zirAsm( block, extended, true),1406 .asm_expr => try sema.zirAsm( block, extended, true),
1407 .typeof_peer => try sema.zirTypeofPeer( block, extended, inst),1407 .typeof_peer => try sema.zirTypeofPeer( block, extended, inst),
1408 .round_cast => try sema.zirRoundCast( block, extended, .round),1408 .round_op => try sema.zirRoundCast( block, extended),
1409 .floor_cast => try sema.zirRoundCast( block, extended, .floor),
1410 .ceil_cast => try sema.zirRoundCast( block, extended, .ceil),
1411 .trunc_cast => try sema.zirRoundCast( block, extended, .truncate),
1412 .round_op_ty => try sema.zirRoundOpType( block, extended),1409 .round_op_ty => try sema.zirRoundOpType( block, extended),
1413 .compile_log => try sema.zirCompileLog( block, extended),1410 .compile_log => try sema.zirCompileLog( block, extended),
1414 .min_multi => try sema.zirMinMaxMulti( block, extended, .min),1411 .min_multi => try sema.zirMinMaxMulti( block, extended, .min),
...@@ -20854,7 +20851,6 @@ fn zirRoundCast(...@@ -20854,7 +20851,6 @@ fn zirRoundCast(
20854 sema: *Sema,20851 sema: *Sema,
20855 block: *Block,20852 block: *Block,
20856 extended: Zir.Inst.Extended.InstData,20853 extended: Zir.Inst.Extended.InstData,
20857 mode: IntFromFloatMode,
20858) CompileError!Air.Inst.Ref {20854) CompileError!Air.Inst.Ref {
20859 const pt = sema.pt;20855 const pt = sema.pt;
20860 const zcu = pt.zcu;20856 const zcu = pt.zcu;
...@@ -20864,6 +20860,14 @@ fn zirRoundCast(...@@ -20864,6 +20860,14 @@ fn zirRoundCast(
2086420860
20865 const operand = sema.resolveInst(extra.rhs);20861 const operand = sema.resolveInst(extra.rhs);
2086620862
20863 const round_op: Zir.Inst.RoundOp = @enumFromInt(extended.small);
20864 const mode: IntFromFloatMode = switch (round_op) {
20865 .round => .round,
20866 .floor => .floor,
20867 .ceil => .ceil,
20868 .trunc => .truncate,
20869 };
20870
20867 const dest_ty = (try sema.resolveTypeOrPoison(block, src, extra.lhs) orelse switch (mode) {20871 const dest_ty = (try sema.resolveTypeOrPoison(block, src, extra.lhs) orelse switch (mode) {
20868 // zig fmt: off20872 // zig fmt: off
20869 .round => return sema.unaryMath(block, operand_src, operand, .round, Value.round),20873 .round => return sema.unaryMath(block, operand_src, operand, .round, Value.round),
src/print_zir.zig+11-4
...@@ -585,10 +585,6 @@ const Writer = struct {...@@ -585,10 +585,6 @@ const Writer = struct {
585 .prefetch,585 .prefetch,
586 .c_va_arg,586 .c_va_arg,
587 .reify_enum_value_slice_ty,587 .reify_enum_value_slice_ty,
588 .round_cast,
589 .floor_cast,
590 .ceil_cast,
591 .trunc_cast,
592 => {588 => {
593 const inst_data = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;589 const inst_data = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
594 try self.writeInstRef(stream, inst_data.lhs);590 try self.writeInstRef(stream, inst_data.lhs);
...@@ -598,6 +594,17 @@ const Writer = struct {...@@ -598,6 +594,17 @@ const Writer = struct {
598 try self.writeSrcNode(stream, inst_data.node);594 try self.writeSrcNode(stream, inst_data.node);
599 },595 },
600596
597 .round_op => {
598 const round_op: Zir.Inst.RoundOp = @enumFromInt(extended.small);
599 const inst_data = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
600 try stream.print("{s}, ", .{@tagName(round_op)});
601 try self.writeInstRef(stream, inst_data.lhs);
602 try stream.writeAll(", ");
603 try self.writeInstRef(stream, inst_data.rhs);
604 try stream.writeAll(")) ");
605 try self.writeSrcNode(stream, inst_data.node);
606 },
607
601 .reify_slice_arg_ty => {608 .reify_slice_arg_ty => {
602 const reify_slice_arg_info: Zir.Inst.ReifySliceArgInfo = @enumFromInt(extended.small);609 const reify_slice_arg_info: Zir.Inst.ReifySliceArgInfo = @enumFromInt(extended.small);
603 const extra = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;610 const extra = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;
test/behavior/cast.zig-1
...@@ -1361,7 +1361,6 @@ test "comptime float casts" {...@@ -1361,7 +1361,6 @@ test "comptime float casts" {
1361 try expectIntFromFloat(comptime_int, 1234, i16, 1234);1361 try expectIntFromFloat(comptime_int, 1234, i16, 1234);
1362 try expectIntFromFloat(comptime_float, 12.3, comptime_int, 12);1362 try expectIntFromFloat(comptime_float, 12.3, comptime_int, 12);
13631363
1364 try expectRoundCast(comptime_int, 1234, i16, 1234);
1365 try expectRoundCast(comptime_float, 12.3, comptime_int, 12);1364 try expectRoundCast(comptime_float, 12.3, comptime_int, 12);
13661365
1367 try expectFloorCast(comptime_float, 12.3, comptime_int, 12);1366 try expectFloorCast(comptime_float, 12.3, comptime_int, 12);