Skip to content

Commit b164f4c

Browse files
committed
updates
1 parent 7c0c32e commit b164f4c

File tree

4 files changed

+58
-8
lines changed

4 files changed

+58
-8
lines changed

llvm/include/llvm/IR/RuntimeLibcalls.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,6 @@ struct RuntimeLibcallsInfo {
8585
LibcallRoutineNames + RTLIB::UNKNOWN_LIBCALL);
8686
}
8787

88-
/// Set a specific lowering convention for `fp128` math libcalls.
89-
///
90-
/// By default, `fp128` math functions get lowered to the C23 `sinf128`-
91-
/// style symbols. This allows overriding with `sinl`-style symbols on
92-
/// platforms where `long double` is known to be identical to _Float128.
93-
/// versions, e.g. `sinf128`.
94-
void setF128LibcallFormat(F128LibcallFormat Format);
95-
9688
private:
9789
/// Stores the name each libcall.
9890
const char *LibcallRoutineNames[RTLIB::UNKNOWN_LIBCALL + 1];
@@ -118,6 +110,13 @@ struct RuntimeLibcallsInfo {
118110
/// Set default libcall names. If a target wants to opt-out of a libcall it
119111
/// should be placed here.
120112
void initLibcalls(const Triple &TT);
113+
114+
/// Set a specific lowering convention for `fp128` math libcalls.
115+
///
116+
/// By default, `fp128` math functions get lowered to the C23 `sinf128`-
117+
/// style symbols. This allows overriding with `sinl`-style symbols on
118+
/// platforms where `long double` is known to be identical to _Float128.
119+
void setF128LibcallFormat(F128LibcallFormat Format);
121120
};
122121

123122
} // namespace RTLIB

llvm/include/llvm/TargetParser/Triple.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,12 @@ class Triple {
12431243
/// or an invalid version tuple if this triple doesn't have one.
12441244
VersionTuple getMinimumSupportedOSVersion() const;
12451245

1246+
/// Check whether (1) `f128` is the same format as `long double`, and (2)
1247+
/// `*f128` symbols are not available. In other words platforms for which
1248+
/// this returns true may safely use `sqrtl` instead of `sqrtf128`, and
1249+
/// should do so because `sqrtf128` isn't expected to be available.
1250+
bool shouldLowerf128AsLongDouble() const;
1251+
12461252
/// @}
12471253
/// @name Static helpers for IDs.
12481254
/// @{

llvm/lib/IR/RuntimeLibcalls.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,14 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT) {
205205
}
206206
setLibcallName(RTLIB::MULO_I128, nullptr);
207207
}
208+
209+
// By default, `fp128` libcalls get lowered to `*f128` symbols, which is
210+
// safest because the symbols are only ever for binary128 on all platforms.
211+
// Unfortunately many platforms only have the `*l` (`long double`) symbols,
212+
// which vary by architecture and compilation flags, so we have to use them
213+
// sometimes.
214+
if(TT.shouldLowerf128AsLongDouble())
215+
setF128LibcallFormat(F128LibcallFormat::LongDouble);
208216
}
209217

210218
void RuntimeLibcallsInfo::setF128LibcallFormat(F128LibcallFormat Format) {

llvm/lib/TargetParser/Triple.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2173,6 +2173,43 @@ VersionTuple Triple::getCanonicalVersionForOS(OSType OSKind,
21732173
}
21742174
}
21752175

2176+
bool Triple::shouldLowerf128AsLongDouble() const {
2177+
// Always prefer to lower to `*f128` symbols when they are likely to be
2178+
// available, to avoid any inaccuracies or problems from libc config.
2179+
//
2180+
// Note that the logic should be kept in sync with Clang's LongDoubleFormat.
2181+
2182+
// Glibc helpfully aliases `*f128` symbols to `*l` symbols on platforms where
2183+
// that works, so use those.
2184+
if (isGNUEnvironment())
2185+
return false;
2186+
2187+
// Windows and Apple always use f64 as `long double`.
2188+
if (isOSWindows() || isOSDarwin())
2189+
return false;
2190+
2191+
// Most 64-bit architectures use use binary128 on all OSs except Windows and
2192+
// Apple. A few are binary128 on both 64- and 32-bit.
2193+
if (isAArch64() || isLoongArch() || isRISCV() || isSPARC() || isSystemZ() ||
2194+
isVE() || isWasm())
2195+
return true;
2196+
2197+
// MIPS64 is usually f128, except on FreeBSD-like operating systems. MIPS32
2198+
// is f128 with N32 but f64 with the O32 ABI. Triple doesn't know about ABI
2199+
// here, so allow MIPS32 to hit the safer `ld !== f128` default.
2200+
if (isMIPS64() && !(isOSFreeBSD() || isOSKFreeBSD() || isOSDragonFly()))
2201+
return true;
2202+
2203+
// Android and Ohos use binary128 on x86_64.
2204+
if (getArch() == Triple::x86_64 && (isAndroid() || isOHOSFamily()))
2205+
return true;
2206+
2207+
// By default, make the safe assumption that `long double !== f128`. This
2208+
// also catchex x86 (`long double` is x87 `f80`) and PowerPC (`long double`
2209+
// is `f64` or PPC double-double).
2210+
return false;
2211+
}
2212+
21762213
// HLSL triple environment orders are relied on in the front end
21772214
static_assert(Triple::Vertex - Triple::Pixel == 1,
21782215
"incorrect HLSL stage order");

0 commit comments

Comments
 (0)