qiucf updated this revision to Diff 392638.
qiucf marked 5 inline comments as done.
qiucf added a comment.

Update some cases


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D109751/new/

https://reviews.llvm.org/D109751

Files:
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/CodeGen/ibm128-cast.c
  clang/test/Sema/float128-ld-incompatibility.cpp

Index: clang/test/Sema/float128-ld-incompatibility.cpp
===================================================================
--- clang/test/Sema/float128-ld-incompatibility.cpp
+++ clang/test/Sema/float128-ld-incompatibility.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 \
 // RUN: -triple powerpc64le-unknown-linux-gnu -target-cpu pwr9 \
-// RUN: -target-feature +float128 %s
+// RUN: -Wno-unused-value -Wno-parentheses -target-feature +float128 %s
 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -triple x86_64-unknown-linux-gnu -Wno-unused-value -Wno-parentheses %s
 
 __float128 qf();
@@ -9,8 +9,9 @@
 #ifdef __PPC__
 // FIXME: once operations between long double and __float128 are implemented for
 //        targets where the types are different, these next two will change
-long double ld{qf()}; // expected-error {{cannot initialize a variable of type 'long double' with an rvalue of type '__float128'}}
-__float128 q{ldf()};  // expected-error {{cannot initialize a variable of type '__float128' with an rvalue of type 'long double'}}
+long double ld{qf()}; // expected-error {{non-constant-expression cannot be narrowed from type '__float128' to 'long double' in initializer list}} expected-note {{insert an explicit cast to silence this issue}}
+__float128 q{ldf()}; // expected-no-error
+__ibm128 w{ldf()}; // expected-no-error
 
 auto test1(__float128 q, long double ld) -> decltype(q + ld) { // expected-error {{invalid operands to binary expression ('__float128' and 'long double')}}
   return q + ld;      // expected-error {{invalid operands to binary expression ('__float128' and 'long double')}}
@@ -33,7 +34,9 @@
   q * ld; // expected-error {{invalid operands to binary expression ('__float128' and 'long double')}}
   ld / q; // expected-error {{invalid operands to binary expression ('long double' and '__float128')}}
   q / ld; // expected-error {{invalid operands to binary expression ('__float128' and 'long double')}}
-  ld = q; // expected-error {{assigning to 'long double' from incompatible type '__float128'}}
-  q = ld; // expected-error {{assigning to '__float128' from incompatible type 'long double'}}
+  ld = q; // expected-no-error {{assigning to 'long double' from incompatible type '__float128'}}
+  q = ld; // expected-no-error {{assigning to '__float128' from incompatible type 'long double'}}
   q + b ? q : ld; // expected-error {{incompatible operand types ('__float128' and 'long double')}}
+  q += ld; // expected-error {{invalid operands to binary expression ('__float128' and 'long double')}}
+  ld /= q; // expected-error {{invalid operands to binary expression ('long double' and '__float128')}}
 }
Index: clang/test/CodeGen/ibm128-cast.c
===================================================================
--- clang/test/CodeGen/ibm128-cast.c
+++ clang/test/CodeGen/ibm128-cast.c
@@ -2,11 +2,18 @@
 // RUN:   -target-feature +float128 -mabi=ieeelongdouble -fsyntax-only -Wno-unused %s
 // RUN: %clang_cc1 -emit-llvm -triple powerpc64le-unknown-unknown -verify \
 // RUN:   -target-feature +float128 -fsyntax-only -Wno-unused %s
+// RUN: %clang_cc1 -emit-llvm -triple powerpc64le-unknown-unknown -DCODEGEN \
+// RUN:   -target-feature +float128 -mabi=ieeelongdouble %s -o - | FileCheck %s
 
-__float128 cast1(__ibm128 x) { return x; } // expected-error {{returning '__ibm128' from a function with incompatible result type '__float128'}}
+// CHECK: define dso_local fp128 @cast1(ppc_fp128 %{{.+}})
+// CHECK: %{{.+}} = call fp128 @llvm.ppc.convert.ppcf128.to.f128(ppc_fp128 %{{.+}})
+__float128 cast1(__ibm128 x) { return x; } // expected-no-error
 
-__ibm128 cast2(__float128 x) { return x; } // expected-error {{returning '__float128' from a function with incompatible result type '__ibm128'}}
+// IEEE: define dso_local ppc_fp128 @cast2(fp128 %{{.+}})
+// IEEE: %{{.+}} = call ppc_fp128 @llvm.ppc.convert.f128.to.ppcf128(fp128 %{{.+}})
+__ibm128 cast2(__float128 x) { return x; } // expected-no-error
 
+#ifndef CODEGEN
 __ibm128 gf;
 
 void narrow(double *d, float *f) {
@@ -17,23 +24,25 @@
 }
 
 #ifdef __LONG_DOUBLE_IEEE128__
-long double cast3(__ibm128 x) { return x; } // expected-error {{returning '__ibm128' from a function with incompatible result type 'long double'}}
+long double cast3(__ibm128 x) { return x; } // expected-no-error
 
-__ibm128 cast4(long double x) { return x; } // expected-error {{returning 'long double' from a function with incompatible result type '__ibm128'}}
+__ibm128 cast4(long double x) { return x; } // expected-no-error
 
 void imp_cast(__ibm128 w, __float128 q, long double l, _Bool b) {
   w + q;      // expected-error {{invalid operands to binary expression ('__ibm128' and '__float128')}}
   l + w;      // expected-error {{invalid operands to binary expression ('long double' and '__ibm128')}}
   q - w;      // expected-error {{invalid operands to binary expression ('__float128' and '__ibm128')}}
   w - l;      // expected-error {{invalid operands to binary expression ('__ibm128' and 'long double')}}
-  w *l;       // expected-error {{invalid operands to binary expression ('__ibm128' and 'long double')}}
-  q *w;       // expected-error {{invalid operands to binary expression ('__float128' and '__ibm128')}}
+  w * l;      // expected-error {{invalid operands to binary expression ('__ibm128' and 'long double')}}
+  q * w;      // expected-error {{invalid operands to binary expression ('__float128' and '__ibm128')}}
   q / w;      // expected-error {{invalid operands to binary expression ('__float128' and '__ibm128')}}
   w / l;      // expected-error {{invalid operands to binary expression ('__ibm128' and 'long double')}}
-  w = q;      // expected-error {{assigning to '__ibm128' from incompatible type '__float128'}}
-  q = w;      // expected-error {{assigning to '__float128' from incompatible type '__ibm128'}}
-  l = w;      // expected-error {{assigning to 'long double' from incompatible type '__ibm128'}}
-  w = l;      // expected-error {{assigning to '__ibm128' from incompatible type 'long double'}}
+  w += q;     // expected-error {{invalid operands to binary expression ('__ibm128' and '__float128')}}
+  l += w;     // expected-error {{invalid operands to binary expression ('long double' and '__ibm128')}}
+  w = q;      // expected-no-error {{assigning to '__ibm128' from incompatible type '__float128'}}
+  q = w;      // expected-no-error {{assigning to '__float128' from incompatible type '__ibm128'}}
+  l = w;      // expected-no-error {{assigning to 'long double' from incompatible type '__ibm128'}}
+  w = l;      // expected-no-error {{assigning to '__ibm128' from incompatible type 'long double'}}
   b ? q : w;  // expected-error {{incompatible operand types ('__float128' and '__ibm128')}}
   !b ? w : l; // expected-error {{incompatible operand types ('__ibm128' and 'long double')}}
 }
@@ -47,15 +56,18 @@
   l + w;      // expected-no-error {{invalid operands to binary expression ('long double' and '__ibm128')}}
   q - w;      // expected-error {{invalid operands to binary expression ('__float128' and '__ibm128')}}
   w - l;      // expected-no-error {{invalid operands to binary expression ('__ibm128' and 'long double')}}
-  w *l;       // expected-no-error {{invalid operands to binary expression ('__ibm128' and 'long double')}}
-  q *w;       // expected-error {{invalid operands to binary expression ('__float128' and '__ibm128')}}
+  w * l;      // expected-no-error {{invalid operands to binary expression ('__ibm128' and 'long double')}}
+  q * w;      // expected-error {{invalid operands to binary expression ('__float128' and '__ibm128')}}
   q / w;      // expected-error {{invalid operands to binary expression ('__float128' and '__ibm128')}}
   w / l;      // expected-no-error {{invalid operands to binary expression ('__ibm128' and 'long double')}}
-  w = q;      // expected-error {{assigning to '__ibm128' from incompatible type '__float128'}}
-  q = w;      // expected-error {{assigning to '__float128' from incompatible type '__ibm128'}}
+  w += q;     // expected-error {{invalid operands to binary expression ('__ibm128' and '__float128')}}
+  q += l;     // expected-error {{invalid operands to binary expression ('__float128' and 'long double')}}
+  w = q;      // expected-no-error {{assigning to '__ibm128' from incompatible type '__float128'}}
+  q = w;      // expected-no-error {{assigning to '__float128' from incompatible type '__ibm128'}}
   l = w;      // expected-no-error {{assigning to 'long double' from incompatible type '__ibm128'}}
   w = l;      // expected-no-error {{assigning to '__ibm128' from incompatible type 'long double'}}
   b ? q : w;  // expected-error {{incompatible operand types ('__float128' and '__ibm128')}}
-  !b ? w : l; // expected-no-error {{incompatible operand types ('__ibm128' and 'long double')}}
+  !b ? w : l; // expected-no-error
 }
 #endif
+#endif
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -1869,25 +1869,10 @@
     SCS.Second = ICK_Complex_Real;
     FromType = ToType.getUnqualifiedType();
   } else if (FromType->isRealFloatingType() && ToType->isRealFloatingType()) {
-    // FIXME: disable conversions between long double, __ibm128 and __float128
-    // if their representation is different until there is back end support
-    // We of course allow this conversion if long double is really double.
-
     // Conversions between bfloat and other floats are not permitted.
     if (FromType == S.Context.BFloat16Ty || ToType == S.Context.BFloat16Ty)
       return false;
 
-    // Conversions between IEEE-quad and IBM-extended semantics are not
-    // permitted.
-    const llvm::fltSemantics &FromSem =
-        S.Context.getFloatTypeSemantics(FromType);
-    const llvm::fltSemantics &ToSem = S.Context.getFloatTypeSemantics(ToType);
-    if ((&FromSem == &llvm::APFloat::PPCDoubleDouble() &&
-         &ToSem == &llvm::APFloat::IEEEquad()) ||
-        (&FromSem == &llvm::APFloat::IEEEquad() &&
-         &ToSem == &llvm::APFloat::PPCDoubleDouble()))
-      return false;
-
     // Floating point conversions (C++ 4.8).
     SCS.Second = ICK_Floating_Conversion;
     FromType = ToType.getUnqualifiedType();
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -1537,7 +1537,7 @@
   // At this point, we have two different arithmetic types.
 
   // Diagnose attempts to convert between __ibm128, __float128 and long double
-  // where such conversions currently can't be handled.
+  // unless it's explicit or in simple assignment.
   if (unsupportedTypeConversion(*this, LHSType, RHSType))
     return QualType();
 
@@ -9305,11 +9305,6 @@
     return Incompatible;
   }
 
-  // Diagnose attempts to convert between __ibm128, __float128 and long double
-  // where such conversions currently can't be handled.
-  if (unsupportedTypeConversion(*this, LHSType, RHSType))
-    return Incompatible;
-
   // Disallow assigning a _Complex to a real type in C++ mode since it simply
   // discards the imaginary part.
   if (getLangOpts().CPlusPlus && RHSType->getAs<ComplexType>() &&
Index: clang/lib/CodeGen/CGExprScalar.cpp
===================================================================
--- clang/lib/CodeGen/CGExprScalar.cpp
+++ clang/lib/CodeGen/CGExprScalar.cpp
@@ -1330,6 +1330,22 @@
     }
   }
 
+  if (SrcType->isFloatingType() && DstType->isFloatingType()) {
+    // Handle cast between PPC double-double and IEEE 128-bit float types.
+    const auto *SrcSemantics = &CGF.getContext().getFloatTypeSemantics(SrcType);
+    const auto *DstSemantics = &CGF.getContext().getFloatTypeSemantics(DstType);
+    if (SrcSemantics == &llvm::APFloat::PPCDoubleDouble() &&
+        DstSemantics == &llvm::APFloat::IEEEquad())
+      return Builder.CreateCall(
+          CGF.CGM.getIntrinsic(llvm::Intrinsic::ppc_convert_ppcf128_to_f128),
+          Src);
+    if (SrcSemantics == &llvm::APFloat::IEEEquad() &&
+        DstSemantics == &llvm::APFloat::PPCDoubleDouble())
+      return Builder.CreateCall(
+          CGF.CGM.getIntrinsic(llvm::Intrinsic::ppc_convert_f128_to_ppcf128),
+          Src);
+  }
+
   // Ignore conversions like int -> uint.
   if (SrcTy == DstTy) {
     if (Opts.EmitImplicitIntegerSignChangeChecks)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to