jdenny updated this revision to Diff 208286.
jdenny added a comment.
This incorporates all the improvements I think we've discussed so far:
- In diagnostics, distinguish between unsupported types and non-equivalent
types.
- Don't treat `__float128` and `long double` as equivalent.
- Compare exact floating point representation instead of just size.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D64289/new/
https://reviews.llvm.org/D64289
Files:
clang/include/clang/AST/ASTContext.h
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/AST/ASTContext.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/test/OpenMP/nvptx_unsupported_type_messages.cpp
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;}
};
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/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<BuiltinType>();
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/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/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;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits