[llvm] [SelectionDAG] Respect no-builtins attribute in SMULO expansion (PR #191020)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 8 10:52:41 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-webassembly
Author: Cameron Taggart (cataggar)
<details>
<summary>Changes</summary>
When expanding `ISD::SMULO` for types that require a libcall (e.g. i128 on WebAssembly), the legalizer now checks for the `no-builtins` function attribute. If present, it expands inline instead of emitting a call to `__muloti4`.
This prevents infinite recursion when a custom implementation of `__muloti4` (under a different name) is compiled with `no-builtins`, as the overflow intrinsic introduced by instcombine would otherwise be lowered back to a call to `__muloti4`.
Fixes https://github.com/llvm/llvm-project/issues/189173
---
**Disclosure (per [LLVM AI Tool Use Policy](https://llvm.org/docs/AIToolPolicy.html)):** This patch was drafted with assistance from GitHub Copilot. It was reviewed, tested, and validated locally by @<!-- -->cataggar, who takes full responsibility for the submission and is available to answer reviewer questions.
---
Full diff: https://github.com/llvm/llvm-project/pull/191020.diff
2 Files Affected:
- (modified) llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (+6-3)
- (added) llvm/test/CodeGen/WebAssembly/muloti4-no-builtins.ll (+21)
``````````diff
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 35e61b78e99a2..eed88eb3cdd47 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -5301,11 +5301,14 @@ void DAGTypeLegalizer::ExpandIntRes_XMULO(SDNode *N,
RTLIB::Libcall LC = RTLIB::getMULO(VT);
RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
- // If we don't have the libcall or if the function we are compiling is the
- // implementation of the expected libcall (avoid inf-loop), expand inline.
+ // If we don't have the libcall, if the function we are compiling is the
+ // implementation of the expected libcall (avoid inf-loop), or if the
+ // function has the no-builtins attribute (it may be a custom implementation
+ // of the libcall under a different name), expand inline.
if (LCImpl == RTLIB::Unsupported ||
RTLIB::RuntimeLibcallsInfo::getLibcallImplName(LCImpl) ==
- DAG.getMachineFunction().getName()) {
+ DAG.getMachineFunction().getName() ||
+ DAG.getMachineFunction().getFunction().hasFnAttribute("no-builtins")) {
// FIXME: This is not an optimal expansion, but better than crashing.
SDValue MulLo, MulHi;
TLI.forceExpandWideMUL(DAG, dl, /*Signed=*/true, N->getOperand(0),
diff --git a/llvm/test/CodeGen/WebAssembly/muloti4-no-builtins.ll b/llvm/test/CodeGen/WebAssembly/muloti4-no-builtins.ll
new file mode 100644
index 0000000000000..b75bf4d16fb58
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/muloti4-no-builtins.ll
@@ -0,0 +1,21 @@
+; RUN: llc -asm-verbose=false < %s -wasm-keep-registers | FileCheck %s
+
+; Test that 128-bit smul.with.overflow does not emit a call to __muloti4
+; when the function has the "no-builtins" attribute. This avoids infinite
+; recursion when the function is a custom implementation of __muloti4.
+; See https://github.com/llvm/llvm-project/issues/189173
+
+target triple = "wasm32-unknown-unknown"
+
+define i128 @custom_muloti4(i128 %a, i128 %b) nounwind "no-builtins" {
+entry:
+ %smul = tail call { i128, i1 } @llvm.smul.with.overflow.i128(i128 %a, i128 %b)
+ %cmp = extractvalue { i128, i1 } %smul, 1
+ %smul.result = extractvalue { i128, i1 } %smul, 0
+ %X = select i1 %cmp, i128 %smul.result, i128 42
+ ret i128 %X
+}
+
+; CHECK-NOT: call __muloti4
+
+declare { i128, i1 } @llvm.smul.with.overflow.i128(i128, i128) nounwind readnone
``````````
</details>
https://github.com/llvm/llvm-project/pull/191020
More information about the llvm-commits
mailing list