[clang] 3e19ba3 - [X86][MS] Add 80bit long double support for Windows

Phoebe Wang via cfe-commits cfe-commits at lists.llvm.org
Sun Feb 13 21:51:18 PST 2022


Author: Phoebe Wang
Date: 2022-02-14T13:32:29+08:00
New Revision: 3e19ba36fca9fa0b6aba0de2767f26dfd463cb5a

URL: https://github.com/llvm/llvm-project/commit/3e19ba36fca9fa0b6aba0de2767f26dfd463cb5a
DIFF: https://github.com/llvm/llvm-project/commit/3e19ba36fca9fa0b6aba0de2767f26dfd463cb5a.diff

LOG: [X86][MS] Add 80bit long double support for Windows

MSVC currently doesn't support 80 bits long double. But ICC does support
it on Windows. Besides, there're also some users asked for this feature.
We can find the discussions from stackoverflow, msdn etc.

Given Clang has already support `-mlong-double-80`, extending it to
support for Windows seems worthwhile.

Reviewed By: rnk, erichkeane

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

Added: 
    clang/test/CodeGen/X86/long-double-config-size.c

Modified: 
    clang/lib/Basic/TargetInfo.cpp
    clang/lib/Frontend/CompilerInvocation.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index e3a2f30febe75..801961dc3b56a 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -449,6 +449,20 @@ void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
     } else if (Opts.LongDoubleSize == 128) {
       LongDoubleWidth = LongDoubleAlign = 128;
       LongDoubleFormat = &llvm::APFloat::IEEEquad();
+    } else if (Opts.LongDoubleSize == 80) {
+      LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
+      if (getTriple().isWindowsMSVCEnvironment()) {
+        LongDoubleWidth = 128;
+        LongDoubleAlign = 128;
+      } else { // Linux
+        if (getTriple().getArch() == llvm::Triple::x86) {
+          LongDoubleWidth = 96;
+          LongDoubleAlign = 32;
+        } else {
+          LongDoubleWidth = 128;
+          LongDoubleAlign = 128;
+        }
+      }
     }
   }
 

diff  --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index c42cae941634f..1b7448feb472b 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3456,6 +3456,8 @@ void CompilerInvocation::GenerateLangArgs(const LangOptions &Opts,
     GenerateArg(Args, OPT_mlong_double_128, SA);
   else if (Opts.LongDoubleSize == 64)
     GenerateArg(Args, OPT_mlong_double_64, SA);
+  else if (Opts.LongDoubleSize == 80)
+    GenerateArg(Args, OPT_mlong_double_80, SA);
 
   // Not generating '-mrtd', it's just an alias for '-fdefault-calling-conv='.
 
@@ -3838,9 +3840,16 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
   Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
   if (!Opts.NoBuiltin)
     getAllNoBuiltinFuncValues(Args, Opts.NoBuiltinFuncs);
-  Opts.LongDoubleSize = Args.hasArg(OPT_mlong_double_128)
-                            ? 128
-                            : Args.hasArg(OPT_mlong_double_64) ? 64 : 0;
+  if (Arg *A = Args.getLastArg(options::OPT_LongDouble_Group)) {
+    if (A->getOption().matches(options::OPT_mlong_double_64))
+      Opts.LongDoubleSize = 64;
+    else if (A->getOption().matches(options::OPT_mlong_double_80))
+      Opts.LongDoubleSize = 80;
+    else if (A->getOption().matches(options::OPT_mlong_double_128))
+      Opts.LongDoubleSize = 128;
+    else
+      Opts.LongDoubleSize = 0;
+  }
   if (Opts.FastRelaxedMath)
     Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
   llvm::sort(Opts.ModuleFeatures);

diff  --git a/clang/test/CodeGen/X86/long-double-config-size.c b/clang/test/CodeGen/X86/long-double-config-size.c
new file mode 100644
index 0000000000000..563a483ca8cd6
--- /dev/null
+++ b/clang/test/CodeGen/X86/long-double-config-size.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple x86_64-windows-msvc %s -emit-llvm -mlong-double-64 -o - | FileCheck %s --check-prefix=SIZE64
+// RUN: %clang_cc1 -triple i386-windows-msvc %s -emit-llvm -mlong-double-80 -o - | FileCheck %s --check-prefix=SIZE80
+// RUN: %clang_cc1 -triple x86_64-windows-msvc %s -emit-llvm -mlong-double-80 -o - | FileCheck %s --check-prefix=SIZE80
+// RUN: %clang_cc1 -triple x86_64-windows-msvc %s -emit-llvm -mlong-double-128 -o - | FileCheck %s --check-prefix=SIZE128
+// RUN: %clang_cc1 -triple x86_64-windows-msvc %s -emit-llvm -o - | FileCheck %s --check-prefix=SIZE64
+
+long double global;
+// SIZE64: @global = dso_local global double 0
+// SIZE80: @global = dso_local global x86_fp80 0xK{{0+}}, align 16
+// SIZE128: @global = dso_local global fp128 0
+
+long double func(long double param) {
+  // SIZE64: define dso_local double @func(double noundef %param)
+  // SIZE80: define dso_local x86_fp80 @func(x86_fp80 noundef %param)
+  // SIZE128: define dso_local fp128  @func(fp128 noundef %param)
+  long double local = param;
+  // SIZE64: alloca double
+  // SIZE80: alloca x86_fp80, align 16
+  // SIZE128: alloca fp128
+  local = param;
+  return local + param;
+}


        


More information about the cfe-commits mailing list