https://github.com/atetubou updated https://github.com/llvm/llvm-project/pull/207135
>From 0d2549a19ac4582762638f316922137eab5042ea Mon Sep 17 00:00:00 2001 From: Takuto Ikuta <[email protected]> Date: Thu, 2 Jul 2026 14:51:51 +0900 Subject: [PATCH] [Clang][CodeGen] Automatically resolve MSVC _hypotf and dllimport for __builtin_hypotf as a fallback When compiling C++ or C code that calls __builtin_hypotf without including header declarations (freestanding builtins), CodeGenModule::getBuiltinLibFunction emits external IR declarations based on its default name. For Windows MSVC targets: 1. Under dynamic CRT (/MD, where _DLL is defined), the function resides in DLLs. We need to automatically attach dllimport and clear dso_local for the emitted declaration to prevent unresolved external symbol errors at link time. 2. On all Windows MSVC targets (including x86, x64, ARM, and ARM64), __builtin_hypotf must be mapped to _hypotf because the MSVC CRT does not export hypotf without a prefix. Other C99 float math functions (such as logbf and nextafterf) are exported normally by UCRT without prefixes, so they do not need prefix mapping. This patch implements this fallback logic in CodeGenModule::getBuiltinLibFunction when no AST declaration for the library function exists. Adds regression test verifying the mapping and dllimport settings for hypotf under both static and dynamic CRT on x64, x86, ARM, and ARM64 Windows targets (clang/test/CodeGen/msvc-builtin-hypotf.c). --- clang/lib/CodeGen/CGBuiltin.cpp | 27 ++++++++++++++++++- clang/test/CodeGen/msvc-builtin-hypotf.c | 34 ++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 clang/test/CodeGen/msvc-builtin-hypotf.c diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 509ab4245d99a..0d9d9de88bd66 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -247,10 +247,35 @@ llvm::Constant *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD, Name = Context.BuiltinInfo.getName(BuiltinID).substr(10); } + // If no standard library declaration was found in the AST (freestanding + // code calling builtins directly without headers), perform automatic + // resolution of MSVC CRT symbol names and DLL import attributes. + bool IsNoHeader = (D == GlobalDecl(FD)); + if (IsNoHeader && getTriple().isWindowsMSVCEnvironment() && + Name == "hypotf") { + // Map C99 float math functions to their MSVC CRT prefixed names on Windows. + // (Only hypotf needs mapping as it is not exported without prefix in UCRT + // on both x86 and x64). + Name = "_hypotf"; + } + llvm::FunctionType *Ty = cast<llvm::FunctionType>(getTypes().ConvertType(FD->getType())); - return GetOrCreateLLVMFunction(Name, Ty, D, /*ForVTable=*/false); + llvm::Constant *C = GetOrCreateLLVMFunction(Name, Ty, D, /*ForVTable=*/false); + + // When compiling under dynamic CRT (/MD or -D_DLL), standard CRT library + // functions reside in dynamic runtime DLLs. Automatically attach dllimport + // storage class and clear dso_local for freestanding builtin calls. + if (IsNoHeader && getTriple().isWindowsMSVCEnvironment() && + Context.Idents.get("_DLL").hasMacroDefinition()) { + auto *F = dyn_cast<llvm::Function>(C); + if (F && F->isDeclaration() && !F->hasDLLImportStorageClass()) { + F->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + F->setDSOLocal(false); + } + } + return C; } /// Emit the conversions required to turn the given value into an diff --git a/clang/test/CodeGen/msvc-builtin-hypotf.c b/clang/test/CodeGen/msvc-builtin-hypotf.c new file mode 100644 index 0000000000000..38fe42f690788 --- /dev/null +++ b/clang/test/CodeGen/msvc-builtin-hypotf.c @@ -0,0 +1,34 @@ +// Test that calling builtin math library functions directly (without including standard headers +// like <math.h>) on Windows MSVC targets correctly resolves MSVC-specific CRT symbol names +// and DLL import storage classes. +// +// 1. On Windows MSVC (including x86, x64, ARM, and ARM64), __builtin_hypotf must be resolved with +// an underscore prefix (i.e. _hypotf) because it is not exported without a prefix in the MSVC CRT. +// 2. Under dynamic CRT configurations (/MD or -D_DLL), standard library functions reside +// in runtime DLLs. Thus, these freestanding builtin calls must inherit dllimport attributes +// and have their dso_local attributes cleared to avoid unresolved external symbol errors +// at link time. +// 3. Under static CRT configurations (/MT), these functions should not have dllimport +// attributes, but MSVC targets still require the underscore prefix mapping for _hypotf. + +// RUN: %clang_cc1 -triple i686-pc-windows-msvc -fdeclspec -D_DLL -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-X86-DLL +// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -fdeclspec -D_DLL -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-X64-DLL +// RUN: %clang_cc1 -triple thumbv7-pc-windows-msvc -fdeclspec -D_DLL -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-X64-DLL +// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -fdeclspec -D_DLL -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-X64-DLL +// RUN: %clang_cc1 -triple i686-pc-windows-msvc -fdeclspec -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-X86-STATIC +// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -fdeclspec -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-X64-STATIC +// RUN: %clang_cc1 -triple thumbv7-pc-windows-msvc -fdeclspec -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-X64-STATIC +// RUN: %clang_cc1 -triple aarch64-pc-windows-msvc -fdeclspec -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-X64-STATIC + + +float test_hypotf(float x, float y) { + return __builtin_hypotf(x, y); +} + +// CHECK-X86-DLL: declare dllimport {{.*}}float @_hypotf(float noundef, float noundef) +// CHECK-X64-DLL: declare dllimport {{.*}}float @_hypotf(float noundef, float noundef) +// CHECK-X86-STATIC: declare dso_local {{.*}}float @_hypotf(float noundef, float noundef) +// CHECK-X64-STATIC: declare dso_local {{.*}}float @_hypotf(float noundef, float noundef) + + + _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
