diff options
author | Reid Kleckner <reid@kleckner.net> | 2014-07-10 01:58:55 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2014-07-10 01:58:55 +0000 |
commit | 677539d0afe90fe8ec6fde19d156c1e2b0d4046a (patch) | |
tree | 2dbc5817c7f73f8e8b17fb5d9b2cee1558a169c3 /clang/lib/CodeGen/TargetInfo.cpp | |
parent | 2e28edf8e1bde1c3d1971758ed9cc3730bf1d61e (diff) | |
download | bcm5719-llvm-677539d0afe90fe8ec6fde19d156c1e2b0d4046a.tar.gz bcm5719-llvm-677539d0afe90fe8ec6fde19d156c1e2b0d4046a.zip |
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.
llvm-svn: 212669
Diffstat (limited to 'clang/lib/CodeGen/TargetInfo.cpp')
-rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 44e001ceb6d..be2d5b38c61 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -957,8 +957,16 @@ void X86_32ABIInfo::computeInfo(CGFunctionInfo &FI) const { 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()) { |