Skip to content

Commit 4a2c827

Browse files
committed
[X86][clang] Emit diagnostic for float and double when we have features -x87 and -sse on 64-bits
A follow up of D114162. Reviewed By: asavonic Differential Revision: https://reviews.llvm.org/D114782
1 parent 5dda2ef commit 4a2c827

File tree

5 files changed

+47
-28
lines changed

5 files changed

+47
-28
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10731,6 +10731,8 @@ def err_omp_wrong_dependency_iterator_type : Error<
1073110731
def err_target_unsupported_type
1073210732
: Error<"%0 requires %select{|%2 bit size}1 %3 %select{|return }4type support,"
1073310733
" but target '%5' does not support it">;
10734+
def err_target_unsupported_type_without_sse : Error<
10735+
"SSE register return with SSE disabled">;
1073410736
def err_omp_lambda_capture_in_declare_target_not_to : Error<
1073510737
"variable captured in declare target region must appear in a to clause">;
1073610738
def err_omp_device_type_mismatch : Error<

clang/lib/Basic/Targets/X86.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,9 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
387387
if (!HasX87 && LongDoubleFormat == &llvm::APFloat::x87DoubleExtended())
388388
HasLongDouble = false;
389389

390+
if (SSELevel < SSE1 && getTriple().getArch() == llvm::Triple::x86_64)
391+
HasFPReturn = false;
392+
390393
return true;
391394
}
392395

clang/lib/Sema/Sema.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1957,15 +1957,7 @@ void Sema::checkTypeSupport(QualType Ty, SourceLocation Loc, ValueDecl *D) {
19571957
bool IsDouble = UnqualTy == Context.DoubleTy;
19581958
bool IsFloat = UnqualTy == Context.FloatTy;
19591959
if (IsRetTy && !TI.hasFPReturn() && (IsDouble || IsFloat)) {
1960-
PartialDiagnostic PD = PDiag(diag::err_target_unsupported_type);
1961-
if (D)
1962-
PD << D;
1963-
else
1964-
PD << "expression";
1965-
1966-
if (Diag(Loc, PD, FD)
1967-
<< false /*show bit size*/ << 0 << Ty << true /*return*/
1968-
<< Context.getTargetInfo().getTriple().str()) {
1960+
if (Diag(Loc, diag::err_target_unsupported_type_without_sse)) {
19691961
if (D)
19701962
D->setInvalidDecl();
19711963
}
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
// RUN: %clang_cc1 -triple x86_64-linux -target-feature -sse -target-feature -sse2 -S -o /dev/null -verify %s
22
// REQUIRES: x86-registered-target
33

4-
double f1(void) { // expected-error {{SSE register return with SSE disabled}}
4+
// expected-error@+2{{SSE register return with SSE disabled}}
5+
// expected-note@+1{{'f1' defined here}}
6+
double f1(void) {
57
return 1.4;
68
}
79
extern double g;
8-
void f2(void) { // expected-error {{SSE register return with SSE disabled}}
10+
void f2(void) {
911
g = f1();
1012
}
1113
void take_double(double);
1214
void pass_double(void) {
13-
// FIXME: Still asserts.
14-
//take_double(1.5);
15+
take_double(1.5);
1516
}

clang/test/Sema/x86_64-no-x87.cpp

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -target-feature -x87
1+
// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -target-feature -x87 -target-feature -sse -DERROR_LONGDOUBLE -DERROR_NOSSE
2+
// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -target-feature -x87 -DERROR_LONGDOUBLE
23
// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -DNOERROR
34

45
#ifdef NOERROR
@@ -18,82 +19,82 @@ long_double decl_ld_del(long_double) = delete;
1819
double decl_ld_del(double) = delete;
1920
float decl_ld_del(float) = delete;
2021

21-
#ifndef NOERROR
22+
#ifdef ERROR_LONGDOUBLE
2223
// expected-error@+4{{'def' requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
2324
// expected-note@+3{{'def' defined here}}
2425
// expected-note@+2{{'x' defined here}}
2526
#endif
2627
int def(long_double x) {
27-
#ifndef NOERROR
28+
#ifdef ERROR_LONGDOUBLE
2829
// expected-error@+2{{'x' requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
2930
#endif
3031
return (int)x;
3132
}
3233

33-
#ifndef NOERROR
34+
#ifdef ERROR_LONGDOUBLE
3435
// expected-note@+3{{'ld_args' defined here}}
3536
// expected-note@+2{{'ld_args' defined here}}
3637
#endif
3738
int ld_args(long_double x, long_double y);
3839

3940
int call1(float x, float y) {
40-
#ifndef NOERROR
41+
#ifdef ERROR_LONGDOUBLE
4142
// expected-error@+2 2{{'ld_args' requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
4243
#endif
4344
return ld_args(x, y);
4445
}
4546

46-
#ifndef NOERROR
47+
#ifdef ERROR_LONGDOUBLE
4748
// expected-note@+2{{'ld_ret' defined here}}
4849
#endif
4950
long_double ld_ret(double x, double y);
5051

5152
int call2(float x, float y) {
52-
#ifndef NOERROR
53+
#ifdef ERROR_LONGDOUBLE
5354
// expected-error@+2{{'ld_ret' requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
5455
#endif
5556
return (int)ld_ret(x, y);
5657
}
5758

5859
int binop(double x, double y) {
59-
#ifndef NOERROR
60+
#ifdef ERROR_LONGDOUBLE
6061
// expected-error@+2 2{{expression requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
6162
#endif
6263
double z = (long_double)x * (long_double)y;
6364
return (int)z;
6465
}
6566

6667
void assign1(long_double *ret, double x) {
67-
#ifndef NOERROR
68+
#ifdef ERROR_LONGDOUBLE
6869
// expected-error@+2{{expression requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
6970
#endif
7071
*ret = x;
7172
}
7273

7374
struct st_long_double1 {
74-
#ifndef NOERROR
75+
#ifdef ERROR_LONGDOUBLE
7576
// expected-note@+2{{'ld' defined here}}
7677
#endif
7778
long_double ld;
7879
};
7980

8081
struct st_long_double2 {
81-
#ifndef NOERROR
82+
#ifdef ERROR_LONGDOUBLE
8283
// expected-note@+2{{'ld' defined here}}
8384
#endif
8485
long_double ld;
8586
};
8687

8788
struct st_long_double3 {
88-
#ifndef NOERROR
89+
#ifdef ERROR_LONGDOUBLE
8990
// expected-note@+2{{'ld' defined here}}
9091
#endif
9192
long_double ld;
9293
};
9394

9495
void assign2() {
9596
struct st_long_double1 st;
96-
#ifndef NOERROR
97+
#ifdef ERROR_LONGDOUBLE
9798
// expected-error@+3{{expression requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
9899
// expected-error@+2{{'ld' requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
99100
#endif
@@ -102,7 +103,7 @@ void assign2() {
102103

103104
void assign3() {
104105
struct st_long_double2 st;
105-
#ifndef NOERROR
106+
#ifdef ERROR_LONGDOUBLE
106107
// expected-error@+3{{expression requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
107108
// expected-error@+2{{'ld' requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
108109
#endif
@@ -111,7 +112,7 @@ void assign3() {
111112

112113
void assign4(double d) {
113114
struct st_long_double3 st;
114-
#ifndef NOERROR
115+
#ifdef ERROR_LONGDOUBLE
115116
// expected-error@+3{{expression requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
116117
// expected-error@+2{{'ld' requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
117118
#endif
@@ -124,22 +125,42 @@ void assign5() {
124125
}
125126

126127
// Double and Float return type on x86_64 do not use x87 registers
128+
#ifdef ERROR_NOSSE
129+
// expected-error@+3{{SSE register return with SSE disabled}}
130+
// expected-note@+2{{'d_ret1' defined here}}
131+
#endif
127132
double d_ret1(float x) {
128133
return 0.0;
129134
}
130135

136+
#ifdef ERROR_NOSSE
137+
// expected-note@+2{{'d_ret2' defined here}}
138+
#endif
131139
double d_ret2(float x);
132140

141+
#ifdef ERROR_NOSSE
142+
// expected-error@+3{{SSE register return with SSE disabled}}
143+
#endif
133144
int d_ret3(float x) {
134145
return (int)d_ret2(x);
135146
}
136147

148+
#ifdef ERROR_NOSSE
149+
// expected-error@+3{{SSE register return with SSE disabled}}
150+
// expected-note@+2{{'f_ret1' defined here}}
151+
#endif
137152
float f_ret1(float x) {
138153
return 0.0f;
139154
}
140155

156+
#ifdef ERROR_NOSSE
157+
// expected-note@+2{{'f_ret2' defined here}}
158+
#endif
141159
float f_ret2(float x);
142160

161+
#ifdef ERROR_NOSSE
162+
// expected-error@+3{{SSE register return with SSE disabled}}
163+
#endif
143164
int f_ret3(float x) {
144165
return (int)f_ret2(x);
145166
}

0 commit comments

Comments
 (0)