From 96fbafe3598822d8d62791d881879c4da33431ea Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 21 Sep 2023 10:38:44 +0100 Subject: [PATCH] Update ABI breaking changes for `f16` types (due to LLVM 15+) --- core/runtime/internal.odin | 26 +++++++++++++++----------- src/checker.cpp | 3 +++ src/llvm_backend.hpp | 14 ++++++++++++++ src/llvm_backend_opt.cpp | 10 ---------- src/main.cpp | 1 - 5 files changed, 32 insertions(+), 22 deletions(-) diff --git a/core/runtime/internal.odin b/core/runtime/internal.odin index 4d166bef0..7e13bb929 100644 --- a/core/runtime/internal.odin +++ b/core/runtime/internal.odin @@ -13,6 +13,9 @@ RUNTIME_LINKAGE :: "strong" when ( !IS_WASM) else "internal" RUNTIME_REQUIRE :: !ODIN_TILDE +@(private) +__float16 :: f16 when __ODIN_LLVM_F16_SUPPORTED else u16 + @(private) byte_slice :: #force_inline proc "contextless" (data: rawptr, len: int) -> []byte #no_bounds_check { @@ -755,7 +758,7 @@ quo_quaternion256 :: proc "contextless" (q, r: quaternion256) -> quaternion256 { } @(link_name="__truncsfhf2", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE) -truncsfhf2 :: proc "c" (value: f32) -> u16 { +truncsfhf2 :: proc "c" (value: f32) -> __float16 { v: struct #raw_union { i: u32, f: f32 } i, s, e, m: i32 @@ -769,7 +772,7 @@ truncsfhf2 :: proc "c" (value: f32) -> u16 { if e <= 0 { if e < -10 { - return u16(s) + return transmute(__float16)u16(s) } m = (m | 0x00800000) >> u32(1 - e) @@ -777,14 +780,14 @@ truncsfhf2 :: proc "c" (value: f32) -> u16 { m += 0x00002000 } - return u16(s | (m >> 13)) + return transmute(__float16)u16(s | (m >> 13)) } else if e == 0xff - (127 - 15) { if m == 0 { - return u16(s | 0x7c00) /* NOTE(bill): infinity */ + return transmute(__float16)u16(s | 0x7c00) /* NOTE(bill): infinity */ } else { /* NOTE(bill): NAN */ m >>= 13 - return u16(s | 0x7c00 | m | i32(m == 0)) + return transmute(__float16)u16(s | 0x7c00 | m | i32(m == 0)) } } else { if m & 0x00001000 != 0 { @@ -804,23 +807,24 @@ truncsfhf2 :: proc "c" (value: f32) -> u16 { intrinsics.volatile_store(&f, g) } - return u16(s | 0x7c00) + return transmute(__float16)u16(s | 0x7c00) } - return u16(s | (e << 10) | (m >> 13)) + return transmute(__float16)u16(s | (e << 10) | (m >> 13)) } } @(link_name="__truncdfhf2", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE) -truncdfhf2 :: proc "c" (value: f64) -> u16 { +truncdfhf2 :: proc "c" (value: f64) -> __float16 { return truncsfhf2(f32(value)) } @(link_name="__gnu_h2f_ieee", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE) -gnu_h2f_ieee :: proc "c" (value: u16) -> f32 { +gnu_h2f_ieee :: proc "c" (value_: __float16) -> f32 { fp32 :: struct #raw_union { u: u32, f: f32 } + value := transmute(u16)value_ v: fp32 magic, inf_or_nan: fp32 magic.u = u32((254 - 15) << 23) @@ -837,12 +841,12 @@ gnu_h2f_ieee :: proc "c" (value: u16) -> f32 { @(link_name="__gnu_f2h_ieee", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE) -gnu_f2h_ieee :: proc "c" (value: f32) -> u16 { +gnu_f2h_ieee :: proc "c" (value: f32) -> __float16 { return truncsfhf2(value) } @(link_name="__extendhfsf2", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE) -extendhfsf2 :: proc "c" (value: u16) -> f32 { +extendhfsf2 :: proc "c" (value: __float16) -> f32 { return gnu_h2f_ieee(value) } diff --git a/src/checker.cpp b/src/checker.cpp index 18d403d80..0be912df5 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -935,6 +935,7 @@ gb_internal i64 odin_compile_timestamp(void) { return ns_after_1970; } +gb_internal bool lb_use_new_pass_system(void); gb_internal void init_universal(void) { BuildContext *bc = &build_context; @@ -1083,6 +1084,8 @@ gb_internal void init_universal(void) { add_global_constant("ODIN_COMPILE_TIMESTAMP", t_untyped_integer, exact_value_i64(odin_compile_timestamp())); + add_global_bool_constant("__ODIN_LLVM_F16_SUPPORTED", lb_use_new_pass_system()); + // Builtin Procedures for (isize i = 0; i < gb_count_of(builtin_procs); i++) { diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index d4da1f18a..048233c08 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -48,6 +48,20 @@ #define ODIN_LLVM_MINIMUM_VERSION_14 0 #endif +#if LLVM_VERSION_MAJOR == 15 || LLVM_VERSION_MAJOR == 16 +#error "LLVM versions 15 and 16 are not supported" +#endif + +#if LLVM_VERSION_MAJOR >= 17 +#define LB_USE_NEW_PASS_SYSTEM 1 +#else +#define LB_USE_NEW_PASS_SYSTEM 0 +#endif + +gb_internal bool lb_use_new_pass_system(void) { + return LB_USE_NEW_PASS_SYSTEM; +} + struct lbProcedure; struct lbValue { diff --git a/src/llvm_backend_opt.cpp b/src/llvm_backend_opt.cpp index 2f0dc24fd..055cb5bcb 100644 --- a/src/llvm_backend_opt.cpp +++ b/src/llvm_backend_opt.cpp @@ -55,16 +55,6 @@ gb_internal void lb_populate_function_pass_manager_specific(lbModule *m, LLVMPas #define LLVM_ADD_CONSTANT_VALUE_PASS(fpm) #endif -#if LLVM_VERSION_MAJOR == 15 || LLVM_VERSION_MAJOR == 16 -#error "LLVM versions 15 and 16 are not supported" -#endif - -#if LLVM_VERSION_MAJOR >= 17 -#define LB_USE_NEW_PASS_SYSTEM 1 -#else -#define LB_USE_NEW_PASS_SYSTEM 0 -#endif - gb_internal bool lb_opt_ignore(i32 optimization_level) { return optimization_level < 0; } diff --git a/src/main.cpp b/src/main.cpp index 706bbab87..c6b6e74bf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -412,7 +412,6 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_SingleFile, str_lit("file"), BuildFlagParam_None, Command__does_build | Command__does_check); add_flag(&build_flags, BuildFlag_OutFile, str_lit("out"), BuildFlagParam_String, Command__does_build | Command_test); add_flag(&build_flags, BuildFlag_OptimizationMode, str_lit("o"), BuildFlagParam_String, Command__does_build); - add_flag(&build_flags, BuildFlag_OptimizationMode, str_lit("O"), BuildFlagParam_String, Command__does_build); add_flag(&build_flags, BuildFlag_ShowTimings, str_lit("show-timings"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_ShowMoreTimings, str_lit("show-more-timings"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_ExportTimings, str_lit("export-timings"), BuildFlagParam_String, Command__does_check);