authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-13 19:15:19-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-07-13 19:15:19-04:00
log1653a9b2597c66cbcc88ea75d8a4b88c163584a5
tree9cbe5d66e5088006ac4b5d5b4861a3b8b25a7a54
parentfad95741db7529bbad873fb330c25d64ac765340
parent92bc3cbe27792be0300fb5f104c011a11f3cf40f
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #12098 from ziglang/llvm-riscv64

LLVM: implement signext/zeroext attributes

8 files changed, 148 insertions(+), 62 deletions(-)

lib/compiler_rt/common.zig+5-1
...@@ -68,7 +68,11 @@ pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) nore...@@ -68,7 +68,11 @@ pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) nore
68/// need for extending them to wider fp types.68/// need for extending them to wider fp types.
69/// TODO remove this; do this type selection in the language rather than69/// TODO remove this; do this type selection in the language rather than
70/// here in compiler-rt.70/// here in compiler-rt.
71pub const F16T = if (builtin.cpu.arch.isAARCH64()) f16 else u16;71pub const F16T = switch (builtin.cpu.arch) {
72 .aarch64, .aarch64_be, .aarch64_32 => f16,
73 .riscv64 => if (builtin.zig_backend == .stage1) u16 else f16,
74 else => u16,
75};
7276
73pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {77pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
74 switch (Z) {78 switch (Z) {
lib/std/math/float.zig+17-17
...@@ -3,20 +3,20 @@ const assert = std.debug.assert;...@@ -3,20 +3,20 @@ const assert = std.debug.assert;
3const expect = std.testing.expect;3const expect = std.testing.expect;
44
5/// Creates a raw "1.0" mantissa for floating point type T. Used to dedupe f80 logic.5/// Creates a raw "1.0" mantissa for floating point type T. Used to dedupe f80 logic.
6fn mantissaOne(comptime T: type) comptime_int {6inline fn mantissaOne(comptime T: type) comptime_int {
7 return if (@typeInfo(T).Float.bits == 80) 1 << floatFractionalBits(T) else 0;7 return if (@typeInfo(T).Float.bits == 80) 1 << floatFractionalBits(T) else 0;
8}8}
99
10/// Creates floating point type T from an unbiased exponent and raw mantissa.10/// Creates floating point type T from an unbiased exponent and raw mantissa.
11fn reconstructFloat(comptime T: type, exponent: comptime_int, mantissa: comptime_int) T {11inline fn reconstructFloat(comptime T: type, exponent: comptime_int, mantissa: comptime_int) T {
12 const TBits = std.meta.Int(.unsigned, @bitSizeOf(T));12 const TBits = @Type(.{ .Int = .{ .signedness = .unsigned, .bits = @bitSizeOf(T) } });
13 const biased_exponent = @as(TBits, exponent + floatExponentMax(T));13 const biased_exponent = @as(TBits, exponent + floatExponentMax(T));
14 return @bitCast(T, (biased_exponent << floatMantissaBits(T)) | @as(TBits, mantissa));14 return @bitCast(T, (biased_exponent << floatMantissaBits(T)) | @as(TBits, mantissa));
15}15}
1616
17/// Returns the number of bits in the exponent of floating point type T.17/// Returns the number of bits in the exponent of floating point type T.
18pub fn floatExponentBits(comptime T: type) comptime_int {18pub inline fn floatExponentBits(comptime T: type) comptime_int {
19 assert(@typeInfo(T) == .Float);19 comptime assert(@typeInfo(T) == .Float);
2020
21 return switch (@typeInfo(T).Float.bits) {21 return switch (@typeInfo(T).Float.bits) {
22 16 => 5,22 16 => 5,
...@@ -29,8 +29,8 @@ pub fn floatExponentBits(comptime T: type) comptime_int {...@@ -29,8 +29,8 @@ pub fn floatExponentBits(comptime T: type) comptime_int {
29}29}
3030
31/// Returns the number of bits in the mantissa of floating point type T.31/// Returns the number of bits in the mantissa of floating point type T.
32pub fn floatMantissaBits(comptime T: type) comptime_int {32pub inline fn floatMantissaBits(comptime T: type) comptime_int {
33 assert(@typeInfo(T) == .Float);33 comptime assert(@typeInfo(T) == .Float);
3434
35 return switch (@typeInfo(T).Float.bits) {35 return switch (@typeInfo(T).Float.bits) {
36 16 => 10,36 16 => 10,
...@@ -43,8 +43,8 @@ pub fn floatMantissaBits(comptime T: type) comptime_int {...@@ -43,8 +43,8 @@ pub fn floatMantissaBits(comptime T: type) comptime_int {
43}43}
4444
45/// Returns the number of fractional bits in the mantissa of floating point type T.45/// Returns the number of fractional bits in the mantissa of floating point type T.
46pub fn floatFractionalBits(comptime T: type) comptime_int {46pub inline fn floatFractionalBits(comptime T: type) comptime_int {
47 assert(@typeInfo(T) == .Float);47 comptime assert(@typeInfo(T) == .Float);
4848
49 // standard IEEE floats have an implicit 0.m or 1.m integer part49 // standard IEEE floats have an implicit 0.m or 1.m integer part
50 // f80 is special and has an explicitly stored bit in the MSB50 // f80 is special and has an explicitly stored bit in the MSB
...@@ -61,43 +61,43 @@ pub fn floatFractionalBits(comptime T: type) comptime_int {...@@ -61,43 +61,43 @@ pub fn floatFractionalBits(comptime T: type) comptime_int {
6161
62/// Returns the minimum exponent that can represent62/// Returns the minimum exponent that can represent
63/// a normalised value in floating point type T.63/// a normalised value in floating point type T.
64pub fn floatExponentMin(comptime T: type) comptime_int {64pub inline fn floatExponentMin(comptime T: type) comptime_int {
65 return -floatExponentMax(T) + 1;65 return -floatExponentMax(T) + 1;
66}66}
6767
68/// Returns the maximum exponent that can represent68/// Returns the maximum exponent that can represent
69/// a normalised value in floating point type T.69/// a normalised value in floating point type T.
70pub fn floatExponentMax(comptime T: type) comptime_int {70pub inline fn floatExponentMax(comptime T: type) comptime_int {
71 return (1 << (floatExponentBits(T) - 1)) - 1;71 return (1 << (floatExponentBits(T) - 1)) - 1;
72}72}
7373
74/// Returns the smallest subnormal number representable in floating point type T.74/// Returns the smallest subnormal number representable in floating point type T.
75pub fn floatTrueMin(comptime T: type) T {75pub inline fn floatTrueMin(comptime T: type) T {
76 return reconstructFloat(T, floatExponentMin(T) - 1, 1);76 return reconstructFloat(T, floatExponentMin(T) - 1, 1);
77}77}
7878
79/// Returns the smallest normal number representable in floating point type T.79/// Returns the smallest normal number representable in floating point type T.
80pub fn floatMin(comptime T: type) T {80pub inline fn floatMin(comptime T: type) T {
81 return reconstructFloat(T, floatExponentMin(T), mantissaOne(T));81 return reconstructFloat(T, floatExponentMin(T), mantissaOne(T));
82}82}
8383
84/// Returns the largest normal number representable in floating point type T.84/// Returns the largest normal number representable in floating point type T.
85pub fn floatMax(comptime T: type) T {85pub inline fn floatMax(comptime T: type) T {
86 const all1s_mantissa = (1 << floatMantissaBits(T)) - 1;86 const all1s_mantissa = (1 << floatMantissaBits(T)) - 1;
87 return reconstructFloat(T, floatExponentMax(T), all1s_mantissa);87 return reconstructFloat(T, floatExponentMax(T), all1s_mantissa);
88}88}
8989
90/// Returns the machine epsilon of floating point type T.90/// Returns the machine epsilon of floating point type T.
91pub fn floatEps(comptime T: type) T {91pub inline fn floatEps(comptime T: type) T {
92 return reconstructFloat(T, -floatFractionalBits(T), mantissaOne(T));92 return reconstructFloat(T, -floatFractionalBits(T), mantissaOne(T));
93}93}
9494
95/// Returns the value inf for floating point type T.95/// Returns the value inf for floating point type T.
96pub fn inf(comptime T: type) T {96pub inline fn inf(comptime T: type) T {
97 return reconstructFloat(T, floatExponentMax(T) + 1, mantissaOne(T));97 return reconstructFloat(T, floatExponentMax(T) + 1, mantissaOne(T));
98}98}
9999
100test "std.math.float" {100test "float bits" {
101 inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| {101 inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| {
102 // (1 +) for the sign bit, since it is separate from the other bits102 // (1 +) for the sign bit, since it is separate from the other bits
103 const size = 1 + floatExponentBits(T) + floatMantissaBits(T);103 const size = 1 + floatExponentBits(T) + floatMantissaBits(T);
lib/std/math/isinf.zig+3-3
...@@ -3,7 +3,7 @@ const math = std.math;...@@ -3,7 +3,7 @@ const math = std.math;
3const expect = std.testing.expect;3const expect = std.testing.expect;
44
5/// Returns whether x is an infinity, ignoring sign.5/// Returns whether x is an infinity, ignoring sign.
6pub fn isInf(x: anytype) bool {6pub inline fn isInf(x: anytype) bool {
7 const T = @TypeOf(x);7 const T = @TypeOf(x);
8 const TBits = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);8 const TBits = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);
9 const remove_sign = ~@as(TBits, 0) >> 1;9 const remove_sign = ~@as(TBits, 0) >> 1;
...@@ -11,12 +11,12 @@ pub fn isInf(x: anytype) bool {...@@ -11,12 +11,12 @@ pub fn isInf(x: anytype) bool {
11}11}
1212
13/// Returns whether x is an infinity with a positive sign.13/// Returns whether x is an infinity with a positive sign.
14pub fn isPositiveInf(x: anytype) bool {14pub inline fn isPositiveInf(x: anytype) bool {
15 return x == math.inf(@TypeOf(x));15 return x == math.inf(@TypeOf(x));
16}16}
1717
18/// Returns whether x is an infinity with a negative sign.18/// Returns whether x is an infinity with a negative sign.
19pub fn isNegativeInf(x: anytype) bool {19pub inline fn isNegativeInf(x: anytype) bool {
20 return x == -math.inf(@TypeOf(x));20 return x == -math.inf(@TypeOf(x));
21}21}
2222
src/Sema.zig+42
...@@ -22571,6 +22571,48 @@ fn bitCastVal(...@@ -22571,6 +22571,48 @@ fn bitCastVal(
22571 const target = sema.mod.getTarget();22571 const target = sema.mod.getTarget();
22572 if (old_ty.eql(new_ty, sema.mod)) return val;22572 if (old_ty.eql(new_ty, sema.mod)) return val;
2257322573
22574 // Some conversions have a bitwise definition that ignores in-memory layout,
22575 // such as converting between f80 and u80.
22576
22577 if (old_ty.eql(Type.f80, sema.mod) and new_ty.isAbiInt()) {
22578 const float = val.toFloat(f80);
22579 switch (new_ty.intInfo(target).signedness) {
22580 .signed => {
22581 const int = @bitCast(i80, float);
22582 const limbs = try sema.arena.alloc(std.math.big.Limb, 2);
22583 const big_int = std.math.big.int.Mutable.init(limbs, int);
22584 return Value.fromBigInt(sema.arena, big_int.toConst());
22585 },
22586 .unsigned => {
22587 const int = @bitCast(u80, float);
22588 const limbs = try sema.arena.alloc(std.math.big.Limb, 2);
22589 const big_int = std.math.big.int.Mutable.init(limbs, int);
22590 return Value.fromBigInt(sema.arena, big_int.toConst());
22591 },
22592 }
22593 }
22594
22595 if (new_ty.eql(Type.f80, sema.mod) and old_ty.isAbiInt()) {
22596 var bigint_space: Value.BigIntSpace = undefined;
22597 var bigint = try val.toBigIntAdvanced(&bigint_space, target, sema.kit(block, src));
22598 switch (old_ty.intInfo(target).signedness) {
22599 .signed => {
22600 // This conversion cannot fail because we already checked bit size before
22601 // calling bitCastVal.
22602 const int = bigint.to(i80) catch unreachable;
22603 const float = @bitCast(f80, int);
22604 return Value.Tag.float_80.create(sema.arena, float);
22605 },
22606 .unsigned => {
22607 // This conversion cannot fail because we already checked bit size before
22608 // calling bitCastVal.
22609 const int = bigint.to(u80) catch unreachable;
22610 const float = @bitCast(f80, int);
22611 return Value.Tag.float_80.create(sema.arena, float);
22612 },
22613 }
22614 }
22615
22574 // For types with well-defined memory layouts, we serialize them a byte buffer,22616 // For types with well-defined memory layouts, we serialize them a byte buffer,
22575 // then deserialize to the new type.22617 // then deserialize to the new type.
22576 const abi_size = try sema.usizeCast(block, src, old_ty.abiSize(target));22618 const abi_size = try sema.usizeCast(block, src, old_ty.abiSize(target));
src/codegen/llvm.zig+64-1
...@@ -717,6 +717,11 @@ pub const Object = struct {...@@ -717,6 +717,11 @@ pub const Object = struct {
717 const ret_ptr = if (sret) llvm_func.getParam(0) else null;717 const ret_ptr = if (sret) llvm_func.getParam(0) else null;
718 const gpa = dg.gpa;718 const gpa = dg.gpa;
719719
720 if (ccAbiPromoteInt(fn_info.cc, target, fn_info.return_type)) |s| switch (s) {
721 .signed => dg.addAttr(llvm_func, 0, "signext"),
722 .unsigned => dg.addAttr(llvm_func, 0, "zeroext"),
723 };
724
720 const err_return_tracing = fn_info.return_type.isError() and725 const err_return_tracing = fn_info.return_type.isError() and
721 dg.module.comp.bin_file.options.error_return_tracing;726 dg.module.comp.bin_file.options.error_return_tracing;
722727
...@@ -774,7 +779,10 @@ pub const Object = struct {...@@ -774,7 +779,10 @@ pub const Object = struct {
774 );779 );
775 dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align);780 dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align);
776 }781 }
777 }782 } else if (ccAbiPromoteInt(fn_info.cc, target, param_ty)) |s| switch (s) {
783 .signed => dg.addArgAttr(llvm_func, llvm_arg_i, "signext"),
784 .unsigned => dg.addArgAttr(llvm_func, llvm_arg_i, "zeroext"),
785 };
778 }786 }
779 llvm_arg_i += 1;787 llvm_arg_i += 1;
780 },788 },
...@@ -887,6 +895,13 @@ pub const Object = struct {...@@ -887,6 +895,13 @@ pub const Object = struct {
887 };895 };
888 try args.append(loaded);896 try args.append(loaded);
889 },897 },
898 .as_u16 => {
899 const param = llvm_func.getParam(llvm_arg_i);
900 llvm_arg_i += 1;
901 const casted = builder.buildBitCast(param, dg.context.halfType(), "");
902 try args.ensureUnusedCapacity(1);
903 args.appendAssumeCapacity(casted);
904 },
890 };905 };
891 }906 }
892907
...@@ -2794,6 +2809,9 @@ pub const DeclGen = struct {...@@ -2794,6 +2809,9 @@ pub const DeclGen = struct {
2794 llvm_params.appendAssumeCapacity(big_int_ty);2809 llvm_params.appendAssumeCapacity(big_int_ty);
2795 }2810 }
2796 },2811 },
2812 .as_u16 => {
2813 try llvm_params.append(dg.context.intType(16));
2814 },
2797 };2815 };
27982816
2799 return llvm.functionType(2817 return llvm.functionType(
...@@ -4234,6 +4252,12 @@ pub const FuncGen = struct {...@@ -4234,6 +4252,12 @@ pub const FuncGen = struct {
4234 llvm_args.appendAssumeCapacity(load_inst);4252 llvm_args.appendAssumeCapacity(load_inst);
4235 }4253 }
4236 },4254 },
4255 .as_u16 => {
4256 const arg = args[it.zig_index - 1];
4257 const llvm_arg = try self.resolveInst(arg);
4258 const casted = self.builder.buildBitCast(llvm_arg, self.dg.context.intType(16), "");
4259 try llvm_args.append(casted);
4260 },
4237 };4261 };
42384262
4239 const call = self.builder.buildCall(4263 const call = self.builder.buildCall(
...@@ -8965,6 +8989,7 @@ const ParamTypeIterator = struct {...@@ -8965,6 +8989,7 @@ const ParamTypeIterator = struct {
8965 abi_sized_int,8989 abi_sized_int,
8966 multiple_llvm_ints,8990 multiple_llvm_ints,
8967 slice,8991 slice,
8992 as_u16,
8968 };8993 };
89698994
8970 pub fn next(it: *ParamTypeIterator) ?Lowering {8995 pub fn next(it: *ParamTypeIterator) ?Lowering {
...@@ -9025,6 +9050,15 @@ const ParamTypeIterator = struct {...@@ -9025,6 +9050,15 @@ const ParamTypeIterator = struct {
9025 else => false,9050 else => false,
9026 };9051 };
9027 switch (it.target.cpu.arch) {9052 switch (it.target.cpu.arch) {
9053 .riscv32, .riscv64 => {
9054 it.zig_index += 1;
9055 it.llvm_index += 1;
9056 if (ty.tag() == .f16) {
9057 return .as_u16;
9058 } else {
9059 return .byval;
9060 }
9061 },
9028 .mips, .mipsel => {9062 .mips, .mipsel => {
9029 it.zig_index += 1;9063 it.zig_index += 1;
9030 it.llvm_index += 1;9064 it.llvm_index += 1;
...@@ -9135,6 +9169,35 @@ fn iterateParamTypes(dg: *DeclGen, fn_info: Type.Payload.Function.Data) ParamTyp...@@ -9135,6 +9169,35 @@ fn iterateParamTypes(dg: *DeclGen, fn_info: Type.Payload.Function.Data) ParamTyp
9135 };9169 };
9136}9170}
91379171
9172fn ccAbiPromoteInt(
9173 cc: std.builtin.CallingConvention,
9174 target: std.Target,
9175 ty: Type,
9176) ?std.builtin.Signedness {
9177 switch (cc) {
9178 .Unspecified, .Inline, .Async => return null,
9179 else => {},
9180 }
9181 const int_info = switch (ty.zigTypeTag()) {
9182 .Int, .Enum, .ErrorSet => ty.intInfo(target),
9183 else => return null,
9184 };
9185 if (int_info.bits <= 16) return int_info.signedness;
9186 switch (target.cpu.arch) {
9187 .sparc64,
9188 .riscv64,
9189 .powerpc64,
9190 .powerpc64le,
9191 => {
9192 if (int_info.bits < 64) {
9193 return int_info.signedness;
9194 }
9195 },
9196 else => {},
9197 }
9198 return null;
9199}
9200
9138fn isByRef(ty: Type) bool {9201fn isByRef(ty: Type) bool {
9139 // For tuples and structs, if there are more than this many non-void9202 // For tuples and structs, if there are more than this many non-void
9140 // fields, then we make it byref, otherwise byval.9203 // fields, then we make it byref, otherwise byval.
src/type.zig+10
...@@ -4439,6 +4439,16 @@ pub const Type = extern union {...@@ -4439,6 +4439,16 @@ pub const Type = extern union {
4439 };4439 };
4440 }4440 }
44414441
4442 /// Returns true for integers, enums, error sets, and packed structs.
4443 /// If this function returns true, then intInfo() can be called on the type.
4444 pub fn isAbiInt(ty: Type) bool {
4445 return switch (ty.zigTypeTag()) {
4446 .Int, .Enum, .ErrorSet => true,
4447 .Struct => ty.containerLayout() == .Packed,
4448 else => false,
4449 };
4450 }
4451
4442 /// Asserts the type is an integer, enum, error set, or vector of one of them.4452 /// Asserts the type is an integer, enum, error set, or vector of one of them.
4443 pub fn intInfo(self: Type, target: Target) struct { signedness: std.builtin.Signedness, bits: u16 } {4453 pub fn intInfo(self: Type, target: Target) struct { signedness: std.builtin.Signedness, bits: u16 } {
4444 var ty = self;4454 var ty = self;
src/value.zig+7-10
...@@ -1468,8 +1468,7 @@ pub const Value = extern union {...@@ -1468,8 +1468,7 @@ pub const Value = extern union {
1468 const repr = std.math.break_f80(f);1468 const repr = std.math.break_f80(f);
1469 std.mem.writeInt(u64, buffer[0..8], repr.fraction, endian);1469 std.mem.writeInt(u64, buffer[0..8], repr.fraction, endian);
1470 std.mem.writeInt(u16, buffer[8..10], repr.exp, endian);1470 std.mem.writeInt(u16, buffer[8..10], repr.exp, endian);
1471 // TODO set the rest of the bytes to undefined. should we use 0xaa1471 std.mem.set(u8, buffer[10..], 0);
1472 // or is there a different way?
1473 return;1472 return;
1474 }1473 }
1475 const Int = @Type(.{ .Int = .{1474 const Int = @Type(.{ .Int = .{
...@@ -1481,20 +1480,18 @@ pub const Value = extern union {...@@ -1481,20 +1480,18 @@ pub const Value = extern union {
1481 }1480 }
14821481
1483 fn floatReadFromMemory(comptime F: type, target: Target, buffer: []const u8) F {1482 fn floatReadFromMemory(comptime F: type, target: Target, buffer: []const u8) F {
1483 const endian = target.cpu.arch.endian();
1484 if (F == f80) {1484 if (F == f80) {
1485 switch (target.cpu.arch) {1485 return std.math.make_f80(.{
1486 .i386, .x86_64 => return std.math.make_f80(.{1486 .fraction = readInt(u64, buffer[0..8], endian),
1487 .fraction = std.mem.readIntLittle(u64, buffer[0..8]),1487 .exp = readInt(u16, buffer[8..10], endian),
1488 .exp = std.mem.readIntLittle(u16, buffer[8..10]),1488 });
1489 }),
1490 else => {},
1491 }
1492 }1489 }
1493 const Int = @Type(.{ .Int = .{1490 const Int = @Type(.{ .Int = .{
1494 .signedness = .unsigned,1491 .signedness = .unsigned,
1495 .bits = @typeInfo(F).Float.bits,1492 .bits = @typeInfo(F).Float.bits,
1496 } });1493 } });
1497 const int = readInt(Int, buffer[0..@sizeOf(Int)], target.cpu.arch.endian());1494 const int = readInt(Int, buffer[0..@sizeOf(Int)], endian);
1498 return @bitCast(F, int);1495 return @bitCast(F, int);
1499 }1496 }
15001497
test/behavior/math.zig-30
...@@ -1168,11 +1168,6 @@ test "remainder division" {...@@ -1168,11 +1168,6 @@ test "remainder division" {
1168 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1168 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1169 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1169 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
11701170
1171 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .riscv64) {
1172 // https://github.com/ziglang/zig/issues/12054
1173 return error.SkipZigTest;
1174 }
1175
1176 comptime try remdiv(f16);1171 comptime try remdiv(f16);
1177 comptime try remdiv(f32);1172 comptime try remdiv(f32);
1178 comptime try remdiv(f64);1173 comptime try remdiv(f64);
...@@ -1204,11 +1199,6 @@ test "float remainder division using @rem" {...@@ -1204,11 +1199,6 @@ test "float remainder division using @rem" {
1204 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1199 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1205 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1200 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
12061201
1207 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .riscv64) {
1208 // https://github.com/ziglang/zig/issues/12054
1209 return error.SkipZigTest;
1210 }
1211
1212 comptime try frem(f16);1202 comptime try frem(f16);
1213 comptime try frem(f32);1203 comptime try frem(f32);
1214 comptime try frem(f64);1204 comptime try frem(f64);
...@@ -1251,11 +1241,6 @@ test "float modulo division using @mod" {...@@ -1251,11 +1241,6 @@ test "float modulo division using @mod" {
1251 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1241 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1252 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1242 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
12531243
1254 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .riscv64) {
1255 // https://github.com/ziglang/zig/issues/12054
1256 return error.SkipZigTest;
1257 }
1258
1259 comptime try fmod(f16);1244 comptime try fmod(f16);
1260 comptime try fmod(f32);1245 comptime try fmod(f32);
1261 comptime try fmod(f64);1246 comptime try fmod(f64);
...@@ -1431,11 +1416,6 @@ test "@ceil f80" {...@@ -1431,11 +1416,6 @@ test "@ceil f80" {
1431 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1416 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1432 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO1417 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
14331418
1434 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .riscv64) {
1435 // https://github.com/ziglang/zig/issues/12054
1436 return error.SkipZigTest;
1437 }
1438
1439 try testCeil(f80, 12.0);1419 try testCeil(f80, 12.0);
1440 comptime try testCeil(f80, 12.0);1420 comptime try testCeil(f80, 12.0);
1441}1421}
...@@ -1447,11 +1427,6 @@ test "@ceil f128" {...@@ -1447,11 +1427,6 @@ test "@ceil f128" {
1447 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1427 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1448 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO1428 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
14491429
1450 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .riscv64) {
1451 // https://github.com/ziglang/zig/issues/12054
1452 return error.SkipZigTest;
1453 }
1454
1455 try testCeil(f128, 12.0);1430 try testCeil(f128, 12.0);
1456 comptime try testCeil(f128, 12.0);1431 comptime try testCeil(f128, 12.0);
1457}1432}
...@@ -1600,11 +1575,6 @@ test "NaN comparison" {...@@ -1600,11 +1575,6 @@ test "NaN comparison" {
1600 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1575 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1601 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1576 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
16021577
1603 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .riscv64) {
1604 // https://github.com/ziglang/zig/issues/12054
1605 return error.SkipZigTest;
1606 }
1607
1608 try testNanEqNan(f16);1578 try testNanEqNan(f16);
1609 try testNanEqNan(f32);1579 try testNanEqNan(f32);
1610 try testNanEqNan(f64);1580 try testNanEqNan(f64);