diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -8944,8 +8944,9 @@ // for now. if (Args[i].IsReturned && !Op.getValueType().isVector() && CanLowerReturn) { - assert(CLI.RetTy == Args[i].Ty && RetTys.size() == NumValues && - "unexpected use of 'returned'"); + assert((CLI.RetTy == Args[i].Ty || + CLI.RetTy->isPointerTy() && Args[i].Ty->isPointerTy()) && + RetTys.size() == NumValues && "unexpected use of 'returned'"); // Before passing 'returned' to the target lowering code, ensure that // either the register MVT and the actual EVT are the same size or that // the return value and argument are extended in the same way; in these diff --git a/llvm/test/CodeGen/Generic/arg_returned_bitcast.ll b/llvm/test/CodeGen/Generic/arg_returned_bitcast.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/Generic/arg_returned_bitcast.ll @@ -0,0 +1,13 @@ +; RUN: llc < %s -asm-verbose=false + +; Test that the "returned" attribute "works" even if there is a bitcast between +; the argument and return value. + +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" + +declare double* @bar(i8* returned) + +define double* @foo(i8*) { + %r = tail call double* @bar(i8* %0) + ret double* %r +}