On ARM the gd pointer is stored in registers r9 / x18. For this the -ffixed-r9 / -ffixed-x18 flag when compiling, but using global register variables causes errors when building with LTO, and these errors are very difficult to overcome.
Richard Biener says [1]: Note that global register vars shouldn't be used with LTO and if they are restricted to just a few compilation units the recommended fix is to build those CUs without -flto. We cannot do this for U-Boot since all CUs use -ffixed-reg flag. It seems that with LTO we could in fact store the gd pointer differently and gain performance or size benefit by allowing the compiler to use r9 / x18. But this would need more work. So for now, when building with LTO, go the clang way, and instead of declaring gd a global register variable we make it a function via macro. [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68384 Signed-off-by: Marek Behún <marek.be...@nic.cz> --- arch/arm/include/asm/global_data.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index fba655f3b9..d694074bff 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -91,7 +91,7 @@ struct arch_global_data { #include <asm-generic/global_data.h> -#ifdef __clang__ +#if defined(__clang__) || defined(CONFIG_LTO) #define DECLARE_GLOBAL_DATA_PTR #define gd get_gd() -- 2.26.2