mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 12:59:04 +00:00
Sema: avoid @intToFloat for f80 which breaks on non-x86 targets
Currently Zig lowers `@intToFloat` for f80 incorrectly on non-x86 targets: ``` broken LLVM module found: UIToFP result must be FP or FP vector %62 = uitofp i64 %61 to i128 SIToFP result must be FP or FP vector %66 = sitofp i64 %65 to i128 ``` This happens because on such targets, we use i128 instead of x86_fp80 in order to avoid "LLVM ERROR: Cannot select". `@intToFloat` must be lowered differently to account for this difference as well.
This commit is contained in:
parent
3bcce5f6d1
commit
65b6faa048
@ -9432,11 +9432,14 @@ static void define_builtin_types(CodeGen *g) {
|
||||
if (target_has_f80(g->zig_target)) {
|
||||
entry->llvm_type = LLVMX86FP80Type();
|
||||
} else {
|
||||
// We use i128 here instead of x86_fp80 because on targets such as arm,
|
||||
// LLVM will give "ERROR: Cannot select" for any instructions involving
|
||||
// the x86_fp80 type.
|
||||
entry->llvm_type = get_int_type(g, false, 128)->llvm_type;
|
||||
}
|
||||
entry->size_in_bits = 8 * 16;
|
||||
entry->abi_size = 16;
|
||||
entry->abi_align = 16;
|
||||
entry->abi_size = 16; // matches LLVMABISizeOfType(LLVMX86FP80Type())
|
||||
entry->abi_align = 16; // matches LLVMABIAlignmentOfType(LLVMX86FP80Type())
|
||||
buf_init_from_str(&entry->name, "f80");
|
||||
entry->data.floating.bit_count = 80;
|
||||
|
||||
|
||||
@ -1120,8 +1120,8 @@ pub const Value = extern union {
|
||||
fn floatReadFromMemory(comptime F: type, target: Target, buffer: []const u8) F {
|
||||
if (F == f80) {
|
||||
// TODO: use std.math.F80Repr?
|
||||
const big_int = std.mem.readInt(u128, buffer[0..16], target.cpu.arch.endian());
|
||||
const int = @truncate(u80, big_int);
|
||||
const int = std.mem.readInt(u128, buffer[0..16], target.cpu.arch.endian());
|
||||
// TODO shouldn't this be a bitcast from u80 to f80 instead of u128 to f80?
|
||||
return @bitCast(F, int);
|
||||
}
|
||||
const Int = @Type(.{ .Int = .{
|
||||
@ -1143,8 +1143,18 @@ pub const Value = extern union {
|
||||
|
||||
.zero => 0,
|
||||
.one => 1,
|
||||
.int_u64 => @intToFloat(T, val.castTag(.int_u64).?.data),
|
||||
.int_i64 => @intToFloat(T, val.castTag(.int_i64).?.data),
|
||||
.int_u64 => {
|
||||
if (T == f80) {
|
||||
@panic("TODO we can't lower this properly on non-x86 llvm backend yet");
|
||||
}
|
||||
return @intToFloat(T, val.castTag(.int_u64).?.data);
|
||||
},
|
||||
.int_i64 => {
|
||||
if (T == f80) {
|
||||
@panic("TODO we can't lower this properly on non-x86 llvm backend yet");
|
||||
}
|
||||
return @intToFloat(T, val.castTag(.int_i64).?.data);
|
||||
},
|
||||
|
||||
.int_big_positive => @floatCast(T, bigIntToFloat(val.castTag(.int_big_positive).?.data, true)),
|
||||
.int_big_negative => @floatCast(T, bigIntToFloat(val.castTag(.int_big_negative).?.data, false)),
|
||||
@ -2202,7 +2212,9 @@ pub const Value = extern union {
|
||||
16 => return Value.Tag.float_16.create(arena, @intToFloat(f16, x)),
|
||||
32 => return Value.Tag.float_32.create(arena, @intToFloat(f32, x)),
|
||||
64 => return Value.Tag.float_64.create(arena, @intToFloat(f64, x)),
|
||||
80 => return Value.Tag.float_80.create(arena, @intToFloat(f80, x)),
|
||||
// We can't lower this properly on non-x86 llvm backends yet
|
||||
//80 => return Value.Tag.float_80.create(arena, @intToFloat(f80, x)),
|
||||
80 => @panic("TODO f80 intToFloat"),
|
||||
128 => return Value.Tag.float_128.create(arena, @intToFloat(f128, x)),
|
||||
else => unreachable,
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user