Browse Source

Update ABI breaking changes for `f16` types (due to LLVM 15+)

gingerBill 1 year ago
parent
commit
96fbafe359
5 changed files with 32 additions and 22 deletions
  1. 15 11
      core/runtime/internal.odin
  2. 3 0
      src/checker.cpp
  3. 14 0
      src/llvm_backend.hpp
  4. 0 10
      src/llvm_backend_opt.cpp
  5. 0 1
      src/main.cpp

+ 15 - 11
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)
 }
 

+ 3 - 0
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++) {

+ 14 - 0
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 {

+ 0 - 10
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;
 }

+ 0 - 1
src/main.cpp

@@ -412,7 +412,6 @@ gb_internal bool parse_build_flags(Array<String> 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);