diff options
author | Dan Gohman <dan433584@gmail.com> | 2018-01-30 00:14:40 +0000 |
---|---|---|
committer | Dan Gohman <dan433584@gmail.com> | 2018-01-30 00:14:40 +0000 |
commit | 832092ca12725ae2261be793adf44b077eb47a2a (patch) | |
tree | 6924570ea1130bf442b8a47c43071f03e8fbf34d | |
parent | fbc56a904fe878817008ac071b27a32eec2aa7e3 (diff) | |
download | bcm5719-llvm-832092ca12725ae2261be793adf44b077eb47a2a.tar.gz bcm5719-llvm-832092ca12725ae2261be793adf44b077eb47a2a.zip |
[SelectionDAG]: Ignore "returned" in the presence of an implicit sret.
When a function return value can't be directly lowered, such as
returning an i128 on WebAssembly, as indicated by the CanLowerReturn
target hook, SelectionDAGBuilder can translate it to return the
value through a hidden sret-like argument.
If such a function has an argument with the "returned" attribute,
the attribute can't be automatically lowered, because the function
no longer has a normal return value. For now, just discard the
"returned" attribute.
This fixes PR36128.
llvm-svn: 323715
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 6 | ||||
-rw-r--r-- | llvm/test/CodeGen/WebAssembly/i128-returned.ll | 20 |
2 files changed, 24 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 7df9ee87bff..3563c423e4f 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -8241,8 +8241,10 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const { else if (Args[i].IsZExt) ExtendKind = ISD::ZERO_EXTEND; - // Conservatively only handle 'returned' on non-vectors for now - if (Args[i].IsReturned && !Op.getValueType().isVector()) { + // Conservatively only handle 'returned' on non-vectors that can be lowered, + // for now. + if (Args[i].IsReturned && !Op.getValueType().isVector() && + CanLowerReturn) { assert(CLI.RetTy == Args[i].Ty && RetTys.size() == NumValues && "unexpected use of 'returned'"); // Before passing 'returned' to the target lowering code, ensure that diff --git a/llvm/test/CodeGen/WebAssembly/i128-returned.ll b/llvm/test/CodeGen/WebAssembly/i128-returned.ll new file mode 100644 index 00000000000..f6a459d0be3 --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/i128-returned.ll @@ -0,0 +1,20 @@ +; RUN: llc < %s -asm-verbose=false | FileCheck %s + +; Test that the "returned" attribute works with i128 types. +; PR36128 + +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown-wasm" + +declare i128 @bar(i128 returned) + +define i128 @foo(i128) { + %r = tail call i128 @bar(i128 %0) + ret i128 %r +} + +; CHECK-LABEL: foo: +; CHECK-NEXT: .param i32, i64, i64 +; CHECK-NOT: .result + +; CHECK: .functype bar, void, i32, i64, i64 |