Commit 897df18573

Jakub Konka <kubkon@jakubkonka.com>
2022-04-16 01:55:41
stage2: fix @mulAdd on aarch64 Darwin
According to Apple docs, the long double type is a double precision IEEE754 binary floating-point type, which makes it identical to the double type. This behavior contrasts to the standard specification, in which a long double is a quad-precision, IEEE754 binary, floating-point type. Thus, we need to take this into account when using the compiler intrinsics so that we select the correct function version for FloatMulAdd.
1 parent 1b5a43f
Changed files (4)
lib
src
test
behavior
lib/std/target.zig
@@ -1718,8 +1718,17 @@ pub const Target = struct {
         }
         return switch (F) {
             f128 => switch (target.cpu.arch) {
+                .aarch64 => {
+                    // According to Apple's official guide:
+                    // > The long double type is a double precision IEEE754 binary floating-point type,
+                    // > which makes it identical to the double type. This behavior contrasts to the
+                    // > standard specification, in which a long double is a quad-precision, IEEE754
+                    // > binary, floating-point type.
+                    // https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms
+                    return !target.isDarwin();
+                },
+
                 .riscv64,
-                .aarch64,
                 .aarch64_be,
                 .aarch64_32,
                 .s390x,
src/stage1/target.cpp
@@ -1008,8 +1008,16 @@ bool target_long_double_is_f128(const ZigTarget *target) {
         return false;
     }
     switch (target->arch) {
-        case ZigLLVM_riscv64:
         case ZigLLVM_aarch64:
+            // According to Apple's official guide:
+            // > The long double type is a double precision IEEE754 binary floating-point type,
+            // > which makes it identical to the double type. This behavior contrasts to the
+            // > standard specification, in which a long double is a quad-precision, IEEE754
+            // > binary, floating-point type.
+            // https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms
+            return !target_os_is_darwin(target->os);
+
+        case ZigLLVM_riscv64:
         case ZigLLVM_aarch64_be:
         case ZigLLVM_aarch64_32:
         case ZigLLVM_systemz:
src/type.zig
@@ -6155,7 +6155,6 @@ pub const CType = enum {
             },
 
             .linux,
-            .macos,
             .freebsd,
             .netbsd,
             .dragonfly,
@@ -6198,7 +6197,7 @@ pub const CType = enum {
                 .longlong, .ulonglong, .longdouble => return 64,
             },
 
-            .ios, .tvos, .watchos => switch (self) {
+            .macos, .ios, .tvos, .watchos => switch (self) {
                 .short, .ushort => return 16,
                 .int, .uint => return 32,
                 .long, .ulong, .longlong, .ulonglong => return 64,
test/behavior/cast.zig
@@ -79,19 +79,16 @@ test "comptime_int @intToFloat" {
         try expect(result == 1234.0);
     }
 
-    if (!((builtin.zig_backend == .stage2_aarch64 or builtin.zig_backend == .stage2_x86_64) and builtin.os.tag == .macos)) {
-        // TODO investigate why this traps on x86_64-macos and aarch64-macos
-        {
-            const result = @intToFloat(f128, 1234);
-            try expect(@TypeOf(result) == f128);
-            try expect(result == 1234.0);
-        }
-        // big comptime_int (> 64 bits) to f128 conversion
-        {
-            const result = @intToFloat(f128, 0x1_0000_0000_0000_0000);
-            try expect(@TypeOf(result) == f128);
-            try expect(result == 0x1_0000_0000_0000_0000.0);
-        }
+    {
+        const result = @intToFloat(f128, 1234);
+        try expect(@TypeOf(result) == f128);
+        try expect(result == 1234.0);
+    }
+    // big comptime_int (> 64 bits) to f128 conversion
+    {
+        const result = @intToFloat(f128, 0x1_0000_0000_0000_0000);
+        try expect(@TypeOf(result) == f128);
+        try expect(result == 0x1_0000_0000_0000_0000.0);
     }
 }