r212669 - MS ABI: Fix __fastcall methods that return structs
    Reid Kleckner 
    reid at kleckner.net
       
    Wed Jul  9 18:58:55 PDT 2014
    
    
  
Author: rnk
Date: Wed Jul  9 20:58:55 2014
New Revision: 212669
URL: http://llvm.org/viewvc/llvm-project?rev=212669&view=rev
Log:
MS ABI: Fix __fastcall methods that return structs
The sret paramater consumes the register after the implicit 'this'
parameter, as with other calling conventions.
Fixes PR20278, which turned out to be very easy.
Modified:
    cfe/trunk/lib/CodeGen/TargetInfo.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp
Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=212669&r1=212668&r2=212669&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Wed Jul  9 20:58:55 2014
@@ -957,8 +957,16 @@ void X86_32ABIInfo::computeInfo(CGFuncti
   else
     State.FreeRegs = DefaultNumRegisterParameters;
 
-  if (!getCXXABI().classifyReturnType(FI))
+  if (!getCXXABI().classifyReturnType(FI)) {
     FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), State);
+  } else if (FI.getReturnInfo().isIndirect()) {
+    // The C++ ABI is not aware of register usage, so we have to check if the
+    // return value was sret and put it in a register ourselves if appropriate.
+    if (State.FreeRegs) {
+      --State.FreeRegs;  // The sret parameter consumes a register.
+      FI.getReturnInfo().setInReg(true);
+    }
+  }
 
   bool UsedInAlloca = false;
   for (auto &I : FI.arguments()) {
Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp?rev=212669&r1=212668&r2=212669&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp Wed Jul  9 20:58:55 2014
@@ -33,3 +33,12 @@ int main() {
 // CHECK: call void {{.*}} @"\01?variadic_sret at C@@QAA?AUS@@PBDZZ"
 // CHECK: call void @"\01?cdecl_sret at C@@QAA?AUS@@XZ"
 // CHECK: call void @"\01?byval_and_sret at C@@QAA?AUS@@U2@@Z"
+
+// __fastcall has similar issues.
+struct A {
+  S __fastcall f(int x);
+};
+S A::f(int x) {
+  return S();
+}
+// CHECK-LABEL: define x86_fastcallcc void @"\01?f at A@@QAI?AUS@@H at Z"(%struct.A* inreg %this, %struct.S* inreg noalias sret %agg.result, i32 %x)
    
    
More information about the cfe-commits
mailing list