summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorErich Keane <erich.keane@intel.com>2019-12-16 11:15:48 -0800
committerErich Keane <erich.keane@intel.com>2019-12-17 06:58:29 -0800
commit1ed832e42446ef8c4afe08f980db2e54ac316bf3 (patch)
tree934a6c57d2ac75076064041081cd1d78a021bf10 /clang/lib/Sema/SemaChecking.cpp
parentb852b3c982d2e8ad3f13c626b3e3655e5b3c399e (diff)
downloadbcm5719-llvm-1ed832e42446ef8c4afe08f980db2e54ac316bf3.tar.gz
bcm5719-llvm-1ed832e42446ef8c4afe08f980db2e54ac316bf3.zip
Reland [NFC-I] Remove hack for fp-classification builtins
The FP-classification builtins (__builtin_isfinite, etc) use variadic packs in the definition file to mean an overload set. Because of that, floats were converted to doubles, which is incorrect. There WAS a patch to remove the cast after the fact. THis patch switches these builtins to just be custom type checking, calls the implicit conversions for the integer members, and makes sure the correct L->R casts are put into place, then does type checking like normal. A future direction (that wouldn't be NFC) would consider making conversions for the floating point parameter legal. Note: The initial patch for this missed that certain systems need to still convert half to float, since they dont' support that type.
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp58
1 files changed, 24 insertions, 34 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 910afefffb6..cc091b27fe5 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -5797,51 +5797,41 @@ bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs) {
<< SourceRange(TheCall->getArg(NumArgs)->getBeginLoc(),
(*(TheCall->arg_end() - 1))->getEndLoc());
+ // __builtin_fpclassify is the only case where NumArgs != 1, so we can count
+ // on all preceding parameters just being int. Try all of those.
+ for (unsigned i = 0; i < NumArgs - 1; ++i) {
+ Expr *Arg = TheCall->getArg(i);
+
+ if (Arg->isTypeDependent())
+ return false;
+
+ ExprResult Res = PerformImplicitConversion(Arg, Context.IntTy, AA_Passing);
+
+ if (Res.isInvalid())
+ return true;
+ TheCall->setArg(i, Res.get());
+ }
+
Expr *OrigArg = TheCall->getArg(NumArgs-1);
if (OrigArg->isTypeDependent())
return false;
+ // Usual Unary Conversions will convert half to float, which we want for
+ // machines that use fp16 conversion intrinsics. Else, we wnat to leave the
+ // type how it is, but do normal L->Rvalue conversions.
+ if (Context.getTargetInfo().useFP16ConversionIntrinsics())
+ OrigArg = UsualUnaryConversions(OrigArg).get();
+ else
+ OrigArg = DefaultFunctionArrayLvalueConversion(OrigArg).get();
+ TheCall->setArg(NumArgs - 1, OrigArg);
+
// This operation requires a non-_Complex floating-point number.
if (!OrigArg->getType()->isRealFloatingType())
return Diag(OrigArg->getBeginLoc(),
diag::err_typecheck_call_invalid_unary_fp)
<< OrigArg->getType() << OrigArg->getSourceRange();
- // If this is an implicit conversion from float -> float, double, or
- // long double, or half -> half, float, double, or long double, remove it.
- if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(OrigArg)) {
- // Only remove standard FloatCasts, leaving other casts inplace
- if (Cast->getCastKind() == CK_FloatingCast) {
- bool IgnoreCast = false;
- Expr *CastArg = Cast->getSubExpr();
- if (CastArg->getType()->isSpecificBuiltinType(BuiltinType::Float)) {
- assert(
- (Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) ||
- Cast->getType()->isSpecificBuiltinType(BuiltinType::Float) ||
- Cast->getType()->isSpecificBuiltinType(BuiltinType::LongDouble)) &&
- "promotion from float to either float, double, or long double is "
- "the only expected cast here");
- IgnoreCast = true;
- } else if (CastArg->getType()->isSpecificBuiltinType(BuiltinType::Half) &&
- !Context.getTargetInfo().useFP16ConversionIntrinsics()) {
- assert(
- (Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) ||
- Cast->getType()->isSpecificBuiltinType(BuiltinType::Float) ||
- Cast->getType()->isSpecificBuiltinType(BuiltinType::Half) ||
- Cast->getType()->isSpecificBuiltinType(BuiltinType::LongDouble)) &&
- "promotion from half to either half, float, double, or long double "
- "is the only expected cast here");
- IgnoreCast = true;
- }
-
- if (IgnoreCast) {
- Cast->setSubExpr(nullptr);
- TheCall->setArg(NumArgs-1, CastArg);
- }
- }
- }
-
return false;
}
OpenPOWER on IntegriCloud