pengfei created this revision.
pengfei added reviewers: asavonic, erichkeane, nickdesaulniers.
pengfei requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
A follow up of D114162 <https://reviews.llvm.org/D114162>.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D114782
Files:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Basic/Targets/X86.cpp
clang/lib/Sema/Sema.cpp
clang/test/Sema/x86_64-no-x87.cpp
Index: clang/test/Sema/x86_64-no-x87.cpp
===================================================================
--- clang/test/Sema/x86_64-no-x87.cpp
+++ clang/test/Sema/x86_64-no-x87.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -target-feature -x87
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -target-feature -x87 -target-feature -sse -DERROR_LONGDOUBLE -DERROR_NOSSE
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -target-feature -x87 -DERROR_LONGDOUBLE
// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -DNOERROR
#ifdef NOERROR
@@ -18,45 +19,45 @@
double decl_ld_del(double) = delete;
float decl_ld_del(float) = delete;
-#ifndef NOERROR
+#ifdef ERROR_LONGDOUBLE
// expected-error@+4{{'def' requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
// expected-note@+3{{'def' defined here}}
// expected-note@+2{{'x' defined here}}
#endif
int def(long_double x) {
-#ifndef NOERROR
+#ifdef ERROR_LONGDOUBLE
// expected-error@+2{{'x' requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
#endif
return (int)x;
}
-#ifndef NOERROR
+#ifdef ERROR_LONGDOUBLE
// expected-note@+3{{'ld_args' defined here}}
// expected-note@+2{{'ld_args' defined here}}
#endif
int ld_args(long_double x, long_double y);
int call1(float x, float y) {
-#ifndef NOERROR
+#ifdef ERROR_LONGDOUBLE
// 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}}
#endif
return ld_args(x, y);
}
-#ifndef NOERROR
+#ifdef ERROR_LONGDOUBLE
// expected-note@+2{{'ld_ret' defined here}}
#endif
long_double ld_ret(double x, double y);
int call2(float x, float y) {
-#ifndef NOERROR
+#ifdef ERROR_LONGDOUBLE
// expected-error@+2{{'ld_ret' requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
#endif
return (int)ld_ret(x, y);
}
int binop(double x, double y) {
-#ifndef NOERROR
+#ifdef ERROR_LONGDOUBLE
// expected-error@+2 2{{expression requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
#endif
double z = (long_double)x * (long_double)y;
@@ -64,28 +65,28 @@
}
void assign1(long_double *ret, double x) {
-#ifndef NOERROR
+#ifdef ERROR_LONGDOUBLE
// expected-error@+2{{expression requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
#endif
*ret = x;
}
struct st_long_double1 {
-#ifndef NOERROR
+#ifdef ERROR_LONGDOUBLE
// expected-note@+2{{'ld' defined here}}
#endif
long_double ld;
};
struct st_long_double2 {
-#ifndef NOERROR
+#ifdef ERROR_LONGDOUBLE
// expected-note@+2{{'ld' defined here}}
#endif
long_double ld;
};
struct st_long_double3 {
-#ifndef NOERROR
+#ifdef ERROR_LONGDOUBLE
// expected-note@+2{{'ld' defined here}}
#endif
long_double ld;
@@ -93,7 +94,7 @@
void assign2() {
struct st_long_double1 st;
-#ifndef NOERROR
+#ifdef ERROR_LONGDOUBLE
// expected-error@+3{{expression requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
// expected-error@+2{{'ld' requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
#endif
@@ -102,7 +103,7 @@
void assign3() {
struct st_long_double2 st;
-#ifndef NOERROR
+#ifdef ERROR_LONGDOUBLE
// expected-error@+3{{expression requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
// expected-error@+2{{'ld' requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
#endif
@@ -111,7 +112,7 @@
void assign4(double d) {
struct st_long_double3 st;
-#ifndef NOERROR
+#ifdef ERROR_LONGDOUBLE
// expected-error@+3{{expression requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
// expected-error@+2{{'ld' requires 'long_double' (aka 'long double') type support, but target 'x86_64-unknown-linux-gnu' does not support it}}
#endif
@@ -124,22 +125,42 @@
}
// Double and Float return type on x86_64 do not use x87 registers
+#ifdef ERROR_NOSSE
+ // expected-error@+3{{SSE register return with SSE disabled}}
+ // expected-note@+2{{'d_ret1' defined here}}
+#endif
double d_ret1(float x) {
return 0.0;
}
+#ifdef ERROR_NOSSE
+ // expected-note@+2{{'d_ret2' defined here}}
+#endif
double d_ret2(float x);
+#ifdef ERROR_NOSSE
+ // expected-error@+3{{SSE register return with SSE disabled}}
+#endif
int d_ret3(float x) {
return (int)d_ret2(x);
}
+#ifdef ERROR_NOSSE
+ // expected-error@+3{{SSE register return with SSE disabled}}
+ // expected-note@+2{{'f_ret1' defined here}}
+#endif
float f_ret1(float x) {
return 0.0f;
}
+#ifdef ERROR_NOSSE
+ // expected-note@+2{{'f_ret2' defined here}}
+#endif
float f_ret2(float x);
+#ifdef ERROR_NOSSE
+ // expected-error@+3{{SSE register return with SSE disabled}}
+#endif
int f_ret3(float x) {
return (int)f_ret2(x);
}
Index: clang/lib/Sema/Sema.cpp
===================================================================
--- clang/lib/Sema/Sema.cpp
+++ clang/lib/Sema/Sema.cpp
@@ -1957,15 +1957,7 @@
bool IsDouble = UnqualTy == Context.DoubleTy;
bool IsFloat = UnqualTy == Context.FloatTy;
if (IsRetTy && !TI.hasFPReturn() && (IsDouble || IsFloat)) {
- PartialDiagnostic PD = PDiag(diag::err_target_unsupported_type);
- if (D)
- PD << D;
- else
- PD << "expression";
-
- if (Diag(Loc, PD, FD)
- << false /*show bit size*/ << 0 << Ty << true /*return*/
- << Context.getTargetInfo().getTriple().str()) {
+ if (Diag(Loc, diag::err_target_unsupported_type_without_sse)) {
if (D)
D->setInvalidDecl();
}
Index: clang/lib/Basic/Targets/X86.cpp
===================================================================
--- clang/lib/Basic/Targets/X86.cpp
+++ clang/lib/Basic/Targets/X86.cpp
@@ -387,6 +387,9 @@
if (!HasX87 && LongDoubleFormat == &llvm::APFloat::x87DoubleExtended())
HasLongDouble = false;
+ if (SSELevel < SSE1 && getTriple().getArch() == llvm::Triple::x86_64)
+ HasFPReturn = false;
+
return true;
}
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10728,6 +10728,8 @@
def err_target_unsupported_type
: Error<"%0 requires %select{|%2 bit size}1 %3 %select{|return }4type support,"
" but target '%5' does not support it">;
+def err_target_unsupported_type_without_sse : Error<
+ "SSE register return with SSE disabled">;
def err_omp_lambda_capture_in_declare_target_not_to : Error<
"variable captured in declare target region must appear in a to clause">;
def err_omp_device_type_mismatch : Error<
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits