-
Notifications
You must be signed in to change notification settings - Fork 12.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[amdgpu] Using fp128 fails with unsupported libcalls #121122
Comments
@llvm/issue-subscribers-backend-amdgpu Author: Sebastian Neubauer (Flakebi)
`fp128` seems to work fine in arguments and return values, but trying to do computations like `fmul` or `fdiv` fails:
```llvm
target triple = "amdgcn-amd-amdhsa"
define fp128 @fp128(fp128 %a, fp128 %b) {
LLVM ERROR: unsupported libcall legalization
|
This is expected. We do not have any support for fp128 operations in any form. There's no inline soft float expansion, and we don't have the infrastructure to use compiler-rt |
This is fp128-specific, correct? I.e. there isn't a technical reason that AMDGPU is unable to make use of any libcalls. |
Oh there certainly are reasons we cannot use any libcalls. We do not have the infrastructure to link compiler-rt, and do not support object linking |
This seems to be frontend-specific. We may not have such infrastructure for clang yet, but rustc has it, it tries to link in the Rust compiler-builtins lib that provides implementations. (This linking can be done with LTO, so it doesn’t need object linking.) I was able to compile builtins with Rust with 2 changes:
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index 7f95442401db..4bf0f5c32d94 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -3667,8 +3667,27 @@ SDValue SITargetLowering::LowerCall(CallLoweringInfo &CLI,
"unsupported call to variadic function ");
}
- if (!CLI.CB)
- report_fatal_error("unsupported libcall legalization");
+ if (!CLI.CB) {
+ // Is a libcall. If the function is defined in the current module, use it,
+ // otherwise abort.
+ bool FoundImpl = false;
+ if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
+ const char *SymName = S->getSymbol();
+ const Module *Mod = DAG.getMachineFunction().getFunction().getParent();
+ if (const Function *F =
+ dyn_cast_or_null<Function>(Mod->getNamedValue(SymName))) {
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ EVT VT = TLI.getValueType(DAG.getDataLayout(), F->getType(), true);
+ Callee = DAG.getGlobalAddress(F, DL, VT);
+ FoundImpl = true;
+ } else if (SymName) {
+ report_fatal_error(Twine("unsupported libcall legalization, did not find '") + SymName + "'");
+ }
+ }
+
+ if (!FoundImpl)
+ report_fatal_error("unsupported libcall legalization");
+ }
if (IsTailCall && MF.getTarget().Options.GuaranteedTailCallOpt) {
return lowerUnhandledCall(CLI, InVals, This is from PowerPC (slightly adjusted).
As a result, the name we get at (1) is just It seems to me that the decision of which libcalls are available may be better in the frontend instead of the backend, though this is probably rather difficult to change. |
It's the exact opposite. The fact that we try to treat "libcalls" as a front-end/language property is a significant fraction of the legacy issues we experience. We need to define the platform for what calls are available.
Where the libcalls are linked in is significant. Without object linking, you would have to force linking in every possible libcall as used and codegen in it in 100% of situations just in case it ends up getting used, which is a significant compile time burden. We really need to put in the work to support compiler-rt in a normal-ish way |
fp128
seems to work fine in arguments and return values, but trying to do computations likefmul
orfdiv
fails:results in
I assume this is expected.
I encountered this while trying to compile Rust code, see also rust-lang/compiler-builtins#737.
The text was updated successfully, but these errors were encountered: