aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Frontend/CompilerInvocation.cpp
diff options
context:
space:
mode:
authorJustin Hibbits <jrh29@alumni.cwru.edu>2020-04-21 15:36:08 -0500
committerJustin Hibbits <jrh29@alumni.cwru.edu>2020-04-21 20:17:25 -0500
commit4ca2cad947d09ba0402f5b85d165aa7fcfbd9e3e (patch)
tree86d5e5c680a5eb8d1669b78b519cb75722f94824 /clang/lib/Frontend/CompilerInvocation.cpp
parenta30e7ea88e75568feed020aedae73c52de888835 (diff)
downloadllvm-4ca2cad947d09ba0402f5b85d165aa7fcfbd9e3e.zip
llvm-4ca2cad947d09ba0402f5b85d165aa7fcfbd9e3e.tar.gz
llvm-4ca2cad947d09ba0402f5b85d165aa7fcfbd9e3e.tar.bz2
[PowerPC] Add clang -msvr4-struct-return for 32-bit ELF
Summary: Change the default ABI to be compatible with GCC. For 32-bit ELF targets other than Linux, Clang now returns small structs in registers r3/r4. This affects FreeBSD, NetBSD, OpenBSD. There is no change for 32-bit Linux, where Clang continues to return all structs in memory. Add clang options -maix-struct-return (to return structs in memory) and -msvr4-struct-return (to return structs in registers) to be compatible with gcc. These options are only for PPC32; reject them on PPC64 and other targets. The options are like -fpcc-struct-return and -freg-struct-return for X86_32, and use similar code. To actually return a struct in registers, coerce it to an integer of the same size. LLVM may optimize the code to remove unnecessary accesses to memory, and will return i32 in r3 or i64 in r3:r4. Fixes PR#40736 Patch by George Koehler! Reviewed By: jhibbits, nemanjai Differential Revision: https://reviews.llvm.org/D73290
Diffstat (limited to 'clang/lib/Frontend/CompilerInvocation.cpp')
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp13
1 files changed, 10 insertions, 3 deletions
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index fc93dfa..6a98867 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1297,11 +1297,18 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
}
- if (Arg *A = Args.getLastArg(OPT_fpcc_struct_return, OPT_freg_struct_return)) {
- if (A->getOption().matches(OPT_fpcc_struct_return)) {
+ // X86_32 has -fppc-struct-return and -freg-struct-return.
+ // PPC32 has -maix-struct-return and -msvr4-struct-return.
+ if (Arg *A =
+ Args.getLastArg(OPT_fpcc_struct_return, OPT_freg_struct_return,
+ OPT_maix_struct_return, OPT_msvr4_struct_return)) {
+ const Option &O = A->getOption();
+ if (O.matches(OPT_fpcc_struct_return) ||
+ O.matches(OPT_maix_struct_return)) {
Opts.setStructReturnConvention(CodeGenOptions::SRCK_OnStack);
} else {
- assert(A->getOption().matches(OPT_freg_struct_return));
+ assert(O.matches(OPT_freg_struct_return) ||
+ O.matches(OPT_msvr4_struct_return));
Opts.setStructReturnConvention(CodeGenOptions::SRCK_InRegs);
}
}