| author | |
| committer | |
| log | 1653a9b2597c66cbcc88ea75d8a4b88c163584a5 |
| tree | 9cbe5d66e5088006ac4b5d5b4861a3b8b25a7a54 |
| parent | fad95741db7529bbad873fb330c25d64ac765340 |
| parent | 92bc3cbe27792be0300fb5f104c011a11f3cf40f |
| signature |
LLVM: implement signext/zeroext attributes8 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 | 68 | /// need for extending them to wider fp types. |
| 69 | 69 | /// TODO remove this; do this type selection in the language rather than |
| 70 | 70 | /// here in compiler-rt. |
| 71 | pub const F16T = if (builtin.cpu.arch.isAARCH64()) f16 else u16; | |
| 71 | pub 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 | }; | |
| 72 | 76 | |
| 73 | 77 | pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void { |
| 74 | 78 | switch (Z) { |
lib/std/math/float.zig+17-17| ... | ... | @@ -3,20 +3,20 @@ const assert = std.debug.assert; |
| 3 | 3 | const expect = std.testing.expect; |
| 4 | 4 | |
| 5 | 5 | /// Creates a raw "1.0" mantissa for floating point type T. Used to dedupe f80 logic. |
| 6 | fn mantissaOne(comptime T: type) comptime_int { | |
| 6 | inline fn mantissaOne(comptime T: type) comptime_int { | |
| 7 | 7 | return if (@typeInfo(T).Float.bits == 80) 1 << floatFractionalBits(T) else 0; |
| 8 | 8 | } |
| 9 | 9 | |
| 10 | 10 | /// Creates floating point type T from an unbiased exponent and raw mantissa. |
| 11 | fn reconstructFloat(comptime T: type, exponent: comptime_int, mantissa: comptime_int) T { | |
| 12 | const TBits = std.meta.Int(.unsigned, @bitSizeOf(T)); | |
| 11 | inline fn reconstructFloat(comptime T: type, exponent: comptime_int, mantissa: comptime_int) T { | |
| 12 | const TBits = @Type(.{ .Int = .{ .signedness = .unsigned, .bits = @bitSizeOf(T) } }); | |
| 13 | 13 | const biased_exponent = @as(TBits, exponent + floatExponentMax(T)); |
| 14 | 14 | return @bitCast(T, (biased_exponent << floatMantissaBits(T)) | @as(TBits, mantissa)); |
| 15 | 15 | } |
| 16 | 16 | |
| 17 | 17 | /// Returns the number of bits in the exponent of floating point type T. |
| 18 | pub fn floatExponentBits(comptime T: type) comptime_int { | |
| 19 | assert(@typeInfo(T) == .Float); | |
| 18 | pub inline fn floatExponentBits(comptime T: type) comptime_int { | |
| 19 | comptime assert(@typeInfo(T) == .Float); | |
| 20 | 20 | |
| 21 | 21 | return switch (@typeInfo(T).Float.bits) { |
| 22 | 22 | 16 => 5, |
| ... | ... | @@ -29,8 +29,8 @@ pub fn floatExponentBits(comptime T: type) comptime_int { |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | 31 | /// Returns the number of bits in the mantissa of floating point type T. |
| 32 | pub fn floatMantissaBits(comptime T: type) comptime_int { | |
| 33 | assert(@typeInfo(T) == .Float); | |
| 32 | pub inline fn floatMantissaBits(comptime T: type) comptime_int { | |
| 33 | comptime assert(@typeInfo(T) == .Float); | |
| 34 | 34 | |
| 35 | 35 | return switch (@typeInfo(T).Float.bits) { |
| 36 | 36 | 16 => 10, |
| ... | ... | @@ -43,8 +43,8 @@ pub fn floatMantissaBits(comptime T: type) comptime_int { |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | 45 | /// Returns the number of fractional bits in the mantissa of floating point type T. |
| 46 | pub fn floatFractionalBits(comptime T: type) comptime_int { | |
| 47 | assert(@typeInfo(T) == .Float); | |
| 46 | pub inline fn floatFractionalBits(comptime T: type) comptime_int { | |
| 47 | comptime assert(@typeInfo(T) == .Float); | |
| 48 | 48 | |
| 49 | 49 | // standard IEEE floats have an implicit 0.m or 1.m integer part |
| 50 | 50 | // 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 | 61 | |
| 62 | 62 | /// Returns the minimum exponent that can represent |
| 63 | 63 | /// a normalised value in floating point type T. |
| 64 | pub fn floatExponentMin(comptime T: type) comptime_int { | |
| 64 | pub inline fn floatExponentMin(comptime T: type) comptime_int { | |
| 65 | 65 | return -floatExponentMax(T) + 1; |
| 66 | 66 | } |
| 67 | 67 | |
| 68 | 68 | /// Returns the maximum exponent that can represent |
| 69 | 69 | /// a normalised value in floating point type T. |
| 70 | pub fn floatExponentMax(comptime T: type) comptime_int { | |
| 70 | pub inline fn floatExponentMax(comptime T: type) comptime_int { | |
| 71 | 71 | return (1 << (floatExponentBits(T) - 1)) - 1; |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | 74 | /// Returns the smallest subnormal number representable in floating point type T. |
| 75 | pub fn floatTrueMin(comptime T: type) T { | |
| 75 | pub inline fn floatTrueMin(comptime T: type) T { | |
| 76 | 76 | return reconstructFloat(T, floatExponentMin(T) - 1, 1); |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | 79 | /// Returns the smallest normal number representable in floating point type T. |
| 80 | pub fn floatMin(comptime T: type) T { | |
| 80 | pub inline fn floatMin(comptime T: type) T { | |
| 81 | 81 | return reconstructFloat(T, floatExponentMin(T), mantissaOne(T)); |
| 82 | 82 | } |
| 83 | 83 | |
| 84 | 84 | /// Returns the largest normal number representable in floating point type T. |
| 85 | pub fn floatMax(comptime T: type) T { | |
| 85 | pub inline fn floatMax(comptime T: type) T { | |
| 86 | 86 | const all1s_mantissa = (1 << floatMantissaBits(T)) - 1; |
| 87 | 87 | return reconstructFloat(T, floatExponentMax(T), all1s_mantissa); |
| 88 | 88 | } |
| 89 | 89 | |
| 90 | 90 | /// Returns the machine epsilon of floating point type T. |
| 91 | pub fn floatEps(comptime T: type) T { | |
| 91 | pub inline fn floatEps(comptime T: type) T { | |
| 92 | 92 | return reconstructFloat(T, -floatFractionalBits(T), mantissaOne(T)); |
| 93 | 93 | } |
| 94 | 94 | |
| 95 | 95 | /// Returns the value inf for floating point type T. |
| 96 | pub fn inf(comptime T: type) T { | |
| 96 | pub inline fn inf(comptime T: type) T { | |
| 97 | 97 | return reconstructFloat(T, floatExponentMax(T) + 1, mantissaOne(T)); |
| 98 | 98 | } |
| 99 | 99 | |
| 100 | test "std.math.float" { | |
| 100 | test "float bits" { | |
| 101 | 101 | inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| { |
| 102 | 102 | // (1 +) for the sign bit, since it is separate from the other bits |
| 103 | 103 | const size = 1 + floatExponentBits(T) + floatMantissaBits(T); |
lib/std/math/isinf.zig+3-3| ... | ... | @@ -3,7 +3,7 @@ const math = std.math; |
| 3 | 3 | const expect = std.testing.expect; |
| 4 | 4 | |
| 5 | 5 | /// Returns whether x is an infinity, ignoring sign. |
| 6 | pub fn isInf(x: anytype) bool { | |
| 6 | pub inline fn isInf(x: anytype) bool { | |
| 7 | 7 | const T = @TypeOf(x); |
| 8 | 8 | const TBits = std.meta.Int(.unsigned, @typeInfo(T).Float.bits); |
| 9 | 9 | const remove_sign = ~@as(TBits, 0) >> 1; |
| ... | ... | @@ -11,12 +11,12 @@ pub fn isInf(x: anytype) bool { |
| 11 | 11 | } |
| 12 | 12 | |
| 13 | 13 | /// Returns whether x is an infinity with a positive sign. |
| 14 | pub fn isPositiveInf(x: anytype) bool { | |
| 14 | pub inline fn isPositiveInf(x: anytype) bool { | |
| 15 | 15 | return x == math.inf(@TypeOf(x)); |
| 16 | 16 | } |
| 17 | 17 | |
| 18 | 18 | /// Returns whether x is an infinity with a negative sign. |
| 19 | pub fn isNegativeInf(x: anytype) bool { | |
| 19 | pub inline fn isNegativeInf(x: anytype) bool { | |
| 20 | 20 | return x == -math.inf(@TypeOf(x)); |
| 21 | 21 | } |
| 22 | 22 |
src/Sema.zig+42| ... | ... | @@ -22571,6 +22571,48 @@ fn bitCastVal( |
| 22571 | 22571 | const target = sema.mod.getTarget(); |
| 22572 | 22572 | if (old_ty.eql(new_ty, sema.mod)) return val; |
| 22573 | 22573 | |
| 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 | 22616 | // For types with well-defined memory layouts, we serialize them a byte buffer, |
| 22575 | 22617 | // then deserialize to the new type. |
| 22576 | 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 | 717 | const ret_ptr = if (sret) llvm_func.getParam(0) else null; |
| 718 | 718 | const gpa = dg.gpa; |
| 719 | 719 | |
| 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 | 725 | const err_return_tracing = fn_info.return_type.isError() and |
| 721 | 726 | dg.module.comp.bin_file.options.error_return_tracing; |
| 722 | 727 | |
| ... | ... | @@ -774,7 +779,10 @@ pub const Object = struct { |
| 774 | 779 | ); |
| 775 | 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 | 787 | llvm_arg_i += 1; |
| 780 | 788 | }, |
| ... | ... | @@ -887,6 +895,13 @@ pub const Object = struct { |
| 887 | 895 | }; |
| 888 | 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 | } |
| 892 | 907 | |
| ... | ... | @@ -2794,6 +2809,9 @@ pub const DeclGen = struct { |
| 2794 | 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 | }; |
| 2798 | 2816 | |
| 2799 | 2817 | return llvm.functionType( |
| ... | ... | @@ -4234,6 +4252,12 @@ pub const FuncGen = struct { |
| 4234 | 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 | }; |
| 4238 | 4262 | |
| 4239 | 4263 | const call = self.builder.buildCall( |
| ... | ... | @@ -8965,6 +8989,7 @@ const ParamTypeIterator = struct { |
| 8965 | 8989 | abi_sized_int, |
| 8966 | 8990 | multiple_llvm_ints, |
| 8967 | 8991 | slice, |
| 8992 | as_u16, | |
| 8968 | 8993 | }; |
| 8969 | 8994 | |
| 8970 | 8995 | pub fn next(it: *ParamTypeIterator) ?Lowering { |
| ... | ... | @@ -9025,6 +9050,15 @@ const ParamTypeIterator = struct { |
| 9025 | 9050 | else => false, |
| 9026 | 9051 | }; |
| 9027 | 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 | 9062 | .mips, .mipsel => { |
| 9029 | 9063 | it.zig_index += 1; |
| 9030 | 9064 | it.llvm_index += 1; |
| ... | ... | @@ -9135,6 +9169,35 @@ fn iterateParamTypes(dg: *DeclGen, fn_info: Type.Payload.Function.Data) ParamTyp |
| 9135 | 9169 | }; |
| 9136 | 9170 | } |
| 9137 | 9171 | |
| 9172 | fn 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 | ||
| 9138 | 9201 | fn isByRef(ty: Type) bool { |
| 9139 | 9202 | // For tuples and structs, if there are more than this many non-void |
| 9140 | 9203 | // fields, then we make it byref, otherwise byval. |
src/type.zig+10| ... | ... | @@ -4439,6 +4439,16 @@ pub const Type = extern union { |
| 4439 | 4439 | }; |
| 4440 | 4440 | } |
| 4441 | 4441 | |
| 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 | 4452 | /// Asserts the type is an integer, enum, error set, or vector of one of them. |
| 4443 | 4453 | pub fn intInfo(self: Type, target: Target) struct { signedness: std.builtin.Signedness, bits: u16 } { |
| 4444 | 4454 | var ty = self; |
src/value.zig+7-10| ... | ... | @@ -1468,8 +1468,7 @@ pub const Value = extern union { |
| 1468 | 1468 | const repr = std.math.break_f80(f); |
| 1469 | 1469 | std.mem.writeInt(u64, buffer[0..8], repr.fraction, endian); |
| 1470 | 1470 | std.mem.writeInt(u16, buffer[8..10], repr.exp, endian); |
| 1471 | // TODO set the rest of the bytes to undefined. should we use 0xaa | |
| 1472 | // or is there a different way? | |
| 1471 | std.mem.set(u8, buffer[10..], 0); | |
| 1473 | 1472 | return; |
| 1474 | 1473 | } |
| 1475 | 1474 | const Int = @Type(.{ .Int = .{ |
| ... | ... | @@ -1481,20 +1480,18 @@ pub const Value = extern union { |
| 1481 | 1480 | } |
| 1482 | 1481 | |
| 1483 | 1482 | fn floatReadFromMemory(comptime F: type, target: Target, buffer: []const u8) F { |
| 1483 | const endian = target.cpu.arch.endian(); | |
| 1484 | 1484 | if (F == f80) { |
| 1485 | switch (target.cpu.arch) { | |
| 1486 | .i386, .x86_64 => return std.math.make_f80(.{ | |
| 1487 | .fraction = std.mem.readIntLittle(u64, buffer[0..8]), | |
| 1488 | .exp = std.mem.readIntLittle(u16, buffer[8..10]), | |
| 1489 | }), | |
| 1490 | else => {}, | |
| 1491 | } | |
| 1485 | return std.math.make_f80(.{ | |
| 1486 | .fraction = readInt(u64, buffer[0..8], endian), | |
| 1487 | .exp = readInt(u16, buffer[8..10], endian), | |
| 1488 | }); | |
| 1492 | 1489 | } |
| 1493 | 1490 | const Int = @Type(.{ .Int = .{ |
| 1494 | 1491 | .signedness = .unsigned, |
| 1495 | 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 | 1495 | return @bitCast(F, int); |
| 1499 | 1496 | } |
| 1500 | 1497 |
test/behavior/math.zig-30| ... | ... | @@ -1168,11 +1168,6 @@ test "remainder division" { |
| 1168 | 1168 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1169 | 1169 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1170 | 1170 | |
| 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 | 1171 | comptime try remdiv(f16); |
| 1177 | 1172 | comptime try remdiv(f32); |
| 1178 | 1173 | comptime try remdiv(f64); |
| ... | ... | @@ -1204,11 +1199,6 @@ test "float remainder division using @rem" { |
| 1204 | 1199 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1205 | 1200 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1206 | 1201 | |
| 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 | 1202 | comptime try frem(f16); |
| 1213 | 1203 | comptime try frem(f32); |
| 1214 | 1204 | comptime try frem(f64); |
| ... | ... | @@ -1251,11 +1241,6 @@ test "float modulo division using @mod" { |
| 1251 | 1241 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1252 | 1242 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1253 | 1243 | |
| 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 | 1244 | comptime try fmod(f16); |
| 1260 | 1245 | comptime try fmod(f32); |
| 1261 | 1246 | comptime try fmod(f64); |
| ... | ... | @@ -1431,11 +1416,6 @@ test "@ceil f80" { |
| 1431 | 1416 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1432 | 1417 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 1433 | 1418 | |
| 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 | 1419 | try testCeil(f80, 12.0); |
| 1440 | 1420 | comptime try testCeil(f80, 12.0); |
| 1441 | 1421 | } |
| ... | ... | @@ -1447,11 +1427,6 @@ test "@ceil f128" { |
| 1447 | 1427 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1448 | 1428 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 1449 | 1429 | |
| 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 | 1430 | try testCeil(f128, 12.0); |
| 1456 | 1431 | comptime try testCeil(f128, 12.0); |
| 1457 | 1432 | } |
| ... | ... | @@ -1600,11 +1575,6 @@ test "NaN comparison" { |
| 1600 | 1575 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1601 | 1576 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1602 | 1577 | |
| 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 | 1578 | try testNanEqNan(f16); |
| 1609 | 1579 | try testNanEqNan(f32); |
| 1610 | 1580 | try testNanEqNan(f64); |