Skip to content

Commit d11fae1

Browse files
committed
[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`.
1 parent 089b811 commit d11fae1

File tree

1 file changed

+53
-41
lines changed

1 file changed

+53
-41
lines changed

libc/src/math/gpu/vendor/amdgpu/platform.h

+53-41
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#ifndef LLVM_LIBC_SRC_MATH_GPU_AMDGPU_PLATFORM_H
1010
#define LLVM_LIBC_SRC_MATH_GPU_AMDGPU_PLATFORM_H
1111

12+
#include "src/__support/macros/attributes.h"
13+
1214
#include <stdint.h>
1315

1416
namespace __llvm_libc {
@@ -19,96 +21,106 @@ namespace __llvm_libc {
1921
extern "C" {
2022

2123
// Disable unsafe math optimizations in the implementation.
22-
extern const uint8_t __oclc_unsafe_math_opt = 0;
24+
extern const LIBC_INLINE uint8_t __oclc_unsafe_math_opt = 0;
2325

2426
// Disable denormalization at zero optimizations in the implementation.
25-
extern const uint8_t __oclc_daz_opt = 0;
27+
extern const LIBC_INLINE uint8_t __oclc_daz_opt = 0;
2628

2729
// Disable rounding optimizations for 32-bit square roots.
28-
extern const uint8_t __oclc_correctly_rounded_sqrt32 = 1;
30+
extern const LIBC_INLINE uint8_t __oclc_correctly_rounded_sqrt32 = 1;
2931

3032
// Disable finite math optimizations.
31-
extern const uint8_t __oclc_finite_only_opt = 0;
33+
extern const LIBC_INLINE uint8_t __oclc_finite_only_opt = 0;
3234

3335
#if defined(__gfx700__)
34-
extern const uint32_t __oclc_ISA_version = 7000;
36+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 7000;
3537
#elif defined(__gfx701__)
36-
extern const uint32_t __oclc_ISA_version = 7001;
38+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 7001;
3739
#elif defined(__gfx702__)
38-
extern const uint32_t __oclc_ISA_version = 7002;
40+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 7002;
3941
#elif defined(__gfx703__)
40-
extern const uint32_t __oclc_ISA_version = 7003;
42+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 7003;
4143
#elif defined(__gfx704__)
42-
extern const uint32_t __oclc_ISA_version = 7004;
44+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 7004;
4345
#elif defined(__gfx705__)
44-
extern const uint32_t __oclc_ISA_version = 7005;
46+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 7005;
4547
#elif defined(__gfx801__)
46-
extern const uint32_t __oclc_ISA_version = 8001;
48+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 8001;
4749
#elif defined(__gfx802__)
48-
extern const uint32_t __oclc_ISA_version = 8002;
50+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 8002;
4951
#elif defined(__gfx803__)
50-
extern const uint32_t __oclc_ISA_version = 8003;
52+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 8003;
5153
#elif defined(__gfx805__)
52-
extern const uint32_t __oclc_ISA_version = 8005;
54+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 8005;
5355
#elif defined(__gfx810__)
54-
extern const uint32_t __oclc_ISA_version = 8100;
56+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 8100;
5557
#elif defined(__gfx900__)
56-
extern const uint32_t __oclc_ISA_version = 9000;
58+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 9000;
5759
#elif defined(__gfx902__)
58-
extern const uint32_t __oclc_ISA_version = 9002;
60+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 9002;
5961
#elif defined(__gfx904__)
60-
extern const uint32_t __oclc_ISA_version = 9004;
62+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 9004;
6163
#elif defined(__gfx906__)
62-
extern const uint32_t __oclc_ISA_version = 9006;
64+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 9006;
6365
#elif defined(__gfx908__)
64-
extern const uint32_t __oclc_ISA_version = 9008;
66+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 9008;
6567
#elif defined(__gfx909__)
66-
extern const uint32_t __oclc_ISA_version = 9009;
68+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 9009;
6769
#elif defined(__gfx90a__)
68-
extern const uint32_t __oclc_ISA_version = 9010;
70+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 9010;
6971
#elif defined(__gfx90c__)
70-
extern const uint32_t __oclc_ISA_version = 9012;
72+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 9012;
7173
#elif defined(__gfx940__)
72-
extern const uint32_t __oclc_ISA_version = 9400;
74+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 9400;
7375
#elif defined(__gfx1010__)
74-
extern const uint32_t __oclc_ISA_version = 10100;
76+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 10100;
7577
#elif defined(__gfx1011__)
76-
extern const uint32_t __oclc_ISA_version = 10101;
78+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 10101;
7779
#elif defined(__gfx1012__)
78-
extern const uint32_t __oclc_ISA_version = 10102;
80+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 10102;
7981
#elif defined(__gfx1013__)
80-
extern const uint32_t __oclc_ISA_version = 10103;
82+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 10103;
8183
#elif defined(__gfx1030__)
82-
extern const uint32_t __oclc_ISA_version = 10300;
84+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 10300;
8385
#elif defined(__gfx1031__)
84-
extern const uint32_t __oclc_ISA_version = 10301;
86+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 10301;
8587
#elif defined(__gfx1032__)
86-
extern const uint32_t __oclc_ISA_version = 10302;
88+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 10302;
8789
#elif defined(__gfx1033__)
88-
extern const uint32_t __oclc_ISA_version = 10303;
90+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 10303;
8991
#elif defined(__gfx1034__)
90-
extern const uint32_t __oclc_ISA_version = 10304;
92+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 10304;
9193
#elif defined(__gfx1035__)
92-
extern const uint32_t __oclc_ISA_version = 10305;
94+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 10305;
9395
#elif defined(__gfx1036__)
94-
extern const uint32_t __oclc_ISA_version = 10306;
96+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 10306;
9597
#elif defined(__gfx1100__)
96-
extern const uint32_t __oclc_ISA_version = 11000;
98+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 11000;
9799
#elif defined(__gfx1101__)
98-
extern const uint32_t __oclc_ISA_version = 11001;
100+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 11001;
99101
#elif defined(__gfx1102__)
100-
extern const uint32_t __oclc_ISA_version = 11002;
102+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 11002;
101103
#elif defined(__gfx1103__)
102-
extern const uint32_t __oclc_ISA_version = 11003;
104+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 11003;
103105
#elif defined(__gfx1150__)
104-
extern const uint32_t __oclc_ISA_version = 11500;
106+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 11500;
105107
#elif defined(__gfx1151__)
106-
extern const uint32_t __oclc_ISA_version = 11501;
108+
extern const LIBC_INLINE uint32_t __oclc_ISA_version = 11501;
107109
#else
108110
#error "Unknown AMDGPU architecture"
109111
#endif
110112
}
111113

114+
// These aliases cause clang to emit the control constants with ODR linkage.
115+
// This allows us to link against the symbols without preventing them from being
116+
// optimized out or causing symbol collisions.
117+
[[gnu::alias("__oclc_unsafe_math_opt")]] const uint8_t __oclc_unsafe_math_opt__;
118+
[[gnu::alias("__oclc_daz_opt")]] const uint8_t __oclc_daz_opt__;
119+
[[gnu::alias("__oclc_correctly_rounded_sqrt32")]] const uint8_t
120+
__oclc_correctly_rounded_sqrt32__;
121+
[[gnu::alias("__oclc_finite_only_opt")]] const uint8_t __oclc_finite_only_opt__;
122+
[[gnu::alias("__oclc_ISA_version")]] const uint32_t __oclc_ISA_version__;
123+
112124
} // namespace __llvm_libc
113125

114126
#endif // LLVM_LIBC_SRC_MATH_GPU_AMDGPU_PLATFORM_H

0 commit comments

Comments
 (0)