macppc base-clang -msvr4-struct-return

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

macppc base-clang -msvr4-struct-return

George Koehler-2
Hello tech list,

This is a diff for base-clang.  It would change the powerpc target to
return small structs in registers r3 and r4.  This would fix an
incompatibility with gcc in OpenBSD macppc.  I fear that if I commit
the diff, I might break snapshot builds.  I am looking for help.

I posted the diff upstream: https://reviews.llvm.org/D73290
Then backported it to ports-clang and mailed it to ports@:
        https://marc.info/?l=openbsd-ports&m=158026852003182&w=2
This is the same diff for base-clang.

Apply diff in /usr/src/gnu/llvm, then build clang like

# cd /usr/src/gnu/usr.bin/clang
# make obj
# make
# make install

My macppc machine, an iMac G3 with 512M RAM, is too slow to build llvm
and clang.  The iMac is now in the 11th day of building ports-clang
(but I turned it off overnight), and within the last 200 of over 4400
targets.  After a .cpp file got stuck while using over 800M swap (on
hard disk), I set vm.swapencrypt.enable=0 and switched to swap on NFS.
(For contrast, my amd64 desktop built ports-clang in about 2 hours.)

cwen@ built ports-clang with my diff on a G4 in "29 hours".
rgc <[hidden email]> built base-clang with the diff in this mail.
Both got good results from my small test programs in the attachment
(sret-examples.tar.gz) to my ports@ mail.

The diff affects all platforms (if they build clang), so if the diff
would break clang, it might break arches other than macppc.  I built
and installed base-clang with this diff on amd64 (using make -j4 to
speed up the build).  Then, with the patched clang, I built an amd64
release(8) of base and xenocara.  I used my new install66.iso
to install a new amd64 virtual machine, including the patched clang.

We build most of OpenBSD macppc with base-gcc, but we use base-clang
for at least clang itself.  I don't know whether the patched
base-clang can still build base-clang, whether the patch would break
the base build on macppc.

The patch adds -maix-struct-return and -msvr4-struct-return:

$ clang -msvr-struct-return -x c /dev/null
clang: error: unknown argument '-msvr-struct-return', did you mean
'-msvr4-struct-return'?
$ clang -msvr4-struct-return -x c /dev/null
clang: error: unsupported option '-msvr4-struct-return' for target
'amd64-unknown-openbsd6.6'

On OpenBSD macppc, gcc defaults to -msvr4-struct-return (to return
small structs in registers r3 and r4), but clang without the patch
always acts like gcc -maix-struct-return (to return small structs in
memory through a sret pointer).  The patch adds the options and
changes the default to -msvr4-struct-return on OpenBSD (and other
ELF except Linux).  The options work only on 32-bit powerpc.

When the patch returns a struct in registers, it coerces the struct
to an integer; this changes the LLVM IR from clang to not use a sret
pointer.  The option handling for -m{aix,svr4}-struct-return is mostly
a copy of that for -f{pcc,reg}-struct-return on i386.

--George

Index: tools/clang/include/clang/Driver/Options.td
===================================================================
RCS file: /cvs/src/gnu/llvm/tools/clang/include/clang/Driver/Options.td,v
retrieving revision 1.11
diff -u -p -r1.11 Options.td
--- tools/clang/include/clang/Driver/Options.td 23 Jun 2019 22:05:15 -0000 1.11
+++ tools/clang/include/clang/Driver/Options.td 30 Jan 2020 01:13:29 -0000
@@ -2238,6 +2238,12 @@ def mlongcall: Flag<["-"], "mlongcall">,
     Group<m_ppc_Features_Group>;
 def mno_longcall : Flag<["-"], "mno-longcall">,
     Group<m_ppc_Features_Group>;
+def maix_struct_return : Flag<["-"], "maix-struct-return">,
+  Group<m_Group>, Flags<[CC1Option]>,
+  HelpText<"Return all structs in memory (PPC32 only)">;
+def msvr4_struct_return : Flag<["-"], "msvr4-struct-return">,
+  Group<m_Group>, Flags<[CC1Option]>,
+  HelpText<"Return small structs in registers (PPC32 only)">;
 
 def mvx : Flag<["-"], "mvx">, Group<m_Group>;
 def mno_vx : Flag<["-"], "mno-vx">, Group<m_Group>;
Index: tools/clang/lib/CodeGen/TargetInfo.cpp
===================================================================
RCS file: /cvs/src/gnu/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp,v
retrieving revision 1.1.1.7
diff -u -p -r1.1.1.7 TargetInfo.cpp
--- tools/clang/lib/CodeGen/TargetInfo.cpp 23 Jun 2019 21:37:39 -0000 1.1.1.7
+++ tools/clang/lib/CodeGen/TargetInfo.cpp 30 Jan 2020 01:13:30 -0000
@@ -4092,12 +4092,24 @@ namespace {
 /// PPC32_SVR4_ABIInfo - The 32-bit PowerPC ELF (SVR4) ABI information.
 class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
   bool IsSoftFloatABI;
+  bool IsRetSmallStructInRegABI;
 
   CharUnits getParamTypeAlignment(QualType Ty) const;
 
 public:
-  PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, bool SoftFloatABI)
-      : DefaultABIInfo(CGT), IsSoftFloatABI(SoftFloatABI) {}
+  PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, bool SoftFloatABI,
+                     bool RetSmallStructInRegABI)
+      : DefaultABIInfo(CGT), IsSoftFloatABI(SoftFloatABI),
+        IsRetSmallStructInRegABI(RetSmallStructInRegABI) {}
+
+  ABIArgInfo classifyReturnType(QualType RetTy) const;
+
+  void computeInfo(CGFunctionInfo &FI) const override {
+    if (!getCXXABI().classifyReturnType(FI))
+      FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+    for (auto &I : FI.arguments())
+      I.info = classifyArgumentType(I.type);
+  }
 
   Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
                     QualType Ty) const override;
@@ -4105,8 +4117,13 @@ public:
 
 class PPC32TargetCodeGenInfo : public TargetCodeGenInfo {
 public:
-  PPC32TargetCodeGenInfo(CodeGenTypes &CGT, bool SoftFloatABI)
-      : TargetCodeGenInfo(new PPC32_SVR4_ABIInfo(CGT, SoftFloatABI)) {}
+  PPC32TargetCodeGenInfo(CodeGenTypes &CGT, bool SoftFloatABI,
+                         bool RetSmallStructInRegABI)
+      : TargetCodeGenInfo(new PPC32_SVR4_ABIInfo(CGT, SoftFloatABI,
+                                                 RetSmallStructInRegABI)) {}
+
+  static bool isStructReturnInRegABI(const llvm::Triple &Triple,
+                                     const CodeGenOptions &Opts);
 
   int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
     // This is recovered from gcc output.
@@ -4142,6 +4159,34 @@ CharUnits PPC32_SVR4_ABIInfo::getParamTy
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const {
+  uint64_t Size;
+
+  // -msvr4-struct-return puts small aggregates in GPR3 and GPR4.
+  if (isAggregateTypeForABI(RetTy) && IsRetSmallStructInRegABI &&
+      (Size = getContext().getTypeSize(RetTy)) <= 64) {
+    // System V ABI (1995), page 3-22, specified:
+    // > A structure or union whose size is less than or equal to 8 bytes
+    // > shall be returned in r3 and r4, as if it were first stored in the
+    // > 8-byte aligned memory area and then the low addressed word were
+    // > loaded into r3 and the high-addressed word into r4.  Bits beyond
+    // > the last member of the structure or union are not defined.
+    //
+    // GCC for big-endian PPC32 inserts the pad before the first member,
+    // not "beyond the last member" of the struct.  To stay compatible
+    // with GCC, we coerce the struct to an integer of the same size.
+    // LLVM will extend it and return i32 in r3, or i64 in r3:r4.
+    if (Size == 0)
+      return ABIArgInfo::getIgnore();
+    else {
+      llvm::Type *CoerceTy = llvm::Type::getIntNTy(getVMContext(), Size);
+      return ABIArgInfo::getDirect(CoerceTy);
+    }
+  }
+
+  return DefaultABIInfo::classifyReturnType(RetTy);
+}
+
 // TODO: this implementation is now likely redundant with
 // DefaultABIInfo::EmitVAArg.
 Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
@@ -4299,6 +4344,25 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(Co
   return Result;
 }
 
+bool PPC32TargetCodeGenInfo::isStructReturnInRegABI(
+    const llvm::Triple &Triple, const CodeGenOptions &Opts) {
+  assert(Triple.getArch() == llvm::Triple::ppc);
+
+  switch (Opts.getStructReturnConvention()) {
+  case CodeGenOptions::SRCK_Default:
+    break;
+  case CodeGenOptions::SRCK_OnStack: // -maix-struct-return
+    return false;
+  case CodeGenOptions::SRCK_InRegs: // -msvr4-struct-return
+    return true;
+  }
+
+  if (Triple.isOSBinFormatELF() && !Triple.isOSLinux())
+    return true;
+
+  return false;
+}
+
 bool
 PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
                                                 llvm::Value *Address) const {
@@ -9330,9 +9394,13 @@ const TargetCodeGenInfo &CodeGenModule::
     return SetCGInfo(new ARMTargetCodeGenInfo(Types, Kind));
   }
 
-  case llvm::Triple::ppc:
+  case llvm::Triple::ppc: {
+    bool RetSmallStructInRegABI =
+        PPC32TargetCodeGenInfo::isStructReturnInRegABI(Triple, CodeGenOpts);
     return SetCGInfo(
-        new PPC32TargetCodeGenInfo(Types, CodeGenOpts.FloatABI == "soft"));
+        new PPC32TargetCodeGenInfo(Types, CodeGenOpts.FloatABI == "soft",
+                                   RetSmallStructInRegABI));
+  }
   case llvm::Triple::ppc64:
     if (Triple.isOSBinFormatELF()) {
       PPC64_SVR4_ABIInfo::ABIKind Kind = PPC64_SVR4_ABIInfo::ELFv1;
Index: tools/clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
RCS file: /cvs/src/gnu/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp,v
retrieving revision 1.20
diff -u -p -r1.20 Clang.cpp
--- tools/clang/lib/Driver/ToolChains/Clang.cpp 25 Oct 2019 00:40:56 -0000 1.20
+++ tools/clang/lib/Driver/ToolChains/Clang.cpp 30 Jan 2020 01:13:30 -0000
@@ -3870,6 +3870,19 @@ void Clang::ConstructJob(Compilation &C,
     CmdArgs.push_back(A->getValue());
   }
 
+  if (Arg *A = Args.getLastArg(options::OPT_maix_struct_return,
+                               options::OPT_msvr4_struct_return)) {
+    if (TC.getArch() != llvm::Triple::ppc) {
+      D.Diag(diag::err_drv_unsupported_opt_for_target)
+          << A->getSpelling() << RawTriple.str();
+    } else if (A->getOption().matches(options::OPT_maix_struct_return)) {
+      CmdArgs.push_back("-maix-struct-return");
+    } else {
+      assert(A->getOption().matches(options::OPT_msvr4_struct_return));
+      CmdArgs.push_back("-msvr4-struct-return");
+    }
+  }
+
   if (Arg *A = Args.getLastArg(options::OPT_fpcc_struct_return,
                                options::OPT_freg_struct_return)) {
     if (TC.getArch() != llvm::Triple::x86) {
Index: tools/clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
RCS file: /cvs/src/gnu/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp,v
retrieving revision 1.4
diff -u -p -r1.4 CompilerInvocation.cpp
--- tools/clang/lib/Frontend/CompilerInvocation.cpp 23 Jun 2019 22:05:15 -0000 1.4
+++ tools/clang/lib/Frontend/CompilerInvocation.cpp 30 Jan 2020 01:13:30 -0000
@@ -1199,11 +1199,18 @@ static bool ParseCodeGenArgs(CodeGenOpti
       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);
     }
   }

Reply | Threaded
Open this post in threaded view
|

Re: macppc base-clang -msvr4-struct-return

Todd Mortimer
Hi George,

On Tue, Feb 04, 2020 at 08:39:12PM -0500, George Koehler wrote:
> Hello tech list,
>
> This is a diff for base-clang.  It would change the powerpc target to
> return small structs in registers r3 and r4.  This would fix an
> incompatibility with gcc in OpenBSD macppc.  I fear that if I commit
> the diff, I might break snapshot builds.  I am looking for help.

The diff looks sane to me. I don't see anything that would obviously
break snaps, and the option is limited to only the ppc platform.

I am running it through a release build here (amd64) and will know how
that turned out tomorrow after work, so will be able to confirm that you
won't break snaps on that arch. I don't expect there to be any problem
there. I should be able to test it on macppc over the weekend, so if
you're paranoid you can wait to see how that goes.

Cheers,
Todd



>
> I posted the diff upstream: https://reviews.llvm.org/D73290
> Then backported it to ports-clang and mailed it to ports@:
> https://marc.info/?l=openbsd-ports&m=158026852003182&w=2
> This is the same diff for base-clang.
>
> Apply diff in /usr/src/gnu/llvm, then build clang like
>
> # cd /usr/src/gnu/usr.bin/clang
> # make obj
> # make
> # make install
>
> My macppc machine, an iMac G3 with 512M RAM, is too slow to build llvm
> and clang.  The iMac is now in the 11th day of building ports-clang
> (but I turned it off overnight), and within the last 200 of over 4400
> targets.  After a .cpp file got stuck while using over 800M swap (on
> hard disk), I set vm.swapencrypt.enable=0 and switched to swap on NFS.
> (For contrast, my amd64 desktop built ports-clang in about 2 hours.)
>
> cwen@ built ports-clang with my diff on a G4 in "29 hours".
> rgc <[hidden email]> built base-clang with the diff in this mail.
> Both got good results from my small test programs in the attachment
> (sret-examples.tar.gz) to my ports@ mail.
>
> The diff affects all platforms (if they build clang), so if the diff
> would break clang, it might break arches other than macppc.  I built
> and installed base-clang with this diff on amd64 (using make -j4 to
> speed up the build).  Then, with the patched clang, I built an amd64
> release(8) of base and xenocara.  I used my new install66.iso
> to install a new amd64 virtual machine, including the patched clang.
>
> We build most of OpenBSD macppc with base-gcc, but we use base-clang
> for at least clang itself.  I don't know whether the patched
> base-clang can still build base-clang, whether the patch would break
> the base build on macppc.
>
> The patch adds -maix-struct-return and -msvr4-struct-return:
>
> $ clang -msvr-struct-return -x c /dev/null
> clang: error: unknown argument '-msvr-struct-return', did you mean
> '-msvr4-struct-return'?
> $ clang -msvr4-struct-return -x c /dev/null
> clang: error: unsupported option '-msvr4-struct-return' for target
> 'amd64-unknown-openbsd6.6'
>
> On OpenBSD macppc, gcc defaults to -msvr4-struct-return (to return
> small structs in registers r3 and r4), but clang without the patch
> always acts like gcc -maix-struct-return (to return small structs in
> memory through a sret pointer).  The patch adds the options and
> changes the default to -msvr4-struct-return on OpenBSD (and other
> ELF except Linux).  The options work only on 32-bit powerpc.
>
> When the patch returns a struct in registers, it coerces the struct
> to an integer; this changes the LLVM IR from clang to not use a sret
> pointer.  The option handling for -m{aix,svr4}-struct-return is mostly
> a copy of that for -f{pcc,reg}-struct-return on i386.
>
> --George
>
> Index: tools/clang/include/clang/Driver/Options.td
> ===================================================================
> RCS file: /cvs/src/gnu/llvm/tools/clang/include/clang/Driver/Options.td,v
> retrieving revision 1.11
> diff -u -p -r1.11 Options.td
> --- tools/clang/include/clang/Driver/Options.td 23 Jun 2019 22:05:15 -0000 1.11
> +++ tools/clang/include/clang/Driver/Options.td 30 Jan 2020 01:13:29 -0000
> @@ -2238,6 +2238,12 @@ def mlongcall: Flag<["-"], "mlongcall">,
>      Group<m_ppc_Features_Group>;
>  def mno_longcall : Flag<["-"], "mno-longcall">,
>      Group<m_ppc_Features_Group>;
> +def maix_struct_return : Flag<["-"], "maix-struct-return">,
> +  Group<m_Group>, Flags<[CC1Option]>,
> +  HelpText<"Return all structs in memory (PPC32 only)">;
> +def msvr4_struct_return : Flag<["-"], "msvr4-struct-return">,
> +  Group<m_Group>, Flags<[CC1Option]>,
> +  HelpText<"Return small structs in registers (PPC32 only)">;
>  
>  def mvx : Flag<["-"], "mvx">, Group<m_Group>;
>  def mno_vx : Flag<["-"], "mno-vx">, Group<m_Group>;
> Index: tools/clang/lib/CodeGen/TargetInfo.cpp
> ===================================================================
> RCS file: /cvs/src/gnu/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp,v
> retrieving revision 1.1.1.7
> diff -u -p -r1.1.1.7 TargetInfo.cpp
> --- tools/clang/lib/CodeGen/TargetInfo.cpp 23 Jun 2019 21:37:39 -0000 1.1.1.7
> +++ tools/clang/lib/CodeGen/TargetInfo.cpp 30 Jan 2020 01:13:30 -0000
> @@ -4092,12 +4092,24 @@ namespace {
>  /// PPC32_SVR4_ABIInfo - The 32-bit PowerPC ELF (SVR4) ABI information.
>  class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
>    bool IsSoftFloatABI;
> +  bool IsRetSmallStructInRegABI;
>  
>    CharUnits getParamTypeAlignment(QualType Ty) const;
>  
>  public:
> -  PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, bool SoftFloatABI)
> -      : DefaultABIInfo(CGT), IsSoftFloatABI(SoftFloatABI) {}
> +  PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, bool SoftFloatABI,
> +                     bool RetSmallStructInRegABI)
> +      : DefaultABIInfo(CGT), IsSoftFloatABI(SoftFloatABI),
> +        IsRetSmallStructInRegABI(RetSmallStructInRegABI) {}
> +
> +  ABIArgInfo classifyReturnType(QualType RetTy) const;
> +
> +  void computeInfo(CGFunctionInfo &FI) const override {
> +    if (!getCXXABI().classifyReturnType(FI))
> +      FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
> +    for (auto &I : FI.arguments())
> +      I.info = classifyArgumentType(I.type);
> +  }
>  
>    Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
>                      QualType Ty) const override;
> @@ -4105,8 +4117,13 @@ public:
>  
>  class PPC32TargetCodeGenInfo : public TargetCodeGenInfo {
>  public:
> -  PPC32TargetCodeGenInfo(CodeGenTypes &CGT, bool SoftFloatABI)
> -      : TargetCodeGenInfo(new PPC32_SVR4_ABIInfo(CGT, SoftFloatABI)) {}
> +  PPC32TargetCodeGenInfo(CodeGenTypes &CGT, bool SoftFloatABI,
> +                         bool RetSmallStructInRegABI)
> +      : TargetCodeGenInfo(new PPC32_SVR4_ABIInfo(CGT, SoftFloatABI,
> +                                                 RetSmallStructInRegABI)) {}
> +
> +  static bool isStructReturnInRegABI(const llvm::Triple &Triple,
> +                                     const CodeGenOptions &Opts);
>  
>    int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
>      // This is recovered from gcc output.
> @@ -4142,6 +4159,34 @@ CharUnits PPC32_SVR4_ABIInfo::getParamTy
>    return CharUnits::fromQuantity(4);
>  }
>  
> +ABIArgInfo PPC32_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const {
> +  uint64_t Size;
> +
> +  // -msvr4-struct-return puts small aggregates in GPR3 and GPR4.
> +  if (isAggregateTypeForABI(RetTy) && IsRetSmallStructInRegABI &&
> +      (Size = getContext().getTypeSize(RetTy)) <= 64) {
> +    // System V ABI (1995), page 3-22, specified:
> +    // > A structure or union whose size is less than or equal to 8 bytes
> +    // > shall be returned in r3 and r4, as if it were first stored in the
> +    // > 8-byte aligned memory area and then the low addressed word were
> +    // > loaded into r3 and the high-addressed word into r4.  Bits beyond
> +    // > the last member of the structure or union are not defined.
> +    //
> +    // GCC for big-endian PPC32 inserts the pad before the first member,
> +    // not "beyond the last member" of the struct.  To stay compatible
> +    // with GCC, we coerce the struct to an integer of the same size.
> +    // LLVM will extend it and return i32 in r3, or i64 in r3:r4.
> +    if (Size == 0)
> +      return ABIArgInfo::getIgnore();
> +    else {
> +      llvm::Type *CoerceTy = llvm::Type::getIntNTy(getVMContext(), Size);
> +      return ABIArgInfo::getDirect(CoerceTy);
> +    }
> +  }
> +
> +  return DefaultABIInfo::classifyReturnType(RetTy);
> +}
> +
>  // TODO: this implementation is now likely redundant with
>  // DefaultABIInfo::EmitVAArg.
>  Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
> @@ -4299,6 +4344,25 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(Co
>    return Result;
>  }
>  
> +bool PPC32TargetCodeGenInfo::isStructReturnInRegABI(
> +    const llvm::Triple &Triple, const CodeGenOptions &Opts) {
> +  assert(Triple.getArch() == llvm::Triple::ppc);
> +
> +  switch (Opts.getStructReturnConvention()) {
> +  case CodeGenOptions::SRCK_Default:
> +    break;
> +  case CodeGenOptions::SRCK_OnStack: // -maix-struct-return
> +    return false;
> +  case CodeGenOptions::SRCK_InRegs: // -msvr4-struct-return
> +    return true;
> +  }
> +
> +  if (Triple.isOSBinFormatELF() && !Triple.isOSLinux())
> +    return true;
> +
> +  return false;
> +}
> +
>  bool
>  PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
>                                                  llvm::Value *Address) const {
> @@ -9330,9 +9394,13 @@ const TargetCodeGenInfo &CodeGenModule::
>      return SetCGInfo(new ARMTargetCodeGenInfo(Types, Kind));
>    }
>  
> -  case llvm::Triple::ppc:
> +  case llvm::Triple::ppc: {
> +    bool RetSmallStructInRegABI =
> +        PPC32TargetCodeGenInfo::isStructReturnInRegABI(Triple, CodeGenOpts);
>      return SetCGInfo(
> -        new PPC32TargetCodeGenInfo(Types, CodeGenOpts.FloatABI == "soft"));
> +        new PPC32TargetCodeGenInfo(Types, CodeGenOpts.FloatABI == "soft",
> +                                   RetSmallStructInRegABI));
> +  }
>    case llvm::Triple::ppc64:
>      if (Triple.isOSBinFormatELF()) {
>        PPC64_SVR4_ABIInfo::ABIKind Kind = PPC64_SVR4_ABIInfo::ELFv1;
> Index: tools/clang/lib/Driver/ToolChains/Clang.cpp
> ===================================================================
> RCS file: /cvs/src/gnu/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp,v
> retrieving revision 1.20
> diff -u -p -r1.20 Clang.cpp
> --- tools/clang/lib/Driver/ToolChains/Clang.cpp 25 Oct 2019 00:40:56 -0000 1.20
> +++ tools/clang/lib/Driver/ToolChains/Clang.cpp 30 Jan 2020 01:13:30 -0000
> @@ -3870,6 +3870,19 @@ void Clang::ConstructJob(Compilation &C,
>      CmdArgs.push_back(A->getValue());
>    }
>  
> +  if (Arg *A = Args.getLastArg(options::OPT_maix_struct_return,
> +                               options::OPT_msvr4_struct_return)) {
> +    if (TC.getArch() != llvm::Triple::ppc) {
> +      D.Diag(diag::err_drv_unsupported_opt_for_target)
> +          << A->getSpelling() << RawTriple.str();
> +    } else if (A->getOption().matches(options::OPT_maix_struct_return)) {
> +      CmdArgs.push_back("-maix-struct-return");
> +    } else {
> +      assert(A->getOption().matches(options::OPT_msvr4_struct_return));
> +      CmdArgs.push_back("-msvr4-struct-return");
> +    }
> +  }
> +
>    if (Arg *A = Args.getLastArg(options::OPT_fpcc_struct_return,
>                                 options::OPT_freg_struct_return)) {
>      if (TC.getArch() != llvm::Triple::x86) {
> Index: tools/clang/lib/Frontend/CompilerInvocation.cpp
> ===================================================================
> RCS file: /cvs/src/gnu/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp,v
> retrieving revision 1.4
> diff -u -p -r1.4 CompilerInvocation.cpp
> --- tools/clang/lib/Frontend/CompilerInvocation.cpp 23 Jun 2019 22:05:15 -0000 1.4
> +++ tools/clang/lib/Frontend/CompilerInvocation.cpp 30 Jan 2020 01:13:30 -0000
> @@ -1199,11 +1199,18 @@ static bool ParseCodeGenArgs(CodeGenOpti
>        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);
>      }
>    }
>

Reply | Threaded
Open this post in threaded view
|

Re: macppc base-clang -msvr4-struct-return

Jeremie Courreges-Anglas-2
On Wed, Feb 05 2020, Todd Mortimer <[hidden email]> wrote:

> Hi George,
>
> On Tue, Feb 04, 2020 at 08:39:12PM -0500, George Koehler wrote:
>> Hello tech list,
>>
>> This is a diff for base-clang.  It would change the powerpc target to
>> return small structs in registers r3 and r4.  This would fix an
>> incompatibility with gcc in OpenBSD macppc.  I fear that if I commit
>> the diff, I might break snapshot builds.  I am looking for help.
>
> The diff looks sane to me. I don't see anything that would obviously
> break snaps, and the option is limited to only the ppc platform.
>
> I am running it through a release build here (amd64) and will know how
> that turned out tomorrow after work, so will be able to confirm that you
> won't break snaps on that arch. I don't expect there to be any problem
> there. I should be able to test it on macppc over the weekend, so if
> you're paranoid you can wait to see how that goes.

fwiw I'm already ok with the diff George sent for ports/devel/llvm.
I'm mostly ok with this one but it would be nice to know whether
base-clang can rebuild itself.  :)

--
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply | Threaded
Open this post in threaded view
|

Re: macppc base-clang -msvr4-struct-return

George Koehler-2
On Tue, 11 Feb 2020 15:20:00 +0100
Jeremie Courreges-Anglas <[hidden email]> wrote:

> fwiw I'm already ok with the diff George sent for ports/devel/llvm.
> I'm mostly ok with this one but it would be nice to know whether
> base-clang can rebuild itself.  :)

base-clang can't rebuild itself in the normal way.  I have been
exchanging mails with Todd Mortimer, who has been testing my diff with
a faster macppc machine.  The diff changes the ABI between
/usr/bin/clang and /usr/lib/libc++.so.3.0, so when we install a new
libc++ built by clang -msvr4-struct-return, but still have a clang
built as if by -maix-struct-return, then clang crashes and can't
rebuild itself!  It might be possible to use a static-link clang to
cross the ABI change.

A backtrace from clang pointed to a function in libc++ that returns a
std::string::iterator, a small struct where sizeof(iterator) == 4.

This was not a problem with ports-clang, because we use ports-gcc to
build ports-clang; and ports-clang uses libestdc++ (from ports-gcc),
not libc++ (from base).  Both ports-clang and libestdc++ got built by
gcc -msvr4-struct-return.  --George

Reply | Threaded
Open this post in threaded view
|

Re: macppc base-clang -msvr4-struct-return

Jeremie Courreges-Anglas-2
On Tue, Feb 11 2020, George Koehler <[hidden email]> wrote:

> On Tue, 11 Feb 2020 15:20:00 +0100
> Jeremie Courreges-Anglas <[hidden email]> wrote:
>
>> fwiw I'm already ok with the diff George sent for ports/devel/llvm.
>> I'm mostly ok with this one but it would be nice to know whether
>> base-clang can rebuild itself.  :)
>
> base-clang can't rebuild itself in the normal way.  I have been
> exchanging mails with Todd Mortimer, who has been testing my diff with
> a faster macppc machine.  The diff changes the ABI between
> /usr/bin/clang and /usr/lib/libc++.so.3.0, so when we install a new
> libc++ built by clang -msvr4-struct-return, but still have a clang
> built as if by -maix-struct-return, then clang crashes and can't
> rebuild itself!  It might be possible to use a static-link clang to
> cross the ABI change.
>
> A backtrace from clang pointed to a function in libc++ that returns a
> std::string::iterator, a small struct where sizeof(iterator) == 4.

So the steps would be:
- build and install a new clang
- bump the major of libc++, build and install it
- rebuild and reinstall clang
- build new snap

Assuming those steps are correct, you could ask Theo to handle the ABI
break.  A note in current.html could be useful too.

> This was not a problem with ports-clang, because we use ports-gcc to
> build ports-clang; and ports-clang uses libestdc++ (from ports-gcc),
> not libc++ (from base).  Both ports-clang and libestdc++ got built by
> gcc -msvr4-struct-return.  --George

Yep.

--
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply | Threaded
Open this post in threaded view
|

Re: macppc base-clang -msvr4-struct-return

Theo de Raadt-2
Jeremie Courreges-Anglas <[hidden email]> wrote:

> On Tue, Feb 11 2020, George Koehler <[hidden email]> wrote:
> > On Tue, 11 Feb 2020 15:20:00 +0100
> > Jeremie Courreges-Anglas <[hidden email]> wrote:
> >
> >> fwiw I'm already ok with the diff George sent for ports/devel/llvm.
> >> I'm mostly ok with this one but it would be nice to know whether
> >> base-clang can rebuild itself.  :)
> >
> > base-clang can't rebuild itself in the normal way.  I have been
> > exchanging mails with Todd Mortimer, who has been testing my diff with
> > a faster macppc machine.  The diff changes the ABI between
> > /usr/bin/clang and /usr/lib/libc++.so.3.0, so when we install a new
> > libc++ built by clang -msvr4-struct-return, but still have a clang
> > built as if by -maix-struct-return, then clang crashes and can't
> > rebuild itself!  It might be possible to use a static-link clang to
> > cross the ABI change.
> >
> > A backtrace from clang pointed to a function in libc++ that returns a
> > std::string::iterator, a small struct where sizeof(iterator) == 4.
>
> So the steps would be:
> - build and install a new clang
> - bump the major of libc++, build and install it
> - rebuild and reinstall clang
> - build new snap
>
> Assuming those steps are correct, you could ask Theo to handle the ABI
> break.  A note in current.html could be useful too.

Sure, commit it then I'll follow.

Reply | Threaded
Open this post in threaded view
|

Re: macppc base-clang -msvr4-struct-return

George Koehler-2
In reply to this post by Jeremie Courreges-Anglas-2
On Tue, 11 Feb 2020 18:58:48 +0100
Jeremie Courreges-Anglas <[hidden email]> wrote:

> So the steps would be:
> - build and install a new clang
> - bump the major of libc++, build and install it
> - rebuild and reinstall clang
> - build new snap

You are the first person to suggest bumping .so majors; I didn't think
to do so.  If libc++ needs a major bump, then libc++abi and libLLVM
might also need them.  These 3 are the only .so (that I can find)
built by base-clang on powerpc.

Across base + xenocara + ports, almost nothing uses these 3 .so on
powerpc.  The only users that I find are
 - /usr/bin/clang* using libc++.so.3.0 and libc++abi.so.1.0
 - nothing using libLLVM.so.1.0

(xenocara/lib/mesa uses libLLVM only for i386 amd64 arm64.  I looked
for ports with LLVM in WANTLIB, found only devel/py-llvmlite, but it
requires base-clang, and ports doesn't use base-clang for powerpc.)

If we don't bump majors, then people who upgrade OpenBSD macppc would
get the new libc++.so.3.0 and libc++abi.so.1.0 at the same time as the
new clang; and people on other platforms won't see an unnecessary
major bump.

If we do bump majors, then people who had used /usr/bin/clang++ on
OpenBSD macppc might be able to run their old binaries with the old
libc++.so.3.0 and libc++abi.so.1.0, while the new clang would use
libc++.so.4.0 and libc++abi.so.2.0.

--George

Reply | Threaded
Open this post in threaded view
|

Re: macppc base-clang -msvr4-struct-return

Theo de Raadt-2
George Koehler <[hidden email]> wrote:

> On Tue, 11 Feb 2020 18:58:48 +0100
> Jeremie Courreges-Anglas <[hidden email]> wrote:
>
> > So the steps would be:
> > - build and install a new clang
> > - bump the major of libc++, build and install it
> > - rebuild and reinstall clang
> > - build new snap
>
> You are the first person to suggest bumping .so majors; I didn't think
> to do so.  If libc++ needs a major bump, then libc++abi and libLLVM
> might also need them.  These 3 are the only .so (that I can find)
> built by base-clang on powerpc.
>
> Across base + xenocara + ports, almost nothing uses these 3 .so on
> powerpc.  The only users that I find are
>  - /usr/bin/clang* using libc++.so.3.0 and libc++abi.so.1.0
>  - nothing using libLLVM.so.1.0
>
> (xenocara/lib/mesa uses libLLVM only for i386 amd64 arm64.  I looked
> for ports with LLVM in WANTLIB, found only devel/py-llvmlite, but it
> requires base-clang, and ports doesn't use base-clang for powerpc.)
>
> If we don't bump majors, then people who upgrade OpenBSD macppc would
> get the new libc++.so.3.0 and libc++abi.so.1.0 at the same time as the
> new clang; and people on other platforms won't see an unnecessary
> major bump.
>
> If we do bump majors, then people who had used /usr/bin/clang++ on
> OpenBSD macppc might be able to run their old binaries with the old
> libc++.so.3.0 and libc++abi.so.1.0, while the new clang would use
> libc++.so.4.0 and libc++abi.so.2.0.

We always bump minors or majors when the ABI changes (depends which kind
of ABI changes, but majors are common).

We never sneak in a ABI change.  You are changing the ABI.  There's
only one way this goes..

Yes the files change on all architectures.  There's nothing wrong
with that.  As long as it can build through..

Reply | Threaded
Open this post in threaded view
|

Re: macppc base-clang -msvr4-struct-return

George Koehler-2
In reply to this post by George Koehler-2
This is the everything diff: it includes the clang diff that I sent to
tech@, plus the major version bumps for libLLVM libc++ libc++abi.

 - distrib/sets/lists: put the new versions in the base sets.
 - gnu/llvm/tools/clang: -msvr4-struct-return
 - gnu/usr.bin/clang/libLLVM, lib/libcxx, lib/libcxxabi: new versions

Index: distrib/sets/lists/base/md.amd64
===================================================================
RCS file: /cvs/src/distrib/sets/lists/base/md.amd64,v
retrieving revision 1.875
diff -u -p -r1.875 md.amd64
--- distrib/sets/lists/base/md.amd64 30 Dec 2019 02:20:33 -0000 1.875
+++ distrib/sets/lists/base/md.amd64 12 Feb 2020 20:52:32 -0000
@@ -81,9 +81,9 @@
 ./usr/lib/gcc-lib/amd64-unknown-openbsd6.6/4.2.1/collect2
 ./usr/lib/gcc-lib/amd64-unknown-openbsd6.6/4.2.1/libgcc.a
 ./usr/lib/gcc-lib/amd64-unknown-openbsd6.6/4.2.1/specs
-./usr/lib/libLLVM.so.1.0
-./usr/lib/libc++.so.3.0
-./usr/lib/libc++abi.so.1.0
+./usr/lib/libLLVM.so.2.0
+./usr/lib/libc++.so.4.0
+./usr/lib/libc++abi.so.2.0
 ./usr/lib/libcompiler_rt.a
 ./usr/lib/libstdc++.so.57.0
 ./usr/libdata/perl5/amd64-openbsd
Index: distrib/sets/lists/base/md.arm64
===================================================================
RCS file: /cvs/src/distrib/sets/lists/base/md.arm64,v
retrieving revision 1.22
diff -u -p -r1.22 md.arm64
--- distrib/sets/lists/base/md.arm64 30 Dec 2019 02:20:34 -0000 1.22
+++ distrib/sets/lists/base/md.arm64 12 Feb 2020 20:52:32 -0000
@@ -37,9 +37,9 @@
 ./usr/lib/crtbeginS.o
 ./usr/lib/crtend.o
 ./usr/lib/crtendS.o
-./usr/lib/libLLVM.so.1.0
-./usr/lib/libc++.so.3.0
-./usr/lib/libc++abi.so.1.0
+./usr/lib/libLLVM.so.2.0
+./usr/lib/libc++.so.4.0
+./usr/lib/libc++abi.so.2.0
 ./usr/lib/libcompiler_rt.a
 ./usr/libdata/perl5/aarch64-openbsd
 ./usr/libdata/perl5/aarch64-openbsd/.packlist
Index: distrib/sets/lists/base/md.armv7
===================================================================
RCS file: /cvs/src/distrib/sets/lists/base/md.armv7,v
retrieving revision 1.284
diff -u -p -r1.284 md.armv7
--- distrib/sets/lists/base/md.armv7 30 Dec 2019 02:20:34 -0000 1.284
+++ distrib/sets/lists/base/md.armv7 12 Feb 2020 20:52:32 -0000
@@ -37,9 +37,9 @@
 ./usr/lib/crtbeginS.o
 ./usr/lib/crtend.o
 ./usr/lib/crtendS.o
-./usr/lib/libLLVM.so.1.0
-./usr/lib/libc++.so.3.0
-./usr/lib/libc++abi.so.1.0
+./usr/lib/libLLVM.so.2.0
+./usr/lib/libc++.so.4.0
+./usr/lib/libc++abi.so.2.0
 ./usr/lib/libcompiler_rt.a
 ./usr/libdata/perl5/arm-openbsd
 ./usr/libdata/perl5/arm-openbsd/.packlist
Index: distrib/sets/lists/base/md.i386
===================================================================
RCS file: /cvs/src/distrib/sets/lists/base/md.i386,v
retrieving revision 1.1254
diff -u -p -r1.1254 md.i386
--- distrib/sets/lists/base/md.i386 30 Dec 2019 02:20:34 -0000 1.1254
+++ distrib/sets/lists/base/md.i386 12 Feb 2020 20:52:32 -0000
@@ -78,9 +78,9 @@
 ./usr/lib/crtbeginS.o
 ./usr/lib/crtend.o
 ./usr/lib/crtendS.o
-./usr/lib/libLLVM.so.1.0
-./usr/lib/libc++.so.3.0
-./usr/lib/libc++abi.so.1.0
+./usr/lib/libLLVM.so.2.0
+./usr/lib/libc++.so.4.0
+./usr/lib/libc++abi.so.2.0
 ./usr/lib/libcompiler_rt.a
 ./usr/libdata/perl5/i386-openbsd
 ./usr/libdata/perl5/i386-openbsd/.packlist
Index: distrib/sets/lists/base/md.loongson
===================================================================
RCS file: /cvs/src/distrib/sets/lists/base/md.loongson,v
retrieving revision 1.456
diff -u -p -r1.456 md.loongson
--- distrib/sets/lists/base/md.loongson 30 Dec 2019 02:20:34 -0000 1.456
+++ distrib/sets/lists/base/md.loongson 12 Feb 2020 20:52:32 -0000
@@ -48,9 +48,9 @@
 ./usr/lib/gcc-lib/mips64el-unknown-openbsd6.6/4.2.1/collect2
 ./usr/lib/gcc-lib/mips64el-unknown-openbsd6.6/4.2.1/libgcc.a
 ./usr/lib/gcc-lib/mips64el-unknown-openbsd6.6/4.2.1/specs
-./usr/lib/libLLVM.so.1.0
-./usr/lib/libc++.so.3.0
-./usr/lib/libc++abi.so.1.0
+./usr/lib/libLLVM.so.2.0
+./usr/lib/libc++.so.4.0
+./usr/lib/libc++abi.so.2.0
 ./usr/lib/libcompiler_rt.a
 ./usr/lib/libstdc++.so.57.0
 ./usr/libdata/perl5/mips64el-openbsd
Index: distrib/sets/lists/base/md.macppc
===================================================================
RCS file: /cvs/src/distrib/sets/lists/base/md.macppc,v
retrieving revision 1.1023
diff -u -p -r1.1023 md.macppc
--- distrib/sets/lists/base/md.macppc 30 Dec 2019 02:20:34 -0000 1.1023
+++ distrib/sets/lists/base/md.macppc 12 Feb 2020 20:52:32 -0000
@@ -78,9 +78,9 @@
 ./usr/lib/gcc-lib/powerpc-unknown-openbsd6.6/4.2.1/collect2
 ./usr/lib/gcc-lib/powerpc-unknown-openbsd6.6/4.2.1/libgcc.a
 ./usr/lib/gcc-lib/powerpc-unknown-openbsd6.6/4.2.1/specs
-./usr/lib/libLLVM.so.1.0
-./usr/lib/libc++.so.3.0
-./usr/lib/libc++abi.so.1.0
+./usr/lib/libLLVM.so.2.0
+./usr/lib/libc++.so.4.0
+./usr/lib/libc++abi.so.2.0
 ./usr/lib/libcompiler_rt.a
 ./usr/lib/libstdc++.so.57.0
 ./usr/libdata/perl5/powerpc-openbsd
Index: distrib/sets/lists/base/md.octeon
===================================================================
RCS file: /cvs/src/distrib/sets/lists/base/md.octeon,v
retrieving revision 1.307
diff -u -p -r1.307 md.octeon
--- distrib/sets/lists/base/md.octeon 30 Dec 2019 02:20:34 -0000 1.307
+++ distrib/sets/lists/base/md.octeon 12 Feb 2020 20:52:32 -0000
@@ -46,9 +46,9 @@
 ./usr/lib/gcc-lib/mips64-unknown-openbsd6.6/4.2.1/collect2
 ./usr/lib/gcc-lib/mips64-unknown-openbsd6.6/4.2.1/libgcc.a
 ./usr/lib/gcc-lib/mips64-unknown-openbsd6.6/4.2.1/specs
-./usr/lib/libLLVM.so.1.0
-./usr/lib/libc++.so.3.0
-./usr/lib/libc++abi.so.1.0
+./usr/lib/libLLVM.so.2.0
+./usr/lib/libc++.so.4.0
+./usr/lib/libc++abi.so.2.0
 ./usr/lib/libcompiler_rt.a
 ./usr/lib/libstdc++.so.57.0
 ./usr/libdata/perl5/mips64-openbsd
Index: distrib/sets/lists/base/md.sgi
===================================================================
RCS file: /cvs/src/distrib/sets/lists/base/md.sgi,v
retrieving revision 1.836
diff -u -p -r1.836 md.sgi
--- distrib/sets/lists/base/md.sgi 30 Dec 2019 02:20:34 -0000 1.836
+++ distrib/sets/lists/base/md.sgi 12 Feb 2020 20:52:32 -0000
@@ -77,9 +77,9 @@
 ./usr/lib/gcc-lib/mips64-unknown-openbsd6.6/4.2.1/collect2
 ./usr/lib/gcc-lib/mips64-unknown-openbsd6.6/4.2.1/libgcc.a
 ./usr/lib/gcc-lib/mips64-unknown-openbsd6.6/4.2.1/specs
-./usr/lib/libLLVM.so.1.0
-./usr/lib/libc++.so.3.0
-./usr/lib/libc++abi.so.1.0
+./usr/lib/libLLVM.so.2.0
+./usr/lib/libc++.so.4.0
+./usr/lib/libc++abi.so.2.0
 ./usr/lib/libcompiler_rt.a
 ./usr/lib/libstdc++.so.57.0
 ./usr/libdata/perl5/mips64-openbsd
Index: distrib/sets/lists/base/md.sparc64
===================================================================
RCS file: /cvs/src/distrib/sets/lists/base/md.sparc64,v
retrieving revision 1.1020
diff -u -p -r1.1020 md.sparc64
--- distrib/sets/lists/base/md.sparc64 30 Dec 2019 02:20:34 -0000 1.1020
+++ distrib/sets/lists/base/md.sparc64 12 Feb 2020 20:52:32 -0000
@@ -79,9 +79,9 @@
 ./usr/lib/gcc-lib/sparc64-unknown-openbsd6.6/4.2.1/collect2
 ./usr/lib/gcc-lib/sparc64-unknown-openbsd6.6/4.2.1/libgcc.a
 ./usr/lib/gcc-lib/sparc64-unknown-openbsd6.6/4.2.1/specs
-./usr/lib/libLLVM.so.1.0
-./usr/lib/libc++.so.3.0
-./usr/lib/libc++abi.so.1.0
+./usr/lib/libLLVM.so.2.0
+./usr/lib/libc++.so.4.0
+./usr/lib/libc++abi.so.2.0
 ./usr/lib/libcompiler_rt.a
 ./usr/lib/libstdc++.so.57.0
 ./usr/libdata/perl5/sparc64-openbsd
Index: gnu/llvm/tools/clang/include/clang/Driver/Options.td
===================================================================
RCS file: /cvs/src/gnu/llvm/tools/clang/include/clang/Driver/Options.td,v
retrieving revision 1.11
diff -u -p -r1.11 Options.td
--- gnu/llvm/tools/clang/include/clang/Driver/Options.td 23 Jun 2019 22:05:15 -0000 1.11
+++ gnu/llvm/tools/clang/include/clang/Driver/Options.td 12 Feb 2020 20:52:35 -0000
@@ -2238,6 +2238,12 @@ def mlongcall: Flag<["-"], "mlongcall">,
     Group<m_ppc_Features_Group>;
 def mno_longcall : Flag<["-"], "mno-longcall">,
     Group<m_ppc_Features_Group>;
+def maix_struct_return : Flag<["-"], "maix-struct-return">,
+  Group<m_Group>, Flags<[CC1Option]>,
+  HelpText<"Return all structs in memory (PPC32 only)">;
+def msvr4_struct_return : Flag<["-"], "msvr4-struct-return">,
+  Group<m_Group>, Flags<[CC1Option]>,
+  HelpText<"Return small structs in registers (PPC32 only)">;
 
 def mvx : Flag<["-"], "mvx">, Group<m_Group>;
 def mno_vx : Flag<["-"], "mno-vx">, Group<m_Group>;
Index: gnu/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp
===================================================================
RCS file: /cvs/src/gnu/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp,v
retrieving revision 1.1.1.7
diff -u -p -r1.1.1.7 TargetInfo.cpp
--- gnu/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp 23 Jun 2019 21:37:39 -0000 1.1.1.7
+++ gnu/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp 12 Feb 2020 20:52:35 -0000
@@ -4092,12 +4092,24 @@ namespace {
 /// PPC32_SVR4_ABIInfo - The 32-bit PowerPC ELF (SVR4) ABI information.
 class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
   bool IsSoftFloatABI;
+  bool IsRetSmallStructInRegABI;
 
   CharUnits getParamTypeAlignment(QualType Ty) const;
 
 public:
-  PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, bool SoftFloatABI)
-      : DefaultABIInfo(CGT), IsSoftFloatABI(SoftFloatABI) {}
+  PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, bool SoftFloatABI,
+                     bool RetSmallStructInRegABI)
+      : DefaultABIInfo(CGT), IsSoftFloatABI(SoftFloatABI),
+        IsRetSmallStructInRegABI(RetSmallStructInRegABI) {}
+
+  ABIArgInfo classifyReturnType(QualType RetTy) const;
+
+  void computeInfo(CGFunctionInfo &FI) const override {
+    if (!getCXXABI().classifyReturnType(FI))
+      FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+    for (auto &I : FI.arguments())
+      I.info = classifyArgumentType(I.type);
+  }
 
   Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
                     QualType Ty) const override;
@@ -4105,8 +4117,13 @@ public:
 
 class PPC32TargetCodeGenInfo : public TargetCodeGenInfo {
 public:
-  PPC32TargetCodeGenInfo(CodeGenTypes &CGT, bool SoftFloatABI)
-      : TargetCodeGenInfo(new PPC32_SVR4_ABIInfo(CGT, SoftFloatABI)) {}
+  PPC32TargetCodeGenInfo(CodeGenTypes &CGT, bool SoftFloatABI,
+                         bool RetSmallStructInRegABI)
+      : TargetCodeGenInfo(new PPC32_SVR4_ABIInfo(CGT, SoftFloatABI,
+                                                 RetSmallStructInRegABI)) {}
+
+  static bool isStructReturnInRegABI(const llvm::Triple &Triple,
+                                     const CodeGenOptions &Opts);
 
   int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
     // This is recovered from gcc output.
@@ -4142,6 +4159,34 @@ CharUnits PPC32_SVR4_ABIInfo::getParamTy
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const {
+  uint64_t Size;
+
+  // -msvr4-struct-return puts small aggregates in GPR3 and GPR4.
+  if (isAggregateTypeForABI(RetTy) && IsRetSmallStructInRegABI &&
+      (Size = getContext().getTypeSize(RetTy)) <= 64) {
+    // System V ABI (1995), page 3-22, specified:
+    // > A structure or union whose size is less than or equal to 8 bytes
+    // > shall be returned in r3 and r4, as if it were first stored in the
+    // > 8-byte aligned memory area and then the low addressed word were
+    // > loaded into r3 and the high-addressed word into r4.  Bits beyond
+    // > the last member of the structure or union are not defined.
+    //
+    // GCC for big-endian PPC32 inserts the pad before the first member,
+    // not "beyond the last member" of the struct.  To stay compatible
+    // with GCC, we coerce the struct to an integer of the same size.
+    // LLVM will extend it and return i32 in r3, or i64 in r3:r4.
+    if (Size == 0)
+      return ABIArgInfo::getIgnore();
+    else {
+      llvm::Type *CoerceTy = llvm::Type::getIntNTy(getVMContext(), Size);
+      return ABIArgInfo::getDirect(CoerceTy);
+    }
+  }
+
+  return DefaultABIInfo::classifyReturnType(RetTy);
+}
+
 // TODO: this implementation is now likely redundant with
 // DefaultABIInfo::EmitVAArg.
 Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
@@ -4299,6 +4344,25 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(Co
   return Result;
 }
 
+bool PPC32TargetCodeGenInfo::isStructReturnInRegABI(
+    const llvm::Triple &Triple, const CodeGenOptions &Opts) {
+  assert(Triple.getArch() == llvm::Triple::ppc);
+
+  switch (Opts.getStructReturnConvention()) {
+  case CodeGenOptions::SRCK_Default:
+    break;
+  case CodeGenOptions::SRCK_OnStack: // -maix-struct-return
+    return false;
+  case CodeGenOptions::SRCK_InRegs: // -msvr4-struct-return
+    return true;
+  }
+
+  if (Triple.isOSBinFormatELF() && !Triple.isOSLinux())
+    return true;
+
+  return false;
+}
+
 bool
 PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
                                                 llvm::Value *Address) const {
@@ -9330,9 +9394,13 @@ const TargetCodeGenInfo &CodeGenModule::
     return SetCGInfo(new ARMTargetCodeGenInfo(Types, Kind));
   }
 
-  case llvm::Triple::ppc:
+  case llvm::Triple::ppc: {
+    bool RetSmallStructInRegABI =
+        PPC32TargetCodeGenInfo::isStructReturnInRegABI(Triple, CodeGenOpts);
     return SetCGInfo(
-        new PPC32TargetCodeGenInfo(Types, CodeGenOpts.FloatABI == "soft"));
+        new PPC32TargetCodeGenInfo(Types, CodeGenOpts.FloatABI == "soft",
+                                   RetSmallStructInRegABI));
+  }
   case llvm::Triple::ppc64:
     if (Triple.isOSBinFormatELF()) {
       PPC64_SVR4_ABIInfo::ABIKind Kind = PPC64_SVR4_ABIInfo::ELFv1;
Index: gnu/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
RCS file: /cvs/src/gnu/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp,v
retrieving revision 1.20
diff -u -p -r1.20 Clang.cpp
--- gnu/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp 25 Oct 2019 00:40:56 -0000 1.20
+++ gnu/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp 12 Feb 2020 20:52:35 -0000
@@ -3870,6 +3870,19 @@ void Clang::ConstructJob(Compilation &C,
     CmdArgs.push_back(A->getValue());
   }
 
+  if (Arg *A = Args.getLastArg(options::OPT_maix_struct_return,
+                               options::OPT_msvr4_struct_return)) {
+    if (TC.getArch() != llvm::Triple::ppc) {
+      D.Diag(diag::err_drv_unsupported_opt_for_target)
+          << A->getSpelling() << RawTriple.str();
+    } else if (A->getOption().matches(options::OPT_maix_struct_return)) {
+      CmdArgs.push_back("-maix-struct-return");
+    } else {
+      assert(A->getOption().matches(options::OPT_msvr4_struct_return));
+      CmdArgs.push_back("-msvr4-struct-return");
+    }
+  }
+
   if (Arg *A = Args.getLastArg(options::OPT_fpcc_struct_return,
                                options::OPT_freg_struct_return)) {
     if (TC.getArch() != llvm::Triple::x86) {
Index: gnu/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
RCS file: /cvs/src/gnu/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp,v
retrieving revision 1.4
diff -u -p -r1.4 CompilerInvocation.cpp
--- gnu/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp 23 Jun 2019 22:05:15 -0000 1.4
+++ gnu/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp 12 Feb 2020 20:52:35 -0000
@@ -1199,11 +1199,18 @@ static bool ParseCodeGenArgs(CodeGenOpti
       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);
     }
   }
Index: gnu/usr.bin/clang/libLLVM/shlib_version
===================================================================
RCS file: /cvs/src/gnu/usr.bin/clang/libLLVM/shlib_version,v
retrieving revision 1.2
diff -u -p -r1.2 shlib_version
--- gnu/usr.bin/clang/libLLVM/shlib_version 23 Jun 2019 22:07:38 -0000 1.2
+++ gnu/usr.bin/clang/libLLVM/shlib_version 12 Feb 2020 20:52:41 -0000
@@ -1,2 +1,2 @@
-major=1
+major=2
 minor=0
Index: lib/libcxx/shlib_version
===================================================================
RCS file: /cvs/src/lib/libcxx/shlib_version,v
retrieving revision 1.6
diff -u -p -r1.6 shlib_version
--- lib/libcxx/shlib_version 17 Jun 2019 22:28:47 -0000 1.6
+++ lib/libcxx/shlib_version 12 Feb 2020 20:52:46 -0000
@@ -1,2 +1,2 @@
-major=3
+major=4
 minor=0
Index: lib/libcxxabi/shlib_version
===================================================================
RCS file: /cvs/src/lib/libcxxabi/shlib_version,v
retrieving revision 1.4
diff -u -p -r1.4 shlib_version
--- lib/libcxxabi/shlib_version 17 Jun 2019 22:28:51 -0000 1.4
+++ lib/libcxxabi/shlib_version 12 Feb 2020 20:52:46 -0000
@@ -1,3 +1,3 @@
 # Don't forget to give libc++ the same type of bump!
-major=1
+major=2
 minor=0

Reply | Threaded
Open this post in threaded view
|

Re: macppc base-clang -msvr4-struct-return

Todd Mortimer
On Wed, Feb 12, 2020 at 04:05:38PM -0500, George Koehler wrote:
> This is the everything diff: it includes the clang diff that I sent to
> tech@, plus the major version bumps for libLLVM libc++ libc++abi.
>
>  - distrib/sets/lists: put the new versions in the base sets.
>  - gnu/llvm/tools/clang: -msvr4-struct-return
>  - gnu/usr.bin/clang/libLLVM, lib/libcxx, lib/libcxxabi: new versions

I think this is good to go.

I built through the ABI change with this diff using the directions
George posted earlier:

> To update from source, you must build clang before you build the
> new versions of base libraries.
> First, change major=2 to major=1 in
> /usr/src/gnu/usr.bin/clang/libLLVM/shlib_version.
>
> Then build clang:
>
> # cd /usr/src/gnu/usr.bin/clang
> # make obj
> # make
> # make install
>
> Then change major=1 back to major=2 in
> /usr/src/gnu/usr.bin/clang/libLLVM/shlib_version.
> Then build userland (including clang again).

Then I built a new snapshot and sysupgraded to that snapshot, all
without incident. The snapshot is in my home dir on cvs
(snapshots/macppc) if anyone wants to avoid the build. I checked the
tarballs and the right versions of the bumped libs are all there.

ok mortimer@


>
> Index: distrib/sets/lists/base/md.amd64
> ===================================================================
> RCS file: /cvs/src/distrib/sets/lists/base/md.amd64,v
> retrieving revision 1.875
> diff -u -p -r1.875 md.amd64
> --- distrib/sets/lists/base/md.amd64 30 Dec 2019 02:20:33 -0000 1.875
> +++ distrib/sets/lists/base/md.amd64 12 Feb 2020 20:52:32 -0000
> @@ -81,9 +81,9 @@
>  ./usr/lib/gcc-lib/amd64-unknown-openbsd6.6/4.2.1/collect2
>  ./usr/lib/gcc-lib/amd64-unknown-openbsd6.6/4.2.1/libgcc.a
>  ./usr/lib/gcc-lib/amd64-unknown-openbsd6.6/4.2.1/specs
> -./usr/lib/libLLVM.so.1.0
> -./usr/lib/libc++.so.3.0
> -./usr/lib/libc++abi.so.1.0
> +./usr/lib/libLLVM.so.2.0
> +./usr/lib/libc++.so.4.0
> +./usr/lib/libc++abi.so.2.0
>  ./usr/lib/libcompiler_rt.a
>  ./usr/lib/libstdc++.so.57.0
>  ./usr/libdata/perl5/amd64-openbsd
> Index: distrib/sets/lists/base/md.arm64
> ===================================================================
> RCS file: /cvs/src/distrib/sets/lists/base/md.arm64,v
> retrieving revision 1.22
> diff -u -p -r1.22 md.arm64
> --- distrib/sets/lists/base/md.arm64 30 Dec 2019 02:20:34 -0000 1.22
> +++ distrib/sets/lists/base/md.arm64 12 Feb 2020 20:52:32 -0000
> @@ -37,9 +37,9 @@
>  ./usr/lib/crtbeginS.o
>  ./usr/lib/crtend.o
>  ./usr/lib/crtendS.o
> -./usr/lib/libLLVM.so.1.0
> -./usr/lib/libc++.so.3.0
> -./usr/lib/libc++abi.so.1.0
> +./usr/lib/libLLVM.so.2.0
> +./usr/lib/libc++.so.4.0
> +./usr/lib/libc++abi.so.2.0
>  ./usr/lib/libcompiler_rt.a
>  ./usr/libdata/perl5/aarch64-openbsd
>  ./usr/libdata/perl5/aarch64-openbsd/.packlist
> Index: distrib/sets/lists/base/md.armv7
> ===================================================================
> RCS file: /cvs/src/distrib/sets/lists/base/md.armv7,v
> retrieving revision 1.284
> diff -u -p -r1.284 md.armv7
> --- distrib/sets/lists/base/md.armv7 30 Dec 2019 02:20:34 -0000 1.284
> +++ distrib/sets/lists/base/md.armv7 12 Feb 2020 20:52:32 -0000
> @@ -37,9 +37,9 @@
>  ./usr/lib/crtbeginS.o
>  ./usr/lib/crtend.o
>  ./usr/lib/crtendS.o
> -./usr/lib/libLLVM.so.1.0
> -./usr/lib/libc++.so.3.0
> -./usr/lib/libc++abi.so.1.0
> +./usr/lib/libLLVM.so.2.0
> +./usr/lib/libc++.so.4.0
> +./usr/lib/libc++abi.so.2.0
>  ./usr/lib/libcompiler_rt.a
>  ./usr/libdata/perl5/arm-openbsd
>  ./usr/libdata/perl5/arm-openbsd/.packlist
> Index: distrib/sets/lists/base/md.i386
> ===================================================================
> RCS file: /cvs/src/distrib/sets/lists/base/md.i386,v
> retrieving revision 1.1254
> diff -u -p -r1.1254 md.i386
> --- distrib/sets/lists/base/md.i386 30 Dec 2019 02:20:34 -0000 1.1254
> +++ distrib/sets/lists/base/md.i386 12 Feb 2020 20:52:32 -0000
> @@ -78,9 +78,9 @@
>  ./usr/lib/crtbeginS.o
>  ./usr/lib/crtend.o
>  ./usr/lib/crtendS.o
> -./usr/lib/libLLVM.so.1.0
> -./usr/lib/libc++.so.3.0
> -./usr/lib/libc++abi.so.1.0
> +./usr/lib/libLLVM.so.2.0
> +./usr/lib/libc++.so.4.0
> +./usr/lib/libc++abi.so.2.0
>  ./usr/lib/libcompiler_rt.a
>  ./usr/libdata/perl5/i386-openbsd
>  ./usr/libdata/perl5/i386-openbsd/.packlist
> Index: distrib/sets/lists/base/md.loongson
> ===================================================================
> RCS file: /cvs/src/distrib/sets/lists/base/md.loongson,v
> retrieving revision 1.456
> diff -u -p -r1.456 md.loongson
> --- distrib/sets/lists/base/md.loongson 30 Dec 2019 02:20:34 -0000 1.456
> +++ distrib/sets/lists/base/md.loongson 12 Feb 2020 20:52:32 -0000
> @@ -48,9 +48,9 @@
>  ./usr/lib/gcc-lib/mips64el-unknown-openbsd6.6/4.2.1/collect2
>  ./usr/lib/gcc-lib/mips64el-unknown-openbsd6.6/4.2.1/libgcc.a
>  ./usr/lib/gcc-lib/mips64el-unknown-openbsd6.6/4.2.1/specs
> -./usr/lib/libLLVM.so.1.0
> -./usr/lib/libc++.so.3.0
> -./usr/lib/libc++abi.so.1.0
> +./usr/lib/libLLVM.so.2.0
> +./usr/lib/libc++.so.4.0
> +./usr/lib/libc++abi.so.2.0
>  ./usr/lib/libcompiler_rt.a
>  ./usr/lib/libstdc++.so.57.0
>  ./usr/libdata/perl5/mips64el-openbsd
> Index: distrib/sets/lists/base/md.macppc
> ===================================================================
> RCS file: /cvs/src/distrib/sets/lists/base/md.macppc,v
> retrieving revision 1.1023
> diff -u -p -r1.1023 md.macppc
> --- distrib/sets/lists/base/md.macppc 30 Dec 2019 02:20:34 -0000 1.1023
> +++ distrib/sets/lists/base/md.macppc 12 Feb 2020 20:52:32 -0000
> @@ -78,9 +78,9 @@
>  ./usr/lib/gcc-lib/powerpc-unknown-openbsd6.6/4.2.1/collect2
>  ./usr/lib/gcc-lib/powerpc-unknown-openbsd6.6/4.2.1/libgcc.a
>  ./usr/lib/gcc-lib/powerpc-unknown-openbsd6.6/4.2.1/specs
> -./usr/lib/libLLVM.so.1.0
> -./usr/lib/libc++.so.3.0
> -./usr/lib/libc++abi.so.1.0
> +./usr/lib/libLLVM.so.2.0
> +./usr/lib/libc++.so.4.0
> +./usr/lib/libc++abi.so.2.0
>  ./usr/lib/libcompiler_rt.a
>  ./usr/lib/libstdc++.so.57.0
>  ./usr/libdata/perl5/powerpc-openbsd
> Index: distrib/sets/lists/base/md.octeon
> ===================================================================
> RCS file: /cvs/src/distrib/sets/lists/base/md.octeon,v
> retrieving revision 1.307
> diff -u -p -r1.307 md.octeon
> --- distrib/sets/lists/base/md.octeon 30 Dec 2019 02:20:34 -0000 1.307
> +++ distrib/sets/lists/base/md.octeon 12 Feb 2020 20:52:32 -0000
> @@ -46,9 +46,9 @@
>  ./usr/lib/gcc-lib/mips64-unknown-openbsd6.6/4.2.1/collect2
>  ./usr/lib/gcc-lib/mips64-unknown-openbsd6.6/4.2.1/libgcc.a
>  ./usr/lib/gcc-lib/mips64-unknown-openbsd6.6/4.2.1/specs
> -./usr/lib/libLLVM.so.1.0
> -./usr/lib/libc++.so.3.0
> -./usr/lib/libc++abi.so.1.0
> +./usr/lib/libLLVM.so.2.0
> +./usr/lib/libc++.so.4.0
> +./usr/lib/libc++abi.so.2.0
>  ./usr/lib/libcompiler_rt.a
>  ./usr/lib/libstdc++.so.57.0
>  ./usr/libdata/perl5/mips64-openbsd
> Index: distrib/sets/lists/base/md.sgi
> ===================================================================
> RCS file: /cvs/src/distrib/sets/lists/base/md.sgi,v
> retrieving revision 1.836
> diff -u -p -r1.836 md.sgi
> --- distrib/sets/lists/base/md.sgi 30 Dec 2019 02:20:34 -0000 1.836
> +++ distrib/sets/lists/base/md.sgi 12 Feb 2020 20:52:32 -0000
> @@ -77,9 +77,9 @@
>  ./usr/lib/gcc-lib/mips64-unknown-openbsd6.6/4.2.1/collect2
>  ./usr/lib/gcc-lib/mips64-unknown-openbsd6.6/4.2.1/libgcc.a
>  ./usr/lib/gcc-lib/mips64-unknown-openbsd6.6/4.2.1/specs
> -./usr/lib/libLLVM.so.1.0
> -./usr/lib/libc++.so.3.0
> -./usr/lib/libc++abi.so.1.0
> +./usr/lib/libLLVM.so.2.0
> +./usr/lib/libc++.so.4.0
> +./usr/lib/libc++abi.so.2.0
>  ./usr/lib/libcompiler_rt.a
>  ./usr/lib/libstdc++.so.57.0
>  ./usr/libdata/perl5/mips64-openbsd
> Index: distrib/sets/lists/base/md.sparc64
> ===================================================================
> RCS file: /cvs/src/distrib/sets/lists/base/md.sparc64,v
> retrieving revision 1.1020
> diff -u -p -r1.1020 md.sparc64
> --- distrib/sets/lists/base/md.sparc64 30 Dec 2019 02:20:34 -0000 1.1020
> +++ distrib/sets/lists/base/md.sparc64 12 Feb 2020 20:52:32 -0000
> @@ -79,9 +79,9 @@
>  ./usr/lib/gcc-lib/sparc64-unknown-openbsd6.6/4.2.1/collect2
>  ./usr/lib/gcc-lib/sparc64-unknown-openbsd6.6/4.2.1/libgcc.a
>  ./usr/lib/gcc-lib/sparc64-unknown-openbsd6.6/4.2.1/specs
> -./usr/lib/libLLVM.so.1.0
> -./usr/lib/libc++.so.3.0
> -./usr/lib/libc++abi.so.1.0
> +./usr/lib/libLLVM.so.2.0
> +./usr/lib/libc++.so.4.0
> +./usr/lib/libc++abi.so.2.0
>  ./usr/lib/libcompiler_rt.a
>  ./usr/lib/libstdc++.so.57.0
>  ./usr/libdata/perl5/sparc64-openbsd
> Index: gnu/llvm/tools/clang/include/clang/Driver/Options.td
> ===================================================================
> RCS file: /cvs/src/gnu/llvm/tools/clang/include/clang/Driver/Options.td,v
> retrieving revision 1.11
> diff -u -p -r1.11 Options.td
> --- gnu/llvm/tools/clang/include/clang/Driver/Options.td 23 Jun 2019 22:05:15 -0000 1.11
> +++ gnu/llvm/tools/clang/include/clang/Driver/Options.td 12 Feb 2020 20:52:35 -0000
> @@ -2238,6 +2238,12 @@ def mlongcall: Flag<["-"], "mlongcall">,
>      Group<m_ppc_Features_Group>;
>  def mno_longcall : Flag<["-"], "mno-longcall">,
>      Group<m_ppc_Features_Group>;
> +def maix_struct_return : Flag<["-"], "maix-struct-return">,
> +  Group<m_Group>, Flags<[CC1Option]>,
> +  HelpText<"Return all structs in memory (PPC32 only)">;
> +def msvr4_struct_return : Flag<["-"], "msvr4-struct-return">,
> +  Group<m_Group>, Flags<[CC1Option]>,
> +  HelpText<"Return small structs in registers (PPC32 only)">;
>  
>  def mvx : Flag<["-"], "mvx">, Group<m_Group>;
>  def mno_vx : Flag<["-"], "mno-vx">, Group<m_Group>;
> Index: gnu/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp
> ===================================================================
> RCS file: /cvs/src/gnu/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp,v
> retrieving revision 1.1.1.7
> diff -u -p -r1.1.1.7 TargetInfo.cpp
> --- gnu/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp 23 Jun 2019 21:37:39 -0000 1.1.1.7
> +++ gnu/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp 12 Feb 2020 20:52:35 -0000
> @@ -4092,12 +4092,24 @@ namespace {
>  /// PPC32_SVR4_ABIInfo - The 32-bit PowerPC ELF (SVR4) ABI information.
>  class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
>    bool IsSoftFloatABI;
> +  bool IsRetSmallStructInRegABI;
>  
>    CharUnits getParamTypeAlignment(QualType Ty) const;
>  
>  public:
> -  PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, bool SoftFloatABI)
> -      : DefaultABIInfo(CGT), IsSoftFloatABI(SoftFloatABI) {}
> +  PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, bool SoftFloatABI,
> +                     bool RetSmallStructInRegABI)
> +      : DefaultABIInfo(CGT), IsSoftFloatABI(SoftFloatABI),
> +        IsRetSmallStructInRegABI(RetSmallStructInRegABI) {}
> +
> +  ABIArgInfo classifyReturnType(QualType RetTy) const;
> +
> +  void computeInfo(CGFunctionInfo &FI) const override {
> +    if (!getCXXABI().classifyReturnType(FI))
> +      FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
> +    for (auto &I : FI.arguments())
> +      I.info = classifyArgumentType(I.type);
> +  }
>  
>    Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
>                      QualType Ty) const override;
> @@ -4105,8 +4117,13 @@ public:
>  
>  class PPC32TargetCodeGenInfo : public TargetCodeGenInfo {
>  public:
> -  PPC32TargetCodeGenInfo(CodeGenTypes &CGT, bool SoftFloatABI)
> -      : TargetCodeGenInfo(new PPC32_SVR4_ABIInfo(CGT, SoftFloatABI)) {}
> +  PPC32TargetCodeGenInfo(CodeGenTypes &CGT, bool SoftFloatABI,
> +                         bool RetSmallStructInRegABI)
> +      : TargetCodeGenInfo(new PPC32_SVR4_ABIInfo(CGT, SoftFloatABI,
> +                                                 RetSmallStructInRegABI)) {}
> +
> +  static bool isStructReturnInRegABI(const llvm::Triple &Triple,
> +                                     const CodeGenOptions &Opts);
>  
>    int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
>      // This is recovered from gcc output.
> @@ -4142,6 +4159,34 @@ CharUnits PPC32_SVR4_ABIInfo::getParamTy
>    return CharUnits::fromQuantity(4);
>  }
>  
> +ABIArgInfo PPC32_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const {
> +  uint64_t Size;
> +
> +  // -msvr4-struct-return puts small aggregates in GPR3 and GPR4.
> +  if (isAggregateTypeForABI(RetTy) && IsRetSmallStructInRegABI &&
> +      (Size = getContext().getTypeSize(RetTy)) <= 64) {
> +    // System V ABI (1995), page 3-22, specified:
> +    // > A structure or union whose size is less than or equal to 8 bytes
> +    // > shall be returned in r3 and r4, as if it were first stored in the
> +    // > 8-byte aligned memory area and then the low addressed word were
> +    // > loaded into r3 and the high-addressed word into r4.  Bits beyond
> +    // > the last member of the structure or union are not defined.
> +    //
> +    // GCC for big-endian PPC32 inserts the pad before the first member,
> +    // not "beyond the last member" of the struct.  To stay compatible
> +    // with GCC, we coerce the struct to an integer of the same size.
> +    // LLVM will extend it and return i32 in r3, or i64 in r3:r4.
> +    if (Size == 0)
> +      return ABIArgInfo::getIgnore();
> +    else {
> +      llvm::Type *CoerceTy = llvm::Type::getIntNTy(getVMContext(), Size);
> +      return ABIArgInfo::getDirect(CoerceTy);
> +    }
> +  }
> +
> +  return DefaultABIInfo::classifyReturnType(RetTy);
> +}
> +
>  // TODO: this implementation is now likely redundant with
>  // DefaultABIInfo::EmitVAArg.
>  Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
> @@ -4299,6 +4344,25 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(Co
>    return Result;
>  }
>  
> +bool PPC32TargetCodeGenInfo::isStructReturnInRegABI(
> +    const llvm::Triple &Triple, const CodeGenOptions &Opts) {
> +  assert(Triple.getArch() == llvm::Triple::ppc);
> +
> +  switch (Opts.getStructReturnConvention()) {
> +  case CodeGenOptions::SRCK_Default:
> +    break;
> +  case CodeGenOptions::SRCK_OnStack: // -maix-struct-return
> +    return false;
> +  case CodeGenOptions::SRCK_InRegs: // -msvr4-struct-return
> +    return true;
> +  }
> +
> +  if (Triple.isOSBinFormatELF() && !Triple.isOSLinux())
> +    return true;
> +
> +  return false;
> +}
> +
>  bool
>  PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
>                                                  llvm::Value *Address) const {
> @@ -9330,9 +9394,13 @@ const TargetCodeGenInfo &CodeGenModule::
>      return SetCGInfo(new ARMTargetCodeGenInfo(Types, Kind));
>    }
>  
> -  case llvm::Triple::ppc:
> +  case llvm::Triple::ppc: {
> +    bool RetSmallStructInRegABI =
> +        PPC32TargetCodeGenInfo::isStructReturnInRegABI(Triple, CodeGenOpts);
>      return SetCGInfo(
> -        new PPC32TargetCodeGenInfo(Types, CodeGenOpts.FloatABI == "soft"));
> +        new PPC32TargetCodeGenInfo(Types, CodeGenOpts.FloatABI == "soft",
> +                                   RetSmallStructInRegABI));
> +  }
>    case llvm::Triple::ppc64:
>      if (Triple.isOSBinFormatELF()) {
>        PPC64_SVR4_ABIInfo::ABIKind Kind = PPC64_SVR4_ABIInfo::ELFv1;
> Index: gnu/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp
> ===================================================================
> RCS file: /cvs/src/gnu/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp,v
> retrieving revision 1.20
> diff -u -p -r1.20 Clang.cpp
> --- gnu/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp 25 Oct 2019 00:40:56 -0000 1.20
> +++ gnu/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp 12 Feb 2020 20:52:35 -0000
> @@ -3870,6 +3870,19 @@ void Clang::ConstructJob(Compilation &C,
>      CmdArgs.push_back(A->getValue());
>    }
>  
> +  if (Arg *A = Args.getLastArg(options::OPT_maix_struct_return,
> +                               options::OPT_msvr4_struct_return)) {
> +    if (TC.getArch() != llvm::Triple::ppc) {
> +      D.Diag(diag::err_drv_unsupported_opt_for_target)
> +          << A->getSpelling() << RawTriple.str();
> +    } else if (A->getOption().matches(options::OPT_maix_struct_return)) {
> +      CmdArgs.push_back("-maix-struct-return");
> +    } else {
> +      assert(A->getOption().matches(options::OPT_msvr4_struct_return));
> +      CmdArgs.push_back("-msvr4-struct-return");
> +    }
> +  }
> +
>    if (Arg *A = Args.getLastArg(options::OPT_fpcc_struct_return,
>                                 options::OPT_freg_struct_return)) {
>      if (TC.getArch() != llvm::Triple::x86) {
> Index: gnu/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp
> ===================================================================
> RCS file: /cvs/src/gnu/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp,v
> retrieving revision 1.4
> diff -u -p -r1.4 CompilerInvocation.cpp
> --- gnu/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp 23 Jun 2019 22:05:15 -0000 1.4
> +++ gnu/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp 12 Feb 2020 20:52:35 -0000
> @@ -1199,11 +1199,18 @@ static bool ParseCodeGenArgs(CodeGenOpti
>        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);
>      }
>    }
> Index: gnu/usr.bin/clang/libLLVM/shlib_version
> ===================================================================
> RCS file: /cvs/src/gnu/usr.bin/clang/libLLVM/shlib_version,v
> retrieving revision 1.2
> diff -u -p -r1.2 shlib_version
> --- gnu/usr.bin/clang/libLLVM/shlib_version 23 Jun 2019 22:07:38 -0000 1.2
> +++ gnu/usr.bin/clang/libLLVM/shlib_version 12 Feb 2020 20:52:41 -0000
> @@ -1,2 +1,2 @@
> -major=1
> +major=2
>  minor=0
> Index: lib/libcxx/shlib_version
> ===================================================================
> RCS file: /cvs/src/lib/libcxx/shlib_version,v
> retrieving revision 1.6
> diff -u -p -r1.6 shlib_version
> --- lib/libcxx/shlib_version 17 Jun 2019 22:28:47 -0000 1.6
> +++ lib/libcxx/shlib_version 12 Feb 2020 20:52:46 -0000
> @@ -1,2 +1,2 @@
> -major=3
> +major=4
>  minor=0
> Index: lib/libcxxabi/shlib_version
> ===================================================================
> RCS file: /cvs/src/lib/libcxxabi/shlib_version,v
> retrieving revision 1.4
> diff -u -p -r1.4 shlib_version
> --- lib/libcxxabi/shlib_version 17 Jun 2019 22:28:51 -0000 1.4
> +++ lib/libcxxabi/shlib_version 12 Feb 2020 20:52:46 -0000
> @@ -1,3 +1,3 @@
>  # Don't forget to give libc++ the same type of bump!
> -major=1
> +major=2
>  minor=0