diff options
author | Fangrui Song <maskray@google.com> | 2019-07-12 02:32:15 +0000 |
---|---|---|
committer | Fangrui Song <maskray@google.com> | 2019-07-12 02:32:15 +0000 |
commit | 586c626a72115fe7a32b7cee305081b83aea6731 (patch) | |
tree | b2762e9f8a683b0b037d525eb335987992b9f88d | |
parent | 27cd6f0ade36b2399fb0198ce5a2ecf17e9bde38 (diff) | |
download | clang-586c626a72115fe7a32b7cee305081b83aea6731.tar.gz |
[X86][PowerPC] Support -mlong-double-128
This patch makes the driver option -mlong-double-128 available for X86
and PowerPC. The CC1 option -mlong-double-128 is available on all targets
for users to test on unsupported targets.
On PowerPC, -mlong-double-128 uses the IBM extended double format
because we don't support -mabi=ieeelongdouble yet (D64283).
Reviewed By: rnk
Differential Revision: https://reviews.llvm.org/D64277
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@365866 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Driver/Options.td | 2 | ||||
-rw-r--r-- | lib/Basic/TargetInfo.cpp | 13 | ||||
-rw-r--r-- | lib/Basic/Targets/PPC.cpp | 2 | ||||
-rw-r--r-- | lib/Basic/Targets/X86.h | 6 | ||||
-rw-r--r-- | lib/Driver/ToolChains/Clang.cpp | 10 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 4 | ||||
-rw-r--r-- | test/CodeGen/ppc64-long-double.cpp | 3 | ||||
-rw-r--r-- | test/CodeGen/x86-long-double.cpp | 13 | ||||
-rw-r--r-- | test/Driver/mlong-double-128.c | 11 |
9 files changed, 52 insertions, 12 deletions
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 08af5ad20a..957483c318 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -2025,6 +2025,8 @@ def mlong_calls : Flag<["-"], "mlong-calls">, Group<m_Group>, HelpText<"Generate branches with extended addressability, usually via indirect jumps.">; def mlong_double_64 : Flag<["-"], "mlong-double-64">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Force long double to be 64 bits">; +def mlong_double_128 : Flag<["-"], "mlong-double-128">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Force long double to be 128 bits">; def mno_long_calls : Flag<["-"], "mno-long-calls">, Group<m_Group>, HelpText<"Restore the default behaviour of not generating long calls">; def mexecute_only : Flag<["-"], "mexecute-only">, Group<m_arm_Features_Group>, diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp index 43ab77289b..a9dfe69b90 100644 --- a/lib/Basic/TargetInfo.cpp +++ b/lib/Basic/TargetInfo.cpp @@ -373,10 +373,15 @@ void TargetInfo::adjust(LangOptions &Opts) { LongDoubleFormat = &llvm::APFloat::IEEEquad(); } - if (Opts.LongDoubleSize && Opts.LongDoubleSize == DoubleWidth) { - LongDoubleWidth = DoubleWidth; - LongDoubleAlign = DoubleAlign; - LongDoubleFormat = DoubleFormat; + if (Opts.LongDoubleSize) { + if (Opts.LongDoubleSize == DoubleWidth) { + LongDoubleWidth = DoubleWidth; + LongDoubleAlign = DoubleAlign; + LongDoubleFormat = DoubleFormat; + } else if (Opts.LongDoubleSize == 128) { + LongDoubleWidth = LongDoubleAlign = 128; + LongDoubleFormat = &llvm::APFloat::IEEEquad(); + } } if (Opts.NewAlignOverride) diff --git a/lib/Basic/Targets/PPC.cpp b/lib/Basic/Targets/PPC.cpp index b052ef433e..bd0ae60038 100644 --- a/lib/Basic/Targets/PPC.cpp +++ b/lib/Basic/Targets/PPC.cpp @@ -465,6 +465,8 @@ void PPCTargetInfo::adjust(LangOptions &Opts) { if (HasAltivec) Opts.AltiVec = 1; TargetInfo::adjust(Opts); + if (LongDoubleFormat != &llvm::APFloat::IEEEdouble()) + LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble(); } ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const { diff --git a/lib/Basic/Targets/X86.h b/lib/Basic/Targets/X86.h index c0dfc81f57..588b6d3da1 100644 --- a/lib/Basic/Targets/X86.h +++ b/lib/Basic/Targets/X86.h @@ -133,6 +133,10 @@ public: LongDoubleFormat = &llvm::APFloat::x87DoubleExtended(); } + const char *getLongDoubleMangling() const override { + return LongDoubleFormat == &llvm::APFloat::IEEEquad() ? "g" : "e"; + } + unsigned getFloatEvalMethod() const override { // X87 evaluates with 80 bits "long double" precision. return SSELevel == NoSSE ? 2 : 0; @@ -845,8 +849,6 @@ public: : LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts) { LongDoubleFormat = &llvm::APFloat::IEEEquad(); } - - const char *getLongDoubleMangling() const override { return "g"; } }; } // namespace targets } // namespace clang diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index 16360189f1..719123fdc3 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -4012,15 +4012,15 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, RenderFloatingPointOptions(TC, D, OFastEnabled, Args, CmdArgs); - if (Arg *A = Args.getLastArg(options::OPT_mlong_double_64)) { + if (Arg *A = Args.getLastArg(options::OPT_mlong_double_64, + options::OPT_mlong_double_128)) { if (TC.getArch() == llvm::Triple::x86 || TC.getArch() == llvm::Triple::x86_64 || - TC.getArch() == llvm::Triple::ppc || TC.getTriple().isPPC64()) { - CmdArgs.push_back("-mlong-double-64"); - } else { + TC.getArch() == llvm::Triple::ppc || TC.getTriple().isPPC64()) + A->render(Args, CmdArgs); + else D.Diag(diag::err_drv_unsupported_opt_for_target) << A->getAsString(Args) << TripleStr; - } } // Decide whether to use verbose asm. Verbose assembly is the default on diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 0d9e29da26..7a07d9955f 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -2742,7 +2742,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.PackStruct = getLastArgIntValue(Args, OPT_fpack_struct_EQ, 0, Diags); Opts.MaxTypeAlign = getLastArgIntValue(Args, OPT_fmax_type_align_EQ, 0, Diags); Opts.AlignDouble = Args.hasArg(OPT_malign_double); - Opts.LongDoubleSize = Args.hasArg(OPT_mlong_double_64) ? 64 : 0; + Opts.LongDoubleSize = Args.hasArg(OPT_mlong_double_128) + ? 128 + : Args.hasArg(OPT_mlong_double_64) ? 64 : 0; Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags); Opts.ROPI = Args.hasArg(OPT_fropi); Opts.RWPI = Args.hasArg(OPT_frwpi); diff --git a/test/CodeGen/ppc64-long-double.cpp b/test/CodeGen/ppc64-long-double.cpp index 56cb24a3d1..d588d6b80e 100644 --- a/test/CodeGen/ppc64-long-double.cpp +++ b/test/CodeGen/ppc64-long-double.cpp @@ -2,8 +2,11 @@ // RUN: FileCheck --check-prefix=FP64 %s // RUN: %clang_cc1 -triple powerpc64-linux-gnu -emit-llvm -o - %s -mlong-double-64 | \ // RUN: FileCheck --check-prefix=FP64 %s + // RUN: %clang_cc1 -triple powerpc64-linux-gnu -emit-llvm -o - %s | \ // RUN: FileCheck --check-prefix=IBM128 %s +// RUN: %clang_cc1 -triple powerpc64-linux-musl -emit-llvm -o - -mlong-double-128 %s | \ +// RUN: FileCheck --check-prefix=IBM128 %s long double x = 0; int size = sizeof(x); diff --git a/test/CodeGen/x86-long-double.cpp b/test/CodeGen/x86-long-double.cpp index a05470aeab..40ac29715f 100644 --- a/test/CodeGen/x86-long-double.cpp +++ b/test/CodeGen/x86-long-double.cpp @@ -16,6 +16,15 @@ // RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin -mlong-double-64 | \ // RUN: FileCheck --check-prefixes=FP64,FP64-X64 %s +// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686 -mlong-double-128 | \ +// RUN: FileCheck --check-prefix=FP128 %s +// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-apple-darwin -mlong-double-128 | \ +// RUN: FileCheck --check-prefix=FP128 %s +// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64 -mlong-double-128 | \ +// RUN: FileCheck --check-prefix=FP128 %s +// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin -mlong-double-128 | \ +// RUN: FileCheck --check-prefix=FP128 %s + // Check -malign-double increases the alignment from 4 to 8 on x86-32. // RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686 -mlong-double-64 \ // RUN: -malign-double | FileCheck --check-prefixes=FP64,FP64-X64 %s @@ -37,7 +46,11 @@ int size = sizeof(x); // FP64-X64: @x = global double {{.*}}, align 8 // FP64-X64: @size = global i32 8 +// FP128: @x = global fp128 {{.*}}, align 16 +// FP128: @size = global i32 16 + long double foo(long double d) { return d; } // FP64: double @_Z3fooe(double %d) // FP80: x86_fp80 @_Z3fooe(x86_fp80 %d) +// FP128: fp128 @_Z3foog(fp128 %d) diff --git a/test/Driver/mlong-double-128.c b/test/Driver/mlong-double-128.c new file mode 100644 index 0000000000..ae76265a3b --- /dev/null +++ b/test/Driver/mlong-double-128.c @@ -0,0 +1,11 @@ +// RUN: %clang -target powerpc-linux-musl -c -### %s -mlong-double-128 2>&1 | FileCheck %s +// RUN: %clang -target powerpc64-pc-freebsd12 -c -### %s -mlong-double-128 2>&1 | FileCheck %s +// RUN: %clang -target powerpc64le-linux-musl -c -### %s -mlong-double-128 2>&1 | FileCheck %s +// RUN: %clang -target i686-linux-gnu -c -### %s -mlong-double-128 2>&1 | FileCheck %s +// RUN: %clang -target x86_64-linux-musl -c -### %s -mlong-double-128 2>&1 | FileCheck %s + +// CHECK: "-mlong-double-128" + +// RUN: %clang -target aarch64 -c -### %s -mlong-double-128 2>&1 | FileCheck --check-prefix=ERR %s + +// ERR: error: unsupported option '-mlong-double-128' for target 'aarch64' |