Skip to content

Conversation

arsenm
Copy link
Contributor

@arsenm arsenm commented Aug 13, 2025

The __truncdfhf2 handling is kind of convoluted, but reproduces
the existing, likely wrong, handling.

@llvmbot
Copy link
Member

llvmbot commented Aug 13, 2025

@llvm/pr-subscribers-backend-arm

@llvm/pr-subscribers-llvm-ir

Author: Matt Arsenault (arsenm)

Changes

The __truncdfhf2 handling is kind of convoluted, but reproduces
the existing, likely wrong, handling.


Full diff: https://github.com/llvm/llvm-project/pull/153408.diff

2 Files Affected:

  • (modified) llvm/include/llvm/IR/RuntimeLibcalls.td (+23-5)
  • (modified) llvm/lib/IR/RuntimeLibcalls.cpp (-19)
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 89bb0be4d26e9..a98e94455dd21 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -1532,10 +1532,17 @@ def ARMHalfConvertLibcallCallingConv : LibcallCallingConv<
     (isAAPCS_ABI(TT, ABIName) ? CallingConv::ARM_AAPCS : CallingConv::ARM_APCS)}]
 >;
 
-def GNUEABIHalfConvertCalls :
-  LibcallImpls<(add __gnu_f2h_ieee, __gnu_h2f_ieee),
-    RuntimeLibcallPredicate<[{!TT.isOSBinFormatMachO() &&
-                              !TT.isTargetAEABI()}]>> {
+def ARMLibgccHalfConvertCalls :
+  LibcallImpls<(add __truncsfhf2, __extendhfsf2),
+    RuntimeLibcallPredicate<[{!TT.isTargetAEABI() && TT.isOSBinFormatMachO()}]>> {
+  let CallingConv = ARMHalfConvertLibcallCallingConv;
+}
+
+// FIXME: These conditions are probably bugged. We're using the
+// default libgcc call when the other cases are replaced.
+def ARMDoubleToHalfCalls :
+  LibcallImpls<(add __truncdfhf2),
+    RuntimeLibcallPredicate<[{!TT.isTargetAEABI()}]>> {
   let CallingConv = ARMHalfConvertLibcallCallingConv;
 }
 
@@ -1546,6 +1553,13 @@ def EABIHalfConvertCalls : LibcallImpls<(add __aeabi_f2h, __aeabi_h2f),
   let CallingConv = ARM_AAPCS;
 }
 
+def GNUEABIHalfConvertCalls :
+  LibcallImpls<(add __gnu_f2h_ieee, __gnu_h2f_ieee),
+    RuntimeLibcallPredicate<[{!TT.isOSBinFormatMachO() &&
+                              !TT.isTargetAEABI()}]>> {
+  let CallingConv = ARMHalfConvertLibcallCallingConv;
+}
+
 def WindowARMDivRemCalls : LibcallImpls<
   (add __rt_sdiv, __rt_sdiv64, __rt_udiv, __rt_udiv64),
   isOSWindows> {
@@ -1665,7 +1679,9 @@ def isARMOrThumb : RuntimeLibcallPredicate<"TT.isARM() || TT.isThumb()">;
 
 def ARMSystemLibrary
     : SystemRuntimeLibrary<isARMOrThumb,
-      (add WinDefaultLibcallImpls,
+      (add (sub WinDefaultLibcallImpls, ARMLibgccHalfConvertCalls,
+                                        GNUEABIHalfConvertCalls,
+                                        ARMDoubleToHalfCalls),
            LibcallImpls<(add __powisf2, __powidf2), isNotOSMSVCRT>,
            LibmHasFrexpF32, LibmHasLdexpF32,
            LibmHasFrexpF128, LibmHasLdexpF128,
@@ -1679,8 +1695,10 @@ def ARMSystemLibrary
 
            AEABICalls,
            AEABI45MemCalls,
+           ARMLibgccHalfConvertCalls,
            EABIHalfConvertCalls,
            GNUEABIHalfConvertCalls,
+           ARMDoubleToHalfCalls,
 
            // Use divmod compiler-rt calls for iOS 5.0 and later.
            LibcallImpls<(add __divmodsi4, __udivmodsi4),
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index ac845c4998783..83f7df5e9f587 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -33,25 +33,6 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
   if (ExceptionModel == ExceptionHandling::SjLj)
     setLibcallImpl(RTLIB::UNWIND_RESUME, RTLIB::_Unwind_SjLj_Resume);
 
-  if (TT.isARM() || TT.isThumb()) {
-    // The half <-> float conversion functions are always soft-float on
-    // non-watchos platforms, but are needed for some targets which use a
-    // hard-float calling convention by default.
-    if (!TT.isWatchABI()) {
-      if (isAAPCS_ABI(TT, ABIName)) {
-        setLibcallImplCallingConv(RTLIB::__truncsfhf2, CallingConv::ARM_AAPCS);
-        setLibcallImplCallingConv(RTLIB::__truncdfhf2, CallingConv::ARM_AAPCS);
-        setLibcallImplCallingConv(RTLIB::__extendhfsf2, CallingConv::ARM_AAPCS);
-      } else {
-        setLibcallImplCallingConv(RTLIB::__truncsfhf2, CallingConv::ARM_APCS);
-        setLibcallImplCallingConv(RTLIB::__truncdfhf2, CallingConv::ARM_APCS);
-        setLibcallImplCallingConv(RTLIB::__extendhfsf2, CallingConv::ARM_APCS);
-      }
-    }
-
-    return;
-  }
-
   if (TT.getArch() == Triple::ArchType::msp430) {
     setLibcallImplCallingConv(RTLIB::__mspabi_mpyll,
                               CallingConv::MSP430_BUILTIN);

@llvmbot
Copy link
Member

llvmbot commented Aug 13, 2025

@llvm/pr-subscribers-tablegen

Author: Matt Arsenault (arsenm)

Changes

The __truncdfhf2 handling is kind of convoluted, but reproduces
the existing, likely wrong, handling.


Full diff: https://github.com/llvm/llvm-project/pull/153408.diff

2 Files Affected:

  • (modified) llvm/include/llvm/IR/RuntimeLibcalls.td (+23-5)
  • (modified) llvm/lib/IR/RuntimeLibcalls.cpp (-19)
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 89bb0be4d26e9..a98e94455dd21 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -1532,10 +1532,17 @@ def ARMHalfConvertLibcallCallingConv : LibcallCallingConv<
     (isAAPCS_ABI(TT, ABIName) ? CallingConv::ARM_AAPCS : CallingConv::ARM_APCS)}]
 >;
 
-def GNUEABIHalfConvertCalls :
-  LibcallImpls<(add __gnu_f2h_ieee, __gnu_h2f_ieee),
-    RuntimeLibcallPredicate<[{!TT.isOSBinFormatMachO() &&
-                              !TT.isTargetAEABI()}]>> {
+def ARMLibgccHalfConvertCalls :
+  LibcallImpls<(add __truncsfhf2, __extendhfsf2),
+    RuntimeLibcallPredicate<[{!TT.isTargetAEABI() && TT.isOSBinFormatMachO()}]>> {
+  let CallingConv = ARMHalfConvertLibcallCallingConv;
+}
+
+// FIXME: These conditions are probably bugged. We're using the
+// default libgcc call when the other cases are replaced.
+def ARMDoubleToHalfCalls :
+  LibcallImpls<(add __truncdfhf2),
+    RuntimeLibcallPredicate<[{!TT.isTargetAEABI()}]>> {
   let CallingConv = ARMHalfConvertLibcallCallingConv;
 }
 
@@ -1546,6 +1553,13 @@ def EABIHalfConvertCalls : LibcallImpls<(add __aeabi_f2h, __aeabi_h2f),
   let CallingConv = ARM_AAPCS;
 }
 
+def GNUEABIHalfConvertCalls :
+  LibcallImpls<(add __gnu_f2h_ieee, __gnu_h2f_ieee),
+    RuntimeLibcallPredicate<[{!TT.isOSBinFormatMachO() &&
+                              !TT.isTargetAEABI()}]>> {
+  let CallingConv = ARMHalfConvertLibcallCallingConv;
+}
+
 def WindowARMDivRemCalls : LibcallImpls<
   (add __rt_sdiv, __rt_sdiv64, __rt_udiv, __rt_udiv64),
   isOSWindows> {
@@ -1665,7 +1679,9 @@ def isARMOrThumb : RuntimeLibcallPredicate<"TT.isARM() || TT.isThumb()">;
 
 def ARMSystemLibrary
     : SystemRuntimeLibrary<isARMOrThumb,
-      (add WinDefaultLibcallImpls,
+      (add (sub WinDefaultLibcallImpls, ARMLibgccHalfConvertCalls,
+                                        GNUEABIHalfConvertCalls,
+                                        ARMDoubleToHalfCalls),
            LibcallImpls<(add __powisf2, __powidf2), isNotOSMSVCRT>,
            LibmHasFrexpF32, LibmHasLdexpF32,
            LibmHasFrexpF128, LibmHasLdexpF128,
@@ -1679,8 +1695,10 @@ def ARMSystemLibrary
 
            AEABICalls,
            AEABI45MemCalls,
+           ARMLibgccHalfConvertCalls,
            EABIHalfConvertCalls,
            GNUEABIHalfConvertCalls,
+           ARMDoubleToHalfCalls,
 
            // Use divmod compiler-rt calls for iOS 5.0 and later.
            LibcallImpls<(add __divmodsi4, __udivmodsi4),
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index ac845c4998783..83f7df5e9f587 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -33,25 +33,6 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
   if (ExceptionModel == ExceptionHandling::SjLj)
     setLibcallImpl(RTLIB::UNWIND_RESUME, RTLIB::_Unwind_SjLj_Resume);
 
-  if (TT.isARM() || TT.isThumb()) {
-    // The half <-> float conversion functions are always soft-float on
-    // non-watchos platforms, but are needed for some targets which use a
-    // hard-float calling convention by default.
-    if (!TT.isWatchABI()) {
-      if (isAAPCS_ABI(TT, ABIName)) {
-        setLibcallImplCallingConv(RTLIB::__truncsfhf2, CallingConv::ARM_AAPCS);
-        setLibcallImplCallingConv(RTLIB::__truncdfhf2, CallingConv::ARM_AAPCS);
-        setLibcallImplCallingConv(RTLIB::__extendhfsf2, CallingConv::ARM_AAPCS);
-      } else {
-        setLibcallImplCallingConv(RTLIB::__truncsfhf2, CallingConv::ARM_APCS);
-        setLibcallImplCallingConv(RTLIB::__truncdfhf2, CallingConv::ARM_APCS);
-        setLibcallImplCallingConv(RTLIB::__extendhfsf2, CallingConv::ARM_APCS);
-      }
-    }
-
-    return;
-  }
-
   if (TT.getArch() == Triple::ArchType::msp430) {
     setLibcallImplCallingConv(RTLIB::__mspabi_mpyll,
                               CallingConv::MSP430_BUILTIN);

@arsenm arsenm force-pushed the users/arsenm/arm/move-gnu-half-convert-libcall-calling-conv-config-tablegen branch from 283d03d to 83b3bab Compare August 13, 2025 23:38
@arsenm arsenm force-pushed the users/arsenm/arm/move-remaining-half-convert-calling-conv-config-tablegen branch from da9d432 to 333abd7 Compare August 13, 2025 23:38
@arsenm arsenm force-pushed the users/arsenm/arm/move-gnu-half-convert-libcall-calling-conv-config-tablegen branch from 83b3bab to 2b09c7b Compare August 14, 2025 07:08
@arsenm arsenm force-pushed the users/arsenm/arm/move-remaining-half-convert-calling-conv-config-tablegen branch from 333abd7 to e77db15 Compare August 14, 2025 07:08
Base automatically changed from users/arsenm/arm/move-gnu-half-convert-libcall-calling-conv-config-tablegen to main August 14, 2025 08:36
@arsenm arsenm force-pushed the users/arsenm/arm/move-remaining-half-convert-calling-conv-config-tablegen branch from e77db15 to bf4e8a6 Compare August 14, 2025 14:14
@@ -1497,6 +1490,27 @@ def ARMHalfConvertLibcallCallingConv : LibcallCallingConv<
(isAAPCS_ABI(TT, ABIName) ? CallingConv::ARM_AAPCS : CallingConv::ARM_APCS)}]
>;

def ARMLibgccHalfConvertCalls :
LibcallImpls<(add __truncsfhf2, __extendhfsf2),
RuntimeLibcallPredicate<[{!TT.isTargetAEABI() && TT.isOSBinFormatMachO()}]>> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I follow this - the old code would add these on !Watch ABI as either AAPCS or APCS.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are the default values, and !WatchABI is not mutually exclusive. This needs to be expressed as the positive set of cases where it is used

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, but what I mean to say is that this feels like it applies to far more cases than previously.

// default libgcc call when the other cases are replaced.
def ARMDoubleToHalfCalls :
LibcallImpls<(add __truncdfhf2),
RuntimeLibcallPredicate<[{!TT.isTargetAEABI()}]>> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise

@arsenm arsenm changed the title ARM: Remove remaining half convert libcall config into tablegen ARM: Move remaining half convert libcall config into tablegen Aug 19, 2025
The __truncdfhf2 handling is kind of convoluted, but reproduces
the existing, likely wrong, handling.
@arsenm arsenm force-pushed the users/arsenm/arm/move-remaining-half-convert-calling-conv-config-tablegen branch from bf4e8a6 to 67eb146 Compare August 19, 2025 06:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants