Commit dbfa3238fe

Jacob Young <jacobly0@users.noreply.github.com>
2024-02-22 23:51:35
Builder: fix float constants in llvm ir
1 parent 83e66d3
Changed files (2)
src
arch
codegen
src/arch/x86_64/CodeGen.zig
@@ -16683,36 +16683,44 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
                             else => null,
                         };
                         defer if (elem_lock) |lock| self.register_manager.unlockReg(lock);
-                        const elem_reg = registerAlias(
-                            try self.copyToTmpRegister(elem_ty, mat_elem_mcv),
-                            elem_abi_size,
-                        );
+
                         const elem_extra_bits = self.regExtraBits(elem_ty);
-                        if (elem_bit_off < elem_extra_bits) {
-                            try self.truncateRegister(elem_ty, elem_reg);
+                        {
+                            const temp_reg = try self.copyToTmpRegister(elem_ty, mat_elem_mcv);
+                            const temp_alias = registerAlias(temp_reg, elem_abi_size);
+                            const temp_lock = self.register_manager.lockRegAssumeUnused(temp_reg);
+                            defer self.register_manager.unlockReg(temp_lock);
+
+                            if (elem_bit_off < elem_extra_bits) {
+                                try self.truncateRegister(elem_ty, temp_alias);
+                            }
+                            if (elem_bit_off > 0) try self.genShiftBinOpMir(
+                                .{ ._l, .sh },
+                                elem_ty,
+                                .{ .register = temp_alias },
+                                Type.u8,
+                                .{ .immediate = elem_bit_off },
+                            );
+                            try self.genBinOpMir(
+                                .{ ._, .@"or" },
+                                elem_ty,
+                                .{ .load_frame = .{ .index = frame_index, .off = elem_byte_off } },
+                                .{ .register = temp_alias },
+                            );
                         }
-                        if (elem_bit_off > 0) try self.genShiftBinOpMir(
-                            .{ ._l, .sh },
-                            elem_ty,
-                            .{ .register = elem_reg },
-                            Type.u8,
-                            .{ .immediate = elem_bit_off },
-                        );
-                        try self.genBinOpMir(
-                            .{ ._, .@"or" },
-                            elem_ty,
-                            .{ .load_frame = .{ .index = frame_index, .off = elem_byte_off } },
-                            .{ .register = elem_reg },
-                        );
                         if (elem_bit_off > elem_extra_bits) {
-                            const reg = try self.copyToTmpRegister(elem_ty, mat_elem_mcv);
+                            const temp_reg = try self.copyToTmpRegister(elem_ty, mat_elem_mcv);
+                            const temp_alias = registerAlias(temp_reg, elem_abi_size);
+                            const temp_lock = self.register_manager.lockRegAssumeUnused(temp_reg);
+                            defer self.register_manager.unlockReg(temp_lock);
+
                             if (elem_extra_bits > 0) {
-                                try self.truncateRegister(elem_ty, registerAlias(reg, elem_abi_size));
+                                try self.truncateRegister(elem_ty, temp_alias);
                             }
                             try self.genShiftBinOpMir(
                                 .{ ._r, .sh },
                                 elem_ty,
-                                .{ .register = reg },
+                                .{ .register = temp_reg },
                                 Type.u8,
                                 .{ .immediate = elem_abi_bits - elem_bit_off },
                             );
@@ -16723,7 +16731,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
                                     .index = frame_index,
                                     .off = elem_byte_off + @as(i32, @intCast(elem_abi_size)),
                                 } },
-                                .{ .register = reg },
+                                .{ .register = temp_alias },
                             );
                         }
                     }
src/codegen/llvm/Builder.zig
@@ -7220,17 +7220,31 @@ pub const Constant = enum(u32) {
                                 };
                             }
                         };
+                        const Mantissa64 = std.meta.FieldType(Float.Repr(f64), .mantissa);
                         const Exponent32 = std.meta.FieldType(Float.Repr(f32), .exponent);
                         const Exponent64 = std.meta.FieldType(Float.Repr(f64), .exponent);
+
                         const repr: Float.Repr(f32) = @bitCast(item.data);
+                        const denormal_shift = switch (repr.exponent) {
+                            std.math.minInt(Exponent32) => @as(
+                                std.math.Log2Int(Mantissa64),
+                                @clz(repr.mantissa),
+                            ) + 1,
+                            else => 0,
+                        };
                         try writer.print("0x{X:0>16}", .{@as(u64, @bitCast(Float.Repr(f64){
                             .mantissa = std.math.shl(
-                                std.meta.FieldType(Float.Repr(f64), .mantissa),
+                                Mantissa64,
                                 repr.mantissa,
-                                std.math.floatMantissaBits(f64) - std.math.floatMantissaBits(f32),
+                                std.math.floatMantissaBits(f64) - std.math.floatMantissaBits(f32) +
+                                    denormal_shift,
                             ),
                             .exponent = switch (repr.exponent) {
-                                std.math.minInt(Exponent32) => std.math.minInt(Exponent64),
+                                std.math.minInt(Exponent32) => if (repr.mantissa > 0)
+                                    @as(Exponent64, std.math.floatExponentMin(f32) +
+                                        std.math.floatExponentMax(f64)) - denormal_shift
+                                else
+                                    std.math.minInt(Exponent64),
                                 else => @as(Exponent64, repr.exponent) +
                                     (std.math.floatExponentMax(f64) - std.math.floatExponentMax(f32)),
                                 std.math.maxInt(Exponent32) => std.math.maxInt(Exponent64),
@@ -9920,7 +9934,7 @@ pub fn printUnbuffered(
                         .scope = extra.file,
                         .file = extra.file,
                         .line = extra.line,
-                        .type = null,
+                        .type = extra.ty,
                         .scopeLine = extra.scope_line,
                         .containingType = null,
                         .virtualIndex = null,