]> granicus.if.org Git - clang/commitdiff
[PowerPC] Support -mabi=ieeelongdouble and -mabi=ibmlongdouble
authorFangrui Song <maskray@google.com>
Mon, 15 Jul 2019 07:25:11 +0000 (07:25 +0000)
committerFangrui Song <maskray@google.com>
Mon, 15 Jul 2019 07:25:11 +0000 (07:25 +0000)
gcc PowerPC supports 3 representations of long double:

* -mlong-double-64

  long double has the same representation of double but is mangled as `e`.
  In clang, this is the default on AIX, FreeBSD and Linux musl.

* -mlong-double-128

  2 possible 128-bit floating point representations:

  + -mabi=ibmlongdouble
    IBM extended double format. Mangled as `g`
    In clang, this is the default on Linux glibc.
  + -mabi=ieeelongdouble
    IEEE 754 quadruple-precision format. Mangled as `u9__ieee128` (`U10__float128` before gcc 8.2)
    This is currently unavailable.

This patch adds -mabi=ibmlongdouble and -mabi=ieeelongdouble, and thus
makes the IEEE 754 quadruple-precision long double available for
languages supported by clang.

Reviewed By: hfinkel

Differential Revision: https://reviews.llvm.org/D64283

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@366044 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/LangOptions.def
include/clang/Driver/CC1Options.td
lib/Basic/Targets/PPC.cpp
lib/Driver/ToolChains/Clang.cpp
lib/Frontend/CompilerInvocation.cpp
test/CodeGen/ppc64-long-double.cpp
test/Driver/ppc-abi.c

index 46012f73aa8b84c453145b25b22857519c7aa0a3..bbe3f7b77dbc67f77503b45895eeb9abbcff045e 100644 (file)
@@ -172,6 +172,7 @@ VALUE_LANGOPT(MaxTypeAlign  , 32, 0,
               "default maximum alignment for types")
 VALUE_LANGOPT(AlignDouble            , 1, 0, "Controls if doubles should be aligned to 8 bytes (x86 only)")
 VALUE_LANGOPT(LongDoubleSize        , 32, 0, "width of long double")
+LANGOPT(PPCIEEELongDouble            , 1, 0, "use IEEE 754 quadruple-precision for long double")
 COMPATIBLE_VALUE_LANGOPT(PICLevel    , 2, 0, "__PIC__ level")
 COMPATIBLE_VALUE_LANGOPT(PIE         , 1, 0, "is pie")
 LANGOPT(ROPI                         , 1, 0, "Read-only position independence")
index 8862a015827bda3b9c4088d722d5f17aeeccd07e..1f6c000ecf6a1172b808e47c080f2eedd3f499bb 100644 (file)
@@ -298,6 +298,8 @@ def menable_unsafe_fp_math : Flag<["-"], "menable-unsafe-fp-math">,
            "precision">;
 def mreassociate : Flag<["-"], "mreassociate">,
   HelpText<"Allow reassociation transformations for floating-point instructions">;
+def mabi_EQ_ieeelongdouble : Flag<["-"], "mabi=ieeelongdouble">,
+  HelpText<"Use IEEE 754 quadruple-precision for long double">;
 def mfloat_abi : Separate<["-"], "mfloat-abi">,
   HelpText<"The float ABI to use">;
 def mtp : Separate<["-"], "mtp">,
index bd0ae600380926d44997a73a8b655e1f55e124aa..2a773d9992869b8bfa211c0e18e4aa50f5437be7 100644 (file)
@@ -466,7 +466,9 @@ void PPCTargetInfo::adjust(LangOptions &Opts) {
     Opts.AltiVec = 1;
   TargetInfo::adjust(Opts);
   if (LongDoubleFormat != &llvm::APFloat::IEEEdouble())
-    LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble();
+    LongDoubleFormat = Opts.PPCIEEELongDouble
+                           ? &llvm::APFloat::IEEEquad()
+                           : &llvm::APFloat::PPCDoubleDouble();
 }
 
 ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const {
index c84cb480f1a54bae26187b3bdc7b5fdf61261c87..6a83e1a480a5d09e08b74bea5732c87482688c5f 100644 (file)
@@ -1803,12 +1803,21 @@ void Clang::AddPPCTargetArgs(const ArgList &Args,
       break;
     }
 
-  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
-    // The ppc64 linux abis are all "altivec" abis by default. Accept and ignore
-    // the option if given as we don't have backend support for any targets
-    // that don't use the altivec abi.
-    if (StringRef(A->getValue()) != "altivec")
+  bool IEEELongDouble = false;
+  for (const Arg *A : Args.filtered(options::OPT_mabi_EQ)) {
+    StringRef V = A->getValue();
+    if (V == "ieeelongdouble")
+      IEEELongDouble = true;
+    else if (V == "ibmlongdouble")
+      IEEELongDouble = false;
+    else if (V != "altivec")
+      // The ppc64 linux abis are all "altivec" abis by default. Accept and ignore
+      // the option if given as we don't have backend support for any targets
+      // that don't use the altivec abi.
       ABIName = A->getValue();
+  }
+  if (IEEELongDouble)
+    CmdArgs.push_back("-mabi=ieeelongdouble");
 
   ppc::FloatABI FloatABI =
       ppc::getPPCFloatABI(getToolChain().getDriver(), Args);
index 7a07d9955fe74a094af724b0910619c762b9b173..8a9844096f08166c0d8807f95787e813a7c2de9d 100644 (file)
@@ -2745,6 +2745,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
   Opts.LongDoubleSize = Args.hasArg(OPT_mlong_double_128)
                             ? 128
                             : Args.hasArg(OPT_mlong_double_64) ? 64 : 0;
+  Opts.PPCIEEELongDouble = Args.hasArg(OPT_mabi_EQ_ieeelongdouble);
   Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
   Opts.ROPI = Args.hasArg(OPT_fropi);
   Opts.RWPI = Args.hasArg(OPT_frwpi);
index d588d6b80e963925809a7d9db6db481591cd665d..a35965f2bf6848a0eab951494dd13da77f3ba480 100644 (file)
@@ -3,6 +3,14 @@
 // RUN: %clang_cc1 -triple powerpc64-linux-gnu -emit-llvm -o - %s -mlong-double-64 | \
 // RUN:   FileCheck --check-prefix=FP64 %s
 
+// musl defaults to -mlong-double-64, so -mlong-double-128 is needed to make
+// -mabi=ieeelongdouble effective.
+// RUN: %clang_cc1 -triple powerpc64-linux-musl -emit-llvm -o - %s -mlong-double-128 \
+// RUN:   -mabi=ieeelongdouble | FileCheck --check-prefix=FP128 %s
+// RUN: %clang_cc1 -triple powerpc64-linux-gnu -emit-llvm -o - %s \
+// RUN:   -mabi=ieeelongdouble | FileCheck --check-prefix=FP128 %s
+
+// IBM extended double is the default.
 // 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 | \
@@ -13,10 +21,13 @@ int size = sizeof(x);
 
 // FP64: @x = global double {{.*}}, align 8
 // FP64: @size = global i32 8
+// FP128: @x = global fp128 {{.*}}, align 16
+// FP128: @size = global i32 16
 // IBM128: @x = global ppc_fp128 {{.*}}, align 16
 // IBM128: @size = global i32 16
 
 long double foo(long double d) { return d; }
 
 // FP64: double @_Z3fooe(double %d)
+// FP128: fp128 @_Z3foou9__ieee128(fp128 %d)
 // IBM128: ppc_fp128 @_Z3foog(ppc_fp128 %d)
index a82a01de2781ec26072f39bfa78e72ae472845cf..fdcf45da2900dd1174d4ae05aa0cbbfadeeafa83 100644 (file)
 // CHECK-ELFv2-PIC: "-mrelocation-model" "pic" "-pic-level" "2"
 // CHECK-ELFv2-PIC: "-target-abi" "elfv2"
 
+// Check -mabi=ieeelongdouble is passed through but it does not change -target-abi.
+// RUN: %clang -target powerpc64le-linux-gnu %s -mabi=ieeelongdouble -mabi=elfv1 -### 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-ELFv1-IEEE %s
+// RUN: %clang -target powerpc64le-linux-gnu %s -mabi=elfv1 -mabi=ieeelongdouble -### 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-ELFv1-IEEE %s
+// RUN: %clang -target powerpc64le-linux-gnu %s -mabi=elfv2 -mabi=elfv1 -mabi=ibmlongdouble -mabi=ieeelongdouble -### 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-ELFv1-IEEE %s
 
+// CHECK-ELFv1-IEEE: "-mabi=ieeelongdouble"
+// CHECK-ELFv1-IEEE: "-target-abi" "elfv1"
+
+// Check -mabi=ibmlongdouble is the default.
+// RUN: %clang -target powerpc64le-linux-gnu %s -### 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-ELFv2-IBM128 %s
+// RUN: %clang -target powerpc64le-linux-gnu %s -mabi=ibmlongdouble -### 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-ELFv2-IBM128 %s
+
+// CHECK-ELFv2-IBM128-NOT: "-mabi=ieeelongdouble"
+// CHECK-ELFv2-IBM128: "-target-abi" "elfv2"