[llvm] [wasm] Disallow tail calls when passing structs on the stack (PR #124443)

via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 25 20:31:14 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-webassembly

Author: Timothy Herchen (anematode)

<details>
<summary>Changes</summary>

[The following code is incorrectly compiled with `-mtail-call`](https://godbolt.org/z/vd95cYh1E):

```
struct passed_by_value { int a; int b; };
int f(struct passed_by_value val);
int g(struct passed_by_value in) {
    return f(in);
}
```

Output:

```
g:
        global.get      __stack_pointer
        i32.const       16
        i32.sub 
        local.tee       1
        global.set      __stack_pointer
        local.get       1
        local.get       0
        i64.load        0:p2align=2
        i64.store       8
        local.get       1
        i32.const       16
        i32.add 
        global.set      __stack_pointer
        local.get       1
        i32.const       8
        i32.add 
        return_call     f
        end_function
```

Stack space is reserved for the struct arguments, but the stack pointer is moved back before the `return_call`. So I added a check to prevent TCO from happening if we're passing things on the stack.

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


1 Files Affected:

- (modified) llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp (+9) 


``````````diff
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index 02db1b142a22b5..ec745ebabb4f63 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1211,6 +1211,15 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI,
         }
       }
     }
+
+    // If outgoing arguments are passed via the stack, we cannot tail call
+    for (const ISD::OutputArg &Out : CLI.Outs) {
+      if (Out.Flags.isByVal() && Out.Flags.getByValSize() != 0) {
+        NoTail(
+            "WebAssembly does not support tail calling with stack arguments");
+        break;
+      }
+    }
   }
 
   SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;

``````````

</details>


https://github.com/llvm/llvm-project/pull/124443


More information about the llvm-commits mailing list