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

Reply via email to