[libc-commits] [libc] [libc] Fix linking of AMDGPU device runtime control constants for math (PR #65676)

Joseph Huber via libc-commits libc-commits at lists.llvm.org
Fri Sep 8 05:15:37 PDT 2023


https://github.com/jhuber6 updated https://github.com/llvm/llvm-project/pull/65676:

>From 9e81d06d7939ad9f32dd99f6dac0c3891b0c684b Mon Sep 17 00:00:00 2001
From: Joseph Huber <jhuber6 at vols.utk.edu>
Date: Thu, 7 Sep 2023 16:08:30 -0500
Subject: [PATCH] [libc] Fix linking of AMDGPU device runtime control constants
 for math

Summary:
Currently, `libc` temporarily provides math by linking against existing
vendor implementations. To use the AMDGPU DeviceRTL we need to define a
handful of control constants that alter behaviour for architecture
specific things. Previously these were marked `extern const` because
they must be present when we link-in the vendor bitcode library.
However, this causes linker errors if more than one math function was
used.

This patch fixes the issue by marking these functions as used and inline
on top of being external. This means that they are linkable, but it
gives us `linkonce_odr` semantics. The downside is that these globals
won't be optimized out, but it allows us to perform constant propagation
on them unlike using `weak`.
---
 libc/src/math/gpu/vendor/amdgpu/platform.h | 92 ++++++++++++----------
 1 file changed, 51 insertions(+), 41 deletions(-)

diff --git a/libc/src/math/gpu/vendor/amdgpu/platform.h b/libc/src/math/gpu/vendor/amdgpu/platform.h
index 6ec47c24a93a2d7..f9543f8ecb0912b 100644
--- a/libc/src/math/gpu/vendor/amdgpu/platform.h
+++ b/libc/src/math/gpu/vendor/amdgpu/platform.h
@@ -19,96 +19,106 @@ namespace __llvm_libc {
 extern "C" {
 
 // Disable unsafe math optimizations in the implementation.
-extern const uint8_t __oclc_unsafe_math_opt = 0;
+extern const inline uint8_t __oclc_unsafe_math_opt = 0;
 
 // Disable denormalization at zero optimizations in the implementation.
-extern const uint8_t __oclc_daz_opt = 0;
+extern const inline uint8_t __oclc_daz_opt = 0;
 
 // Disable rounding optimizations for 32-bit square roots.
-extern const uint8_t __oclc_correctly_rounded_sqrt32 = 1;
+extern const inline uint8_t __oclc_correctly_rounded_sqrt32 = 1;
 
 // Disable finite math optimizations.
-extern const uint8_t __oclc_finite_only_opt = 0;
+extern const inline uint8_t __oclc_finite_only_opt = 0;
 
 #if defined(__gfx700__)
-extern const uint32_t __oclc_ISA_version = 7000;
+extern const inline uint32_t __oclc_ISA_version = 7000;
 #elif defined(__gfx701__)
-extern const uint32_t __oclc_ISA_version = 7001;
+extern const inline uint32_t __oclc_ISA_version = 7001;
 #elif defined(__gfx702__)
-extern const uint32_t __oclc_ISA_version = 7002;
+extern const inline uint32_t __oclc_ISA_version = 7002;
 #elif defined(__gfx703__)
-extern const uint32_t __oclc_ISA_version = 7003;
+extern const inline uint32_t __oclc_ISA_version = 7003;
 #elif defined(__gfx704__)
-extern const uint32_t __oclc_ISA_version = 7004;
+extern const inline uint32_t __oclc_ISA_version = 7004;
 #elif defined(__gfx705__)
-extern const uint32_t __oclc_ISA_version = 7005;
+extern const inline uint32_t __oclc_ISA_version = 7005;
 #elif defined(__gfx801__)
-extern const uint32_t __oclc_ISA_version = 8001;
+extern const inline uint32_t __oclc_ISA_version = 8001;
 #elif defined(__gfx802__)
-extern const uint32_t __oclc_ISA_version = 8002;
+extern const inline uint32_t __oclc_ISA_version = 8002;
 #elif defined(__gfx803__)
-extern const uint32_t __oclc_ISA_version = 8003;
+extern const inline uint32_t __oclc_ISA_version = 8003;
 #elif defined(__gfx805__)
-extern const uint32_t __oclc_ISA_version = 8005;
+extern const inline uint32_t __oclc_ISA_version = 8005;
 #elif defined(__gfx810__)
-extern const uint32_t __oclc_ISA_version = 8100;
+extern const inline uint32_t __oclc_ISA_version = 8100;
 #elif defined(__gfx900__)
-extern const uint32_t __oclc_ISA_version = 9000;
+extern const inline uint32_t __oclc_ISA_version = 9000;
 #elif defined(__gfx902__)
-extern const uint32_t __oclc_ISA_version = 9002;
+extern const inline uint32_t __oclc_ISA_version = 9002;
 #elif defined(__gfx904__)
-extern const uint32_t __oclc_ISA_version = 9004;
+extern const inline uint32_t __oclc_ISA_version = 9004;
 #elif defined(__gfx906__)
-extern const uint32_t __oclc_ISA_version = 9006;
+extern const inline uint32_t __oclc_ISA_version = 9006;
 #elif defined(__gfx908__)
-extern const uint32_t __oclc_ISA_version = 9008;
+extern const inline uint32_t __oclc_ISA_version = 9008;
 #elif defined(__gfx909__)
-extern const uint32_t __oclc_ISA_version = 9009;
+extern const inline uint32_t __oclc_ISA_version = 9009;
 #elif defined(__gfx90a__)
-extern const uint32_t __oclc_ISA_version = 9010;
+extern const inline uint32_t __oclc_ISA_version = 9010;
 #elif defined(__gfx90c__)
-extern const uint32_t __oclc_ISA_version = 9012;
+extern const inline uint32_t __oclc_ISA_version = 9012;
 #elif defined(__gfx940__)
-extern const uint32_t __oclc_ISA_version = 9400;
+extern const inline uint32_t __oclc_ISA_version = 9400;
 #elif defined(__gfx1010__)
-extern const uint32_t __oclc_ISA_version = 10100;
+extern const inline uint32_t __oclc_ISA_version = 10100;
 #elif defined(__gfx1011__)
-extern const uint32_t __oclc_ISA_version = 10101;
+extern const inline uint32_t __oclc_ISA_version = 10101;
 #elif defined(__gfx1012__)
-extern const uint32_t __oclc_ISA_version = 10102;
+extern const inline uint32_t __oclc_ISA_version = 10102;
 #elif defined(__gfx1013__)
-extern const uint32_t __oclc_ISA_version = 10103;
+extern const inline uint32_t __oclc_ISA_version = 10103;
 #elif defined(__gfx1030__)
-extern const uint32_t __oclc_ISA_version = 10300;
+extern const inline uint32_t __oclc_ISA_version = 10300;
 #elif defined(__gfx1031__)
-extern const uint32_t __oclc_ISA_version = 10301;
+extern const inline uint32_t __oclc_ISA_version = 10301;
 #elif defined(__gfx1032__)
-extern const uint32_t __oclc_ISA_version = 10302;
+extern const inline uint32_t __oclc_ISA_version = 10302;
 #elif defined(__gfx1033__)
-extern const uint32_t __oclc_ISA_version = 10303;
+extern const inline uint32_t __oclc_ISA_version = 10303;
 #elif defined(__gfx1034__)
-extern const uint32_t __oclc_ISA_version = 10304;
+extern const inline uint32_t __oclc_ISA_version = 10304;
 #elif defined(__gfx1035__)
-extern const uint32_t __oclc_ISA_version = 10305;
+extern const inline uint32_t __oclc_ISA_version = 10305;
 #elif defined(__gfx1036__)
-extern const uint32_t __oclc_ISA_version = 10306;
+extern const inline uint32_t __oclc_ISA_version = 10306;
 #elif defined(__gfx1100__)
-extern const uint32_t __oclc_ISA_version = 11000;
+extern const inline uint32_t __oclc_ISA_version = 11000;
 #elif defined(__gfx1101__)
-extern const uint32_t __oclc_ISA_version = 11001;
+extern const inline uint32_t __oclc_ISA_version = 11001;
 #elif defined(__gfx1102__)
-extern const uint32_t __oclc_ISA_version = 11002;
+extern const inline uint32_t __oclc_ISA_version = 11002;
 #elif defined(__gfx1103__)
-extern const uint32_t __oclc_ISA_version = 11003;
+extern const inline uint32_t __oclc_ISA_version = 11003;
 #elif defined(__gfx1150__)
-extern const uint32_t __oclc_ISA_version = 11500;
+extern const inline uint32_t __oclc_ISA_version = 11500;
 #elif defined(__gfx1151__)
-extern const uint32_t __oclc_ISA_version = 11501;
+extern const inline uint32_t __oclc_ISA_version = 11501;
 #else
 #error "Unknown AMDGPU architecture"
 #endif
 }
 
+// These aliases cause clang to emit the control constants with ODR linkage.
+// This allows us to link against the symbols without preventing them from being
+// optimized out or causing symbol collisions.
+[[gnu::alias("__oclc_unsafe_math_opt")]] const uint8_t __oclc_unsafe_math_opt__;
+[[gnu::alias("__oclc_daz_opt")]] const uint8_t __oclc_daz_opt__;
+[[gnu::alias("__oclc_correctly_rounded_sqrt32")]] const uint8_t
+    __oclc_correctly_rounded_sqrt32__;
+[[gnu::alias("__oclc_finite_only_opt")]] const uint8_t __oclc_finite_only_opt__;
+[[gnu::alias("__oclc_ISA_version")]] const uint32_t __oclc_ISA_version__;
+
 } // namespace __llvm_libc
 
 #endif // LLVM_LIBC_SRC_MATH_GPU_AMDGPU_PLATFORM_H



More information about the libc-commits mailing list