Skip to content

Commit

Permalink
[FPEnv] Use strictfp metadata in casting nodes
Browse files Browse the repository at this point in the history
The strictfp metadata was added to the casting AST nodes in D85960, but
we aren't using that metadata yet. This patch adds that support.

In order to avoid lots of ad-hoc passing around of the strictfp bits I
updated the IRBuilder when moving from a function that has the Expr* to a
function that lacks it. I believe we should switch to this pattern to keep
the strictfp support from being overly invasive.

For the purpose of testing that we're picking up the right metadata, I
also made my tests use a pragma to make the AST's strictfp metadata not
match the global strictfp metadata. This exposes issues that we need to
deal with in subsequent patches, and I believe this is the right method
for most all of our clang strictfp tests.

Differential Revision: https://reviews.llvm.org/D88913
  • Loading branch information
kpneal committed Nov 6, 2020
1 parent d0b8810 commit 2069403
Show file tree
Hide file tree
Showing 13 changed files with 1,058 additions and 36 deletions.
1 change: 1 addition & 0 deletions clang/lib/CodeGen/CGExpr.cpp
Expand Up @@ -187,6 +187,7 @@ llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) {

QualType BoolTy = getContext().BoolTy;
SourceLocation Loc = E->getExprLoc();
CGFPOptionsRAII FPOptsRAII(*this, E);
if (!E->getType()->isAnyComplexType())
return EmitScalarConversion(EmitScalarExpr(E), E->getType(), BoolTy, Loc);

Expand Down
9 changes: 7 additions & 2 deletions clang/lib/CodeGen/CGExprComplex.cpp
Expand Up @@ -536,17 +536,21 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op,
llvm_unreachable("invalid cast kind for complex value");

case CK_FloatingRealToComplex:
case CK_IntegralRealToComplex:
case CK_IntegralRealToComplex: {
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op);
return EmitScalarToComplexCast(CGF.EmitScalarExpr(Op), Op->getType(),
DestTy, Op->getExprLoc());
}

case CK_FloatingComplexCast:
case CK_FloatingComplexToIntegralComplex:
case CK_IntegralComplexCast:
case CK_IntegralComplexToFloatingComplex:
case CK_IntegralComplexToFloatingComplex: {
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op);
return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy,
Op->getExprLoc());
}
}

llvm_unreachable("unknown cast resulting in complex value");
}
Expand Down Expand Up @@ -900,6 +904,7 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E,
if (const AtomicType *AT = LHSTy->getAs<AtomicType>())
LHSTy = AT->getValueType();

CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
BinOpInfo OpInfo;

// Load the RHS and LHS operands.
Expand Down
8 changes: 6 additions & 2 deletions clang/lib/CodeGen/CGExprScalar.cpp
Expand Up @@ -2235,9 +2235,11 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
case CK_FloatingToIntegral:
case CK_FloatingCast:
case CK_FixedPointToFloating:
case CK_FloatingToFixedPoint:
case CK_FloatingToFixedPoint: {
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
return EmitScalarConversion(Visit(E), E->getType(), DestTy,
CE->getExprLoc());
}
case CK_BooleanToSignedIntegral: {
ScalarConversionOpts Opts;
Opts.TreatBooleanAsSigned = true;
Expand All @@ -2248,8 +2250,10 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
return EmitIntToBoolConversion(Visit(E));
case CK_PointerToBoolean:
return EmitPointerToBoolConversion(Visit(E), E->getType());
case CK_FloatingToBoolean:
case CK_FloatingToBoolean: {
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
return EmitFloatToBoolConversion(Visit(E));
}
case CK_MemberPointerToBoolean: {
llvm::Value *MemPtr = Visit(E);
const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>();
Expand Down
19 changes: 18 additions & 1 deletion clang/lib/CodeGen/CodeGenFunction.cpp
Expand Up @@ -25,6 +25,7 @@
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Expr.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
#include "clang/Basic/Builtins.h"
Expand Down Expand Up @@ -130,11 +131,25 @@ void CodeGenFunction::SetFastMathFlags(FPOptions FPFeatures) {
Builder.setFastMathFlags(FMF);
}

CodeGenFunction::CGFPOptionsRAII::CGFPOptionsRAII(CodeGenFunction &CGF,
const Expr *E)
: CGF(CGF) {
ConstructorHelper(E->getFPFeaturesInEffect(CGF.getLangOpts()));
}

CodeGenFunction::CGFPOptionsRAII::CGFPOptionsRAII(CodeGenFunction &CGF,
FPOptions FPFeatures)
: CGF(CGF), OldFPFeatures(CGF.CurFPFeatures) {
: CGF(CGF) {
ConstructorHelper(FPFeatures);
}

void CodeGenFunction::CGFPOptionsRAII::ConstructorHelper(FPOptions FPFeatures) {
OldFPFeatures = CGF.CurFPFeatures;
CGF.CurFPFeatures = FPFeatures;

OldExcept = CGF.Builder.getDefaultConstrainedExcept();
OldRounding = CGF.Builder.getDefaultConstrainedRounding();

if (OldFPFeatures == FPFeatures)
return;

Expand Down Expand Up @@ -175,6 +190,8 @@ CodeGenFunction::CGFPOptionsRAII::CGFPOptionsRAII(CodeGenFunction &CGF,

CodeGenFunction::CGFPOptionsRAII::~CGFPOptionsRAII() {
CGF.CurFPFeatures = OldFPFeatures;
CGF.Builder.setDefaultConstrainedExcept(OldExcept);
CGF.Builder.setDefaultConstrainedRounding(OldRounding);
}

LValue CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) {
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/CodeGen/CodeGenFunction.h
Expand Up @@ -628,11 +628,15 @@ class CodeGenFunction : public CodeGenTypeCache {
class CGFPOptionsRAII {
public:
CGFPOptionsRAII(CodeGenFunction &CGF, FPOptions FPFeatures);
CGFPOptionsRAII(CodeGenFunction &CGF, const Expr *E);
~CGFPOptionsRAII();

private:
void ConstructorHelper(FPOptions FPFeatures);
CodeGenFunction &CGF;
FPOptions OldFPFeatures;
llvm::fp::ExceptionBehavior OldExcept;
llvm::RoundingMode OldRounding;
Optional<CGBuilderTy::FastMathFlagGuard> FMFGuard;
};
FPOptions CurFPFeatures;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaExpr.cpp
Expand Up @@ -697,7 +697,7 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
// If T is cv std::nullptr_t, the result is a null pointer constant.
CastKind CK = T->isNullPtrType() ? CK_NullToPointer : CK_LValueToRValue;
Res = ImplicitCastExpr::Create(Context, T, CK, E, nullptr, VK_RValue,
FPOptionsOverride());
CurFPFeatureOverrides());

// C11 6.3.2.1p2:
// ... if the lvalue has atomic type, the value has the non-atomic version
Expand Down

0 comments on commit 2069403

Please sign in to comment.