diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -382,12 +382,9 @@ SimdDefaultAlign = hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128; - if (!HasX87) { - if (LongDoubleFormat == &llvm::APFloat::x87DoubleExtended()) - HasLongDouble = false; - if (getTriple().getArch() == llvm::Triple::x86) - HasFPReturn = false; - } + if (!HasX87 && getTriple().getArch() == llvm::Triple::x86_64 && + LongDoubleFormat == &llvm::APFloat::x87DoubleExtended()) + HasLongDouble = false; return true; } diff --git a/clang/test/Sema/x86-no-x87.cpp b/clang/test/Sema/x86-no-x87.cpp --- a/clang/test/Sema/x86-no-x87.cpp +++ b/clang/test/Sema/x86-no-x87.cpp @@ -1,5 +1,6 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -triple i686-linux-gnu -target-feature -x87 -DRET_ERROR -// RUN: %clang_cc1 -fsyntax-only -verify %s -triple i686-linux-gnu -DNOERROR +// 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 -DNOERROR +// RUN: %clang_cc1 -fsyntax-only -verify %s -triple i686-linux-gnu -target-feature -x87 -DNOERROR #ifdef NOERROR // expected-no-diagnostics @@ -19,13 +20,13 @@ float decl_ld_del(float) = delete; #ifndef NOERROR -// expected-error@+4{{'def' requires 'long_double' (aka 'long double') type support, but target 'i686-unknown-linux-gnu' does not support it}} +// 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 -// expected-error@+2{{'x' requires 'long_double' (aka 'long double') type support, but target 'i686-unknown-linux-gnu' does not support it}} +// 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; } @@ -38,7 +39,7 @@ int call1(float x, float y) { #ifndef NOERROR - // expected-error@+2 2{{'ld_args' requires 'long_double' (aka 'long double') type support, but target 'i686-unknown-linux-gnu' does not support it}} + // 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); } @@ -50,14 +51,14 @@ int call2(float x, float y) { #ifndef NOERROR - // expected-error@+2{{'ld_ret' requires 'long_double' (aka 'long double') type support, but target 'i686-unknown-linux-gnu' does not support it}} + // 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 - // expected-error@+2 2{{expression requires 'long_double' (aka 'long double') type support, but target 'i686-unknown-linux-gnu' does not support it}} + // 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; return (int)z; @@ -65,7 +66,7 @@ void assign1(long_double *ret, double x) { #ifndef NOERROR - // expected-error@+2{{expression requires 'long_double' (aka 'long double') type support, but target 'i686-unknown-linux-gnu' does not support it}} + // 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; } @@ -94,8 +95,8 @@ void assign2() { struct st_long_double1 st; #ifndef NOERROR - // expected-error@+3{{expression requires 'long_double' (aka 'long double') type support, but target 'i686-unknown-linux-gnu' does not support it}} - // expected-error@+2{{'ld' requires 'long_double' (aka 'long double') type support, but target 'i686-unknown-linux-gnu' does not support it}} + // 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 st.ld = 0.42; } @@ -103,8 +104,8 @@ void assign3() { struct st_long_double2 st; #ifndef NOERROR - // expected-error@+3{{expression requires 'long_double' (aka 'long double') type support, but target 'i686-unknown-linux-gnu' does not support it}} - // expected-error@+2{{'ld' requires 'long_double' (aka 'long double') type support, but target 'i686-unknown-linux-gnu' does not support it}} + // 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 st.ld = 42; } @@ -112,8 +113,8 @@ void assign4(double d) { struct st_long_double3 st; #ifndef NOERROR - // expected-error@+3{{expression requires 'long_double' (aka 'long double') type support, but target 'i686-unknown-linux-gnu' does not support it}} - // expected-error@+2{{'ld' requires 'long_double' (aka 'long double') type support, but target 'i686-unknown-linux-gnu' does not support it}} + // 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 st.ld = d; } @@ -123,42 +124,23 @@ long_double ld = 0.42; } -#ifndef NOERROR -// expected-note@+3{{'d_ret1' defined here}} -// expected-error@+2{{'d_ret1' requires 'double' return type support, but target 'i686-unknown-linux-gnu' does not support it}} -#endif +// Double and Float return type on x86_64 do not use x87 registers double d_ret1(float x) { return 0.0; } -#ifndef NOERROR -// expected-note@+2{{'d_ret2' defined here}} -#endif double d_ret2(float x); int d_ret3(float x) { -#ifndef NOERROR - // expected-error@+2{{'d_ret2' requires 'double' return type support, but target 'i686-unknown-linux-gnu' does not support it}} -#endif return (int)d_ret2(x); } -#ifndef NOERROR -// expected-note@+3{{'f_ret1' defined here}} -// expected-error@+2{{'f_ret1' requires 'float' return type support, but target 'i686-unknown-linux-gnu' does not support it}} -#endif float f_ret1(float x) { return 0.0f; } -#ifndef NOERROR -// expected-note@+2{{'f_ret2' defined here}} -#endif float f_ret2(float x); int f_ret3(float x) { -#ifndef NOERROR - // expected-error@+2{{'f_ret2' requires 'float' return type support, but target 'i686-unknown-linux-gnu' does not support it}} -#endif return (int)f_ret2(x); } diff --git a/clang/test/Sema/x86_64-no-x87.cpp b/clang/test/Sema/x86_64-no-x87.cpp deleted file mode 100644 --- a/clang/test/Sema/x86_64-no-x87.cpp +++ /dev/null @@ -1,145 +0,0 @@ -// 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 -DNOERROR - -#ifdef NOERROR -// expected-no-diagnostics -#endif - -typedef long double long_double; - -// Declaration is fine, unless it is called or defined. -double decl(long_double x, long_double y); - -template -T decl_ld_del(T); - -// No code is generated for deleted functions -long_double decl_ld_del(long_double) = delete; -double decl_ld_del(double) = delete; -float decl_ld_del(float) = delete; - -#ifndef NOERROR -// 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 -// 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 -// 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 - // 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 -// expected-note@+2{{'ld_ret' defined here}} -#endif -long_double ld_ret(double x, double y); - -int call2(float x, float y) { -#ifndef NOERROR - // 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 - // 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; - return (int)z; -} - -void assign1(long_double *ret, double x) { -#ifndef NOERROR - // 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 - // expected-note@+2{{'ld' defined here}} -#endif - long_double ld; -}; - -struct st_long_double2 { -#ifndef NOERROR - // expected-note@+2{{'ld' defined here}} -#endif - long_double ld; -}; - -struct st_long_double3 { -#ifndef NOERROR - // expected-note@+2{{'ld' defined here}} -#endif - long_double ld; -}; - -void assign2() { - struct st_long_double1 st; -#ifndef NOERROR - // 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 - st.ld = 0.42; -} - -void assign3() { - struct st_long_double2 st; -#ifndef NOERROR - // 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 - st.ld = 42; -} - -void assign4(double d) { - struct st_long_double3 st; -#ifndef NOERROR - // 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 - st.ld = d; -} - -void assign5() { - // unused variable declaration is fine - long_double ld = 0.42; -} - -// Double and Float return type on x86_64 do not use x87 registers -double d_ret1(float x) { - return 0.0; -} - -double d_ret2(float x); - -int d_ret3(float x) { - return (int)d_ret2(x); -} - -float f_ret1(float x) { - return 0.0f; -} - -float f_ret2(float x); - -int f_ret3(float x) { - return (int)f_ret2(x); -}