<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">On Feb 5, 2015, at 11:08 AM, Reid Kleckner <<a href="mailto:rnk@google.com" class="">rnk@google.com</a>> wrote:<br class=""><div><blockquote type="cite" class=""><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Is it possible for Clang generated IR to hit this? I would prefer if Clang avoided relying on CanLowerReturn. So far as I can tell, it is designed to make large struct return work without attempting to respect the local ABI.</div></div></blockquote><div><br class=""></div>Not as far as I know. Clang adjusts argument and return types to match the target ABI, including adding an explicit “sret” argument. I’m not really the expert here though.</div><div><br class=""></div><div>This is a case that the backend was clearly trying to handle but was incomplete on X86 and not well tested because clang doesn’t run into it.</div><div><br class=""></div><div>Andy</div><div><br class=""><blockquote type="cite" class=""><div class=""><div class="gmail_extra"><br class=""><div class="gmail_quote">On Thu, Feb 5, 2015 at 10:09 AM, Andrew Trick <span dir="ltr" class=""><<a href="mailto:atrick@apple.com" target="_blank" class="">atrick@apple.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: atrick<br class="">
Date: Thu Feb  5 12:09:05 2015<br class="">
New Revision: 228321<br class="">
<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=228321&view=rev" target="_blank" class="">http://llvm.org/viewvc/llvm-project?rev=228321&view=rev</a><br class="">
Log:<br class="">
X86 ABI fix for return values > 24 bytes.<br class="">
<br class="">
The return value's address must be returned in %rax.<br class="">
i.e. the callee needs to copy the sret argument (%rdi)<br class="">
into the return value (%rax).<br class="">
<br class="">
This probably won't manifest as a bug when the caller is LLVM-compiled<br class="">
code. But it is an ABI guarantee and tools expect it.<br class="">
<br class="">
Added:<br class="">
    llvm/trunk/test/CodeGen/X86/sret-implicit.ll<br class="">
Modified:<br class="">
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br class="">
    llvm/trunk/test/CodeGen/X86/vselect.ll<br class="">
<br class="">
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=228321&r1=228320&r2=228321&view=diff" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=228321&r1=228320&r2=228321&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)<br class="">
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Feb  5 12:09:05 2015<br class="">
@@ -2107,14 +2107,15 @@ X86TargetLowering::LowerReturn(SDValue C<br class="">
   // Win32 requires us to put the sret argument to %eax as well.<br class="">
   // We saved the argument into a virtual register in the entry block,<br class="">
   // so now we copy the value out and into %rax/%eax.<br class="">
-  if (DAG.getMachineFunction().getFunction()->hasStructRetAttr() &&<br class="">
-      (Subtarget->is64Bit() || Subtarget->isTargetKnownWindowsMSVC())) {<br class="">
-    MachineFunction &MF = DAG.getMachineFunction();<br class="">
-    X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();<br class="">
-    unsigned Reg = FuncInfo->getSRetReturnReg();<br class="">
-    assert(Reg &&<br class="">
-           "SRetReturnReg should have been set in LowerFormalArguments().");<br class="">
-    SDValue Val = DAG.getCopyFromReg(Chain, dl, Reg, getPointerTy());<br class="">
+  //<br class="">
+  // Checking Function.hasStructRetAttr() here is insufficient because the IR<br class="">
+  // may not have an explicit sret argument. If FuncInfo.CanLowerReturn is<br class="">
+  // false, then an sret argument may be implicitly inserted in the SelDAG. In<br class="">
+  // either case FuncInfo->setSRetReturnReg() will have been called.<br class="">
+  if (unsigned SRetReg = FuncInfo->getSRetReturnReg()) {<br class="">
+    assert((Subtarget->is64Bit() || Subtarget->isTargetKnownWindowsMSVC()) &&<br class="">
+           "No need for an sret register");<br class="">
+    SDValue Val = DAG.getCopyFromReg(Chain, dl, SRetReg, getPointerTy());<br class="">
<br class="">
     unsigned RetValReg<br class="">
         = (Subtarget->is64Bit() && !Subtarget->isTarget64BitILP32()) ?<br class="">
<br class="">
Added: llvm/trunk/test/CodeGen/X86/sret-implicit.ll<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sret-implicit.ll?rev=228321&view=auto" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sret-implicit.ll?rev=228321&view=auto</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/test/CodeGen/X86/sret-implicit.ll (added)<br class="">
+++ llvm/trunk/test/CodeGen/X86/sret-implicit.ll Thu Feb  5 12:09:05 2015<br class="">
@@ -0,0 +1,10 @@<br class="">
+; RUN: llc -mtriple=x86_64-apple-darwin8 < %s | FileCheck %s<br class="">
+; RUN: llc -mtriple=x86_64-pc-linux < %s | FileCheck %s<br class="">
+<br class="">
+; CHECK-LABEL: return32<br class="">
+; CHECK-DAG: movq      $0, (%rdi)<br class="">
+; CHECK-DAG: movq      %rdi, %rax<br class="">
+; CHECK: retq<br class="">
+define i256 @return32() {<br class="">
+  ret i256 0<br class="">
+}<br class="">
<br class="">
Modified: llvm/trunk/test/CodeGen/X86/vselect.ll<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vselect.ll?rev=228321&r1=228320&r2=228321&view=diff" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vselect.ll?rev=228321&r1=228320&r2=228321&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/test/CodeGen/X86/vselect.ll (original)<br class="">
+++ llvm/trunk/test/CodeGen/X86/vselect.ll Thu Feb  5 12:09:05 2015<br class="">
@@ -275,6 +275,7 @@ define <16 x double> @select_illegal(<16<br class="">
 ; CHECK-NEXT:    movaps %xmm2, 32(%rdi)<br class="">
 ; CHECK-NEXT:    movaps %xmm1, 16(%rdi)<br class="">
 ; CHECK-NEXT:    movaps %xmm0, (%rdi)<br class="">
+; CHECK-NEXT:    movq %rdi, %rax<br class="">
 ; CHECK-NEXT:    retq<br class="">
   %sel = select <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <16 x double> %a, <16 x double> %b<br class="">
   ret <16 x double> %sel<br class="">
<br class="">
<br class="">
_______________________________________________<br class="">
llvm-commits mailing list<br class="">
<a href="mailto:llvm-commits@cs.uiuc.edu" class="">llvm-commits@cs.uiuc.edu</a><br class="">
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank" class="">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br class="">
</blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></body></html>