Skip to content

Commit 3e19ba3

Browse files
committed
[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
1 parent 15dfe03 commit 3e19ba3

File tree

3 files changed

+48
-3
lines changed

3 files changed

+48
-3
lines changed

clang/lib/Basic/TargetInfo.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,20 @@ void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
449449
} else if (Opts.LongDoubleSize == 128) {
450450
LongDoubleWidth = LongDoubleAlign = 128;
451451
LongDoubleFormat = &llvm::APFloat::IEEEquad();
452+
} else if (Opts.LongDoubleSize == 80) {
453+
LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
454+
if (getTriple().isWindowsMSVCEnvironment()) {
455+
LongDoubleWidth = 128;
456+
LongDoubleAlign = 128;
457+
} else { // Linux
458+
if (getTriple().getArch() == llvm::Triple::x86) {
459+
LongDoubleWidth = 96;
460+
LongDoubleAlign = 32;
461+
} else {
462+
LongDoubleWidth = 128;
463+
LongDoubleAlign = 128;
464+
}
465+
}
452466
}
453467
}
454468

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3456,6 +3456,8 @@ void CompilerInvocation::GenerateLangArgs(const LangOptions &Opts,
34563456
GenerateArg(Args, OPT_mlong_double_128, SA);
34573457
else if (Opts.LongDoubleSize == 64)
34583458
GenerateArg(Args, OPT_mlong_double_64, SA);
3459+
else if (Opts.LongDoubleSize == 80)
3460+
GenerateArg(Args, OPT_mlong_double_80, SA);
34593461

34603462
// Not generating '-mrtd', it's just an alias for '-fdefault-calling-conv='.
34613463

@@ -3838,9 +3840,16 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
38383840
Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
38393841
if (!Opts.NoBuiltin)
38403842
getAllNoBuiltinFuncValues(Args, Opts.NoBuiltinFuncs);
3841-
Opts.LongDoubleSize = Args.hasArg(OPT_mlong_double_128)
3842-
? 128
3843-
: Args.hasArg(OPT_mlong_double_64) ? 64 : 0;
3843+
if (Arg *A = Args.getLastArg(options::OPT_LongDouble_Group)) {
3844+
if (A->getOption().matches(options::OPT_mlong_double_64))
3845+
Opts.LongDoubleSize = 64;
3846+
else if (A->getOption().matches(options::OPT_mlong_double_80))
3847+
Opts.LongDoubleSize = 80;
3848+
else if (A->getOption().matches(options::OPT_mlong_double_128))
3849+
Opts.LongDoubleSize = 128;
3850+
else
3851+
Opts.LongDoubleSize = 0;
3852+
}
38443853
if (Opts.FastRelaxedMath)
38453854
Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
38463855
llvm::sort(Opts.ModuleFeatures);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %clang_cc1 -triple x86_64-windows-msvc %s -emit-llvm -mlong-double-64 -o - | FileCheck %s --check-prefix=SIZE64
2+
// RUN: %clang_cc1 -triple i386-windows-msvc %s -emit-llvm -mlong-double-80 -o - | FileCheck %s --check-prefix=SIZE80
3+
// RUN: %clang_cc1 -triple x86_64-windows-msvc %s -emit-llvm -mlong-double-80 -o - | FileCheck %s --check-prefix=SIZE80
4+
// RUN: %clang_cc1 -triple x86_64-windows-msvc %s -emit-llvm -mlong-double-128 -o - | FileCheck %s --check-prefix=SIZE128
5+
// RUN: %clang_cc1 -triple x86_64-windows-msvc %s -emit-llvm -o - | FileCheck %s --check-prefix=SIZE64
6+
7+
long double global;
8+
// SIZE64: @global = dso_local global double 0
9+
// SIZE80: @global = dso_local global x86_fp80 0xK{{0+}}, align 16
10+
// SIZE128: @global = dso_local global fp128 0
11+
12+
long double func(long double param) {
13+
// SIZE64: define dso_local double @func(double noundef %param)
14+
// SIZE80: define dso_local x86_fp80 @func(x86_fp80 noundef %param)
15+
// SIZE128: define dso_local fp128 @func(fp128 noundef %param)
16+
long double local = param;
17+
// SIZE64: alloca double
18+
// SIZE80: alloca x86_fp80, align 16
19+
// SIZE128: alloca fp128
20+
local = param;
21+
return local + param;
22+
}

0 commit comments

Comments
 (0)