[SelectionDAG][FIX] Allow "returned" arguments to be bit-casted
authorJohannes Doerfert <jdoerfert@anl.gov>
Tue, 4 Jun 2019 20:34:43 +0000 (20:34 +0000)
committerJohannes Doerfert <jdoerfert@anl.gov>
Tue, 4 Jun 2019 20:34:43 +0000 (20:34 +0000)
Summary:
An argument that is return by a function but bit-casted before can still
be annotated as "returned". Make sure we do not crash for this case.

Reviewers: sunfish, stephenwlin, niravd, arsenm

Subscribers: wdng, hiraditya, bollu, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D59917

llvm-svn: 362546

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/test/CodeGen/X86/arg_returned_bitcast.ll [new file with mode: 0644]

index da06ac7..4f7257d 100644 (file)
@@ -9111,8 +9111,11 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
       // 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() &&
+                 CLI.RetTy->getPointerAddressSpace() ==
+                     Args[i].Ty->getPointerAddressSpace())) &&
+               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/X86/arg_returned_bitcast.ll b/llvm/test/CodeGen/X86/arg_returned_bitcast.ll
new file mode 100644 (file)
index 0000000..2287c12
--- /dev/null
@@ -0,0 +1,12 @@
+; RUN: llc < %s -mtriple=i686-unknown-linux-gnu | FileCheck %s
+
+; Test that the "returned" attribute "works" even if there is a bitcast between
+; the argument and return value.
+
+declare double* @bar(i8* returned)
+
+define double* @foo(i8*) {
+  %r = tail call double* @bar(i8* %0)
+; CHECK: jmp    bar
+  ret double* %r
+}