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 cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits