Index: clang/include/clang/AST/ASTContext.h =================================================================== --- clang/include/clang/AST/ASTContext.h +++ clang/include/clang/AST/ASTContext.h @@ -2065,8 +2065,10 @@ //===--------------------------------------------------------------------===// /// Return the APFloat 'semantics' for the specified scalar floating - /// point type. - const llvm::fltSemantics &getFloatTypeSemantics(QualType T) const; + /// point type. Get the semantics from the auxiliary target if one is + /// defined and \p PreferAuxTarget. + const llvm::fltSemantics &getFloatTypeSemantics( + QualType T, bool PreferAuxTarget = false) const; /// Get the size and alignment of the specified complete type in bits. TypeInfo getTypeInfo(const Type *T) const; Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -8512,6 +8512,8 @@ "feature, not permitted in C++">; def err_type_unsupported : Error< "%0 is not supported on this target">; +def err_type_not_equivalent : Error< + "%0 is not equivalent between host and target">; def err_nsconsumed_attribute_mismatch : Error< "overriding method has mismatched ns_consumed attribute on its" " parameter">; Index: clang/lib/AST/ASTContext.cpp =================================================================== --- clang/lib/AST/ASTContext.cpp +++ clang/lib/AST/ASTContext.cpp @@ -1515,18 +1515,20 @@ /// getFloatTypeSemantics - Return the APFloat 'semantics' for the specified /// scalar floating point type. -const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const { +const llvm::fltSemantics &ASTContext::getFloatTypeSemantics( + QualType T, bool PreferAuxTarget) const { + const TargetInfo *Tgt = PreferAuxTarget && AuxTarget ? AuxTarget : Target; const auto *BT = T->getAs(); assert(BT && "Not a floating point type!"); switch (BT->getKind()) { default: llvm_unreachable("Not a floating point type!"); case BuiltinType::Float16: case BuiltinType::Half: - return Target->getHalfFormat(); - case BuiltinType::Float: return Target->getFloatFormat(); - case BuiltinType::Double: return Target->getDoubleFormat(); - case BuiltinType::LongDouble: return Target->getLongDoubleFormat(); - case BuiltinType::Float128: return Target->getFloat128Format(); + return Tgt->getHalfFormat(); + case BuiltinType::Float: return Tgt->getFloatFormat(); + case BuiltinType::Double: return Tgt->getDoubleFormat(); + case BuiltinType::LongDouble: return Tgt->getLongDoubleFormat(); + case BuiltinType::Float128: return Tgt->getFloat128Format(); } } Index: clang/lib/Sema/SemaOpenMP.cpp =================================================================== --- clang/lib/Sema/SemaOpenMP.cpp +++ clang/lib/Sema/SemaOpenMP.cpp @@ -1588,13 +1588,23 @@ "OpenMP device compilation mode is expected."); QualType Ty = E->getType(); if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || - ((Ty->isFloat128Type() || - (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && - !Context.getTargetInfo().hasFloat128Type()) || + (Ty->isFloat128Type() && !Context.getTargetInfo().hasFloat128Type()) || (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && !Context.getTargetInfo().hasInt128Type())) targetDiag(E->getExprLoc(), diag::err_type_unsupported) << Ty << E->getSourceRange(); + if (Ty->isRealFloatingType()) { + llvm::APFloatBase::Semantics Sem = llvm::APFloatBase::SemanticsToEnum( + Context.getFloatTypeSemantics(Ty, /*PreferAuxTarget*/ true)); + const TargetInfo &TI = Context.getTargetInfo(); + if ((Ty->isFloat128Type() && + Sem != llvm::APFloatBase::SemanticsToEnum(TI.getFloat128Format())) || + (Ty.getUnqualifiedType() == Context.LongDoubleTy && + Sem != llvm::APFloatBase::SemanticsToEnum(TI.getLongDoubleFormat()))) + // TODO: Naming the floating point representations would be helpful. + targetDiag(E->getExprLoc(), diag::err_type_not_equivalent) + << Ty << E->getSourceRange(); + } } bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const { Index: clang/test/OpenMP/nvptx_unsupported_type_messages.cpp =================================================================== --- clang/test/OpenMP/nvptx_unsupported_type_messages.cpp +++ clang/test/OpenMP/nvptx_unsupported_type_messages.cpp @@ -1,8 +1,16 @@ // Test target codegen - host bc file has to be created first. -// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-linux -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-host.bc +// RUN: %clang_cc1 -verify=quiet -fopenmp -x c++ -triple x86_64-unknown-linux -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-host.bc // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -aux-triple x86_64-unknown-linux -fopenmp-targets=nvptx64-nvidia-cuda %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc -fsyntax-only -// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-linux-gnu -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-host.bc +// RUN: %clang_cc1 -verify=quiet -fopenmp -x c++ -triple powerpc64le-unknown-linux-gnu -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-host.bc // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -aux-triple powerpc64le-unknown-linux-gnu -fopenmp-targets=nvptx64-nvidia-cuda %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc -fsyntax-only +// +// Make sure this code does compile when the host and target are the same. +// RUN: %clang_cc1 -verify=quiet -fopenmp -x c++ -triple x86_64-unknown-linux -fopenmp-targets=x86_64-unknown-linux -emit-llvm-bc %s -o %t-host.bc +// RUN: %clang_cc1 -verify=quiet -fopenmp -x c++ -triple x86_64-unknown-linux -aux-triple x86_64-unknown-linux -fopenmp-targets=x86_64-unknown-linux %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc -fsyntax-only +// RUN: %clang_cc1 -verify=quiet -fopenmp -x c++ -triple powerpc64le-unknown-linux-gnu -fopenmp-targets=powerpc64le-unknown-linux-gnu -emit-llvm-bc %s -o %t-host.bc +// RUN: %clang_cc1 -verify=quiet -fopenmp -x c++ -triple powerpc64le-unknown-linux-gnu -aux-triple powerpc64le-unknown-linux-gnu -fopenmp-targets=powerpc64le-unknown-linux-gnu %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc -fsyntax-only + +// quiet-no-diagnostics struct T { char a; @@ -16,7 +24,7 @@ #ifndef _ARCH_PPC // expected-error@+4 {{'__float128' is not supported on this target}} #else -// expected-error@+2 {{'long double' is not supported on this target}} +// expected-error@+2 {{'long double' is not equivalent between host and target}} #endif T &operator+(T &b) { f += b.a; return *this;} };