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.

We should match GCC's behavior which allows floating-point type for -mno-x87 
option on 32-bits. https://godbolt.org/z/KrbhfWc9o

The previous block issues have partially been fixed by D112143 
<https://reviews.llvm.org/D112143>.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D114162

Files:
  clang/lib/Basic/Targets/X86.cpp
  clang/test/Sema/x86-no-x87.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
+++ /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 <typename T>
-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);
-}
Index: clang/test/Sema/x86-no-x87.cpp
===================================================================
--- clang/test/Sema/x86-no-x87.cpp
+++ 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);
 }
Index: clang/lib/Basic/Targets/X86.cpp
===================================================================
--- clang/lib/Basic/Targets/X86.cpp
+++ 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;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to