-
Notifications
You must be signed in to change notification settings - Fork 11.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The pragma STDC CX_LIMITED_RANGE ON should have precedence. #98520
Conversation
command line -fcomplex-arithmetic.
✅ With the latest revision this PR passed the C/C++ code formatter. |
// PRMTD-NEXT: fdiv double | ||
// PRMTD-NEXT: fptrunc double {{.*}} to float | ||
// PRMTD-NEXT: fptrunc double {{.*}} to float | ||
// PRMTD: call{{.*}}float @llvm.fabs.f32(float {{.*}}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we using the Smith algorithm in this case? I would have expected it to be the promoted implementation (as it was before this PR).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mmh! That's because I have added the condition !Features.hasComplexRangeOverride()
in getPromotionType
. It is set to true, so it jumps to the next condition. There is override here, except that the value of the range is equal to the LangOpts if the value of the pragma is DEFAULT
. I guess I need to check that the value of the override is not equal to the Range of the LangOpt .... Will fix that.
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-codegen Author: Zahira Ammarguellat (zahiraam) ChangesThe Full diff: https://github.com/llvm/llvm-project/pull/98520.diff 2 Files Affected:
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index 84ad3b566b647..de526a74b0f2d 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -328,12 +328,21 @@ class ComplexExprEmitter
}
}
- QualType getPromotionType(QualType Ty, bool IsDivOpCode = false) {
+ QualType getPromotionType(FPOptionsOverride Features, QualType Ty,
+ bool IsDivOpCode = false) {
if (auto *CT = Ty->getAs<ComplexType>()) {
QualType ElementType = CT->getElementType();
- if (IsDivOpCode && ElementType->isFloatingType() &&
- CGF.getLangOpts().getComplexRange() ==
- LangOptions::ComplexRangeKind::CX_Promoted)
+ bool isFloatingType = ElementType->isFloatingType();
+ bool isComplexRangePromoted = CGF.getLangOpts().getComplexRange() ==
+ LangOptions::ComplexRangeKind::CX_Promoted;
+ bool hasNoComplexRangeOverride = !Features.hasComplexRangeOverride();
+ bool hasMatchingComplexRange =
+ Features.hasComplexRangeOverride() &&
+ Features.getComplexRangeOverride() ==
+ CGF.getLangOpts().getComplexRange();
+
+ if (IsDivOpCode && isFloatingType && isComplexRangePromoted &&
+ (hasNoComplexRangeOverride || hasMatchingComplexRange))
return HigherPrecisionTypeForComplexArithmetic(ElementType,
IsDivOpCode);
if (ElementType.UseExcessPrecision(CGF.getContext()))
@@ -347,6 +356,8 @@ class ComplexExprEmitter
#define HANDLEBINOP(OP) \
ComplexPairTy VisitBin##OP(const BinaryOperator *E) { \
QualType promotionTy = getPromotionType( \
+ (E->hasStoredFPFeatures() ? E->getStoredFPFeatures() \
+ : FPOptionsOverride()), \
E->getType(), \
(E->getOpcode() == BinaryOperatorKind::BO_Div) ? true : false); \
ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy)); \
@@ -642,7 +653,10 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op,
ComplexPairTy ComplexExprEmitter::VisitUnaryPlus(const UnaryOperator *E,
QualType PromotionType) {
QualType promotionTy = PromotionType.isNull()
- ? getPromotionType(E->getSubExpr()->getType())
+ ? getPromotionType((E->hasStoredFPFeatures()
+ ? E->getStoredFPFeatures()
+ : FPOptionsOverride()),
+ E->getSubExpr()->getType())
: PromotionType;
ComplexPairTy result = VisitPlus(E, promotionTy);
if (!promotionTy.isNull())
@@ -662,7 +676,10 @@ ComplexPairTy ComplexExprEmitter::VisitPlus(const UnaryOperator *E,
ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E,
QualType PromotionType) {
QualType promotionTy = PromotionType.isNull()
- ? getPromotionType(E->getSubExpr()->getType())
+ ? getPromotionType((E->hasStoredFPFeatures()
+ ? E->getStoredFPFeatures()
+ : FPOptionsOverride()),
+ E->getSubExpr()->getType())
: PromotionType;
ComplexPairTy result = VisitMinus(E, promotionTy);
if (!promotionTy.isNull())
@@ -1223,13 +1240,19 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E,
// __block variables need to have the rhs evaluated first, plus this should
// improve codegen a little.
QualType PromotionTypeCR;
- PromotionTypeCR = getPromotionType(E->getComputationResultType());
+ PromotionTypeCR =
+ getPromotionType((E->hasStoredFPFeatures() ? E->getStoredFPFeatures()
+ : FPOptionsOverride()),
+ E->getComputationResultType());
if (PromotionTypeCR.isNull())
PromotionTypeCR = E->getComputationResultType();
OpInfo.Ty = PromotionTypeCR;
QualType ComplexElementTy =
OpInfo.Ty->castAs<ComplexType>()->getElementType();
- QualType PromotionTypeRHS = getPromotionType(E->getRHS()->getType());
+ QualType PromotionTypeRHS =
+ getPromotionType((E->hasStoredFPFeatures() ? E->getStoredFPFeatures()
+ : FPOptionsOverride()),
+ E->getRHS()->getType());
// The RHS should have been converted to the computation type.
if (E->getRHS()->getType()->isRealFloatingType()) {
@@ -1257,7 +1280,10 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E,
// Load from the l-value and convert it.
SourceLocation Loc = E->getExprLoc();
- QualType PromotionTypeLHS = getPromotionType(E->getComputationLHSType());
+ QualType PromotionTypeLHS =
+ getPromotionType((E->hasStoredFPFeatures() ? E->getStoredFPFeatures()
+ : FPOptionsOverride()),
+ E->getComputationLHSType());
if (LHSTy->isAnyComplexType()) {
ComplexPairTy LHSVal = EmitLoadOfLValue(LHS, Loc);
if (!PromotionTypeLHS.isNull())
diff --git a/clang/test/CodeGen/pragma-cx-limited-range.c b/clang/test/CodeGen/pragma-cx-limited-range.c
index 68615348c1871..1c9bf40fd714f 100644
--- a/clang/test/CodeGen/pragma-cx-limited-range.c
+++ b/clang/test/CodeGen/pragma-cx-limited-range.c
@@ -106,21 +106,17 @@ _Complex float pragma_on_div(_Complex float a, _Complex float b) {
// IMPRVD-NEXT: fdiv float
// IMPRVD-NEXT: fdiv float
- // PRMTD: fpext float {{.*}} to double
- // PRMTD: fpext float {{.*}} to double
- // PRMTD: fmul double
- // PRMTD: fmul double
- // PRMTD: fadd double
- // PRMTD: fmul double
- // PRMTD: fmul double
- // PRMTD: fadd double
- // PRMTD: fmul double
- // PRMTD: fmul double
- // PRMTD: fsub double
- // PRMTD: fdiv double
- // PRMTD: fdiv double
- // PRMTD: fptrunc double
- // PRMTD: fptrunc double
+ // PRMTD: fmul float
+ // PRMTD-NEXT: fmul float
+ // PRMTD-NEXT: fadd float
+ // PRMTD-NEXT: fmul float
+ // PRMTD-NEXT: fmul float
+ // PRMTD-NEXT: fadd float
+ // PRMTD-NEXT: fmul float
+ // PRMTD-NEXT: fmul float
+ // PRMTD-NEXT: fsub float
+ // PRMTD-NEXT: fdiv float
+ // PRMTD-NEXT: fdiv float
return a / b;
}
@@ -135,7 +131,7 @@ _Complex float pragma_off_div(_Complex float a, _Complex float b) {
// IMPRVD: call {{.*}} @__divsc3
- // PRMTD: call {{.*}} @__divdc3
+ // PRMTD: call {{.*}} @__divsc3
return a / b;
}
|
clang/lib/CodeGen/CGExprComplex.cpp
Outdated
bool isFloatingType = ElementType->isFloatingType(); | ||
bool isComplexRangePromoted = CGF.getLangOpts().getComplexRange() == | ||
LangOptions::ComplexRangeKind::CX_Promoted; | ||
bool hasNoComplexRangeOverride = !Features.hasComplexRangeOverride(); | ||
bool hasMatchingComplexRange = Features.hasComplexRangeOverride() && | ||
Features.getComplexRangeOverride() == | ||
CGF.getLangOpts().getComplexRange(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bool isFloatingType = ElementType->isFloatingType(); | |
bool isComplexRangePromoted = CGF.getLangOpts().getComplexRange() == | |
LangOptions::ComplexRangeKind::CX_Promoted; | |
bool hasNoComplexRangeOverride = !Features.hasComplexRangeOverride(); | |
bool hasMatchingComplexRange = Features.hasComplexRangeOverride() && | |
Features.getComplexRangeOverride() == | |
CGF.getLangOpts().getComplexRange(); | |
bool IsFloatingType = ElementType->isFloatingType(); | |
bool IsComplexRangePromoted = CGF.getLangOpts().getComplexRange() == | |
LangOptions::ComplexRangeKind::CX_Promoted; | |
bool HasNoComplexRangeOverride = !Features.hasComplexRangeOverride(); | |
bool HasMatchingComplexRange = Features.hasComplexRangeOverride() && | |
Features.getComplexRangeOverride() == | |
CGF.getLangOpts().getComplexRange(); |
clang/lib/CodeGen/CGExprComplex.cpp
Outdated
@@ -347,6 +355,8 @@ class ComplexExprEmitter | |||
#define HANDLEBINOP(OP) \ | |||
ComplexPairTy VisitBin##OP(const BinaryOperator *E) { \ | |||
QualType promotionTy = getPromotionType( \ | |||
(E->hasStoredFPFeatures() ? E->getStoredFPFeatures() \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This pattern comes up often enough, I wonder if we should add getStoredFPFeaturesOrDefault()
that does this dance for us?
clang/lib/CodeGen/CGExprComplex.cpp
Outdated
@@ -344,10 +352,17 @@ class ComplexExprEmitter | |||
return QualType(); | |||
} | |||
|
|||
template <typename T> | |||
FPOptionsOverride getStoredFPFeaturesOrDefault(const T *E, | |||
const CodeGenFunction &CGF) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CGF
is unused, can it be removed?
Why a template type? Everything is passing in some subclass of Expr
it seems.
Also, the function should be marked static
, but why not add it as a member function alongside getStoredFPFeatures()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Expr
doesn't have a hasStoredFPFeatures
or getSoreFpFeatures
. Ok. will add it as a member function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM assuming @andykaylor doesn't have any additional concerns.
Thanks @AaronBallman. I got thumbs up from @andykaylor offline. Merging this PR. |
The `pragma STDC CX_LIMITED_RANGE` should have precedence over the command line `-fcomplex-arithmetic`.
The `pragma STDC CX_LIMITED_RANGE` should have precedence over the command line `-fcomplex-arithmetic`.
The
pragma STDC CX_LIMITED_RANGE
should have precedence over the command line-fcomplex-arithmetic
.