Skip to content

Commit 321a0c0

Browse files
authored
The pragma STDC CX_LIMITED_RANGE ON should have precedence. (#98520)
The `pragma STDC CX_LIMITED_RANGE` should have precedence over the command line `-fcomplex-arithmetic`.
1 parent e3b8d36 commit 321a0c0

File tree

4 files changed

+66
-30
lines changed

4 files changed

+66
-30
lines changed

clang/include/clang/AST/Expr.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2333,6 +2333,11 @@ class UnaryOperator final
23332333
return getTrailingFPFeatures();
23342334
}
23352335

2336+
/// Get the store FPOptionsOverride or default if not stored.
2337+
FPOptionsOverride getStoredFPFeaturesOrDefault() const {
2338+
return hasStoredFPFeatures() ? getStoredFPFeatures() : FPOptionsOverride();
2339+
}
2340+
23362341
protected:
23372342
/// Set FPFeatures in trailing storage, used by Serialization & ASTImporter.
23382343
void setStoredFPFeatures(FPOptionsOverride F) { getTrailingFPFeatures() = F; }
@@ -3096,6 +3101,11 @@ class CallExpr : public Expr {
30963101
*getTrailingFPFeatures() = F;
30973102
}
30983103

3104+
/// Get the store FPOptionsOverride or default if not stored.
3105+
FPOptionsOverride getStoredFPFeaturesOrDefault() const {
3106+
return hasStoredFPFeatures() ? getStoredFPFeatures() : FPOptionsOverride();
3107+
}
3108+
30993109
/// Get the FP features status of this operator. Only meaningful for
31003110
/// operations on floating point types.
31013111
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
@@ -3592,6 +3602,11 @@ class CastExpr : public Expr {
35923602
return *getTrailingFPFeatures();
35933603
}
35943604

3605+
/// Get the store FPOptionsOverride or default if not stored.
3606+
FPOptionsOverride getStoredFPFeaturesOrDefault() const {
3607+
return hasStoredFPFeatures() ? getStoredFPFeatures() : FPOptionsOverride();
3608+
}
3609+
35953610
/// Get the FP features status of this operation. Only meaningful for
35963611
/// operations on floating point types.
35973612
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
@@ -4038,6 +4053,10 @@ class BinaryOperator : public Expr {
40384053
assert(BinaryOperatorBits.HasFPFeatures);
40394054
*getTrailingFPFeatures() = F;
40404055
}
4056+
/// Get the store FPOptionsOverride or default if not stored.
4057+
FPOptionsOverride getStoredFPFeaturesOrDefault() const {
4058+
return hasStoredFPFeatures() ? getStoredFPFeatures() : FPOptionsOverride();
4059+
}
40414060

40424061
/// Get the FP features status of this operator. Only meaningful for
40434062
/// operations on floating point types.

clang/include/clang/AST/Stmt.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,6 +1658,11 @@ class CompoundStmt final
16581658
return *getTrailingObjects<FPOptionsOverride>();
16591659
}
16601660

1661+
/// Get the store FPOptionsOverride or default if not stored.
1662+
FPOptionsOverride getStoredFPFeaturesOrDefault() const {
1663+
return hasStoredFPFeatures() ? getStoredFPFeatures() : FPOptionsOverride();
1664+
}
1665+
16611666
using body_iterator = Stmt **;
16621667
using body_range = llvm::iterator_range<body_iterator>;
16631668

clang/lib/CodeGen/CGExprComplex.cpp

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -328,12 +328,20 @@ class ComplexExprEmitter
328328
}
329329
}
330330

331-
QualType getPromotionType(QualType Ty, bool IsDivOpCode = false) {
331+
QualType getPromotionType(FPOptionsOverride Features, QualType Ty,
332+
bool IsDivOpCode = false) {
332333
if (auto *CT = Ty->getAs<ComplexType>()) {
333334
QualType ElementType = CT->getElementType();
334-
if (IsDivOpCode && ElementType->isFloatingType() &&
335-
CGF.getLangOpts().getComplexRange() ==
336-
LangOptions::ComplexRangeKind::CX_Promoted)
335+
bool IsFloatingType = ElementType->isFloatingType();
336+
bool IsComplexRangePromoted = CGF.getLangOpts().getComplexRange() ==
337+
LangOptions::ComplexRangeKind::CX_Promoted;
338+
bool HasNoComplexRangeOverride = !Features.hasComplexRangeOverride();
339+
bool HasMatchingComplexRange = Features.hasComplexRangeOverride() &&
340+
Features.getComplexRangeOverride() ==
341+
CGF.getLangOpts().getComplexRange();
342+
343+
if (IsDivOpCode && IsFloatingType && IsComplexRangePromoted &&
344+
(HasNoComplexRangeOverride || HasMatchingComplexRange))
337345
return HigherPrecisionTypeForComplexArithmetic(ElementType,
338346
IsDivOpCode);
339347
if (ElementType.UseExcessPrecision(CGF.getContext()))
@@ -347,7 +355,7 @@ class ComplexExprEmitter
347355
#define HANDLEBINOP(OP) \
348356
ComplexPairTy VisitBin##OP(const BinaryOperator *E) { \
349357
QualType promotionTy = getPromotionType( \
350-
E->getType(), \
358+
E->getStoredFPFeaturesOrDefault(), E->getType(), \
351359
(E->getOpcode() == BinaryOperatorKind::BO_Div) ? true : false); \
352360
ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy)); \
353361
if (!promotionTy.isNull()) \
@@ -641,9 +649,12 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op,
641649

642650
ComplexPairTy ComplexExprEmitter::VisitUnaryPlus(const UnaryOperator *E,
643651
QualType PromotionType) {
644-
QualType promotionTy = PromotionType.isNull()
645-
? getPromotionType(E->getSubExpr()->getType())
646-
: PromotionType;
652+
E->hasStoredFPFeatures();
653+
QualType promotionTy =
654+
PromotionType.isNull()
655+
? getPromotionType(E->getStoredFPFeaturesOrDefault(),
656+
E->getSubExpr()->getType())
657+
: PromotionType;
647658
ComplexPairTy result = VisitPlus(E, promotionTy);
648659
if (!promotionTy.isNull())
649660
return CGF.EmitUnPromotedValue(result, E->getSubExpr()->getType());
@@ -661,9 +672,11 @@ ComplexPairTy ComplexExprEmitter::VisitPlus(const UnaryOperator *E,
661672

662673
ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E,
663674
QualType PromotionType) {
664-
QualType promotionTy = PromotionType.isNull()
665-
? getPromotionType(E->getSubExpr()->getType())
666-
: PromotionType;
675+
QualType promotionTy =
676+
PromotionType.isNull()
677+
? getPromotionType(E->getStoredFPFeaturesOrDefault(),
678+
E->getSubExpr()->getType())
679+
: PromotionType;
667680
ComplexPairTy result = VisitMinus(E, promotionTy);
668681
if (!promotionTy.isNull())
669682
return CGF.EmitUnPromotedValue(result, E->getSubExpr()->getType());
@@ -1218,13 +1231,15 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E,
12181231
// __block variables need to have the rhs evaluated first, plus this should
12191232
// improve codegen a little.
12201233
QualType PromotionTypeCR;
1221-
PromotionTypeCR = getPromotionType(E->getComputationResultType());
1234+
PromotionTypeCR = getPromotionType(E->getStoredFPFeaturesOrDefault(),
1235+
E->getComputationResultType());
12221236
if (PromotionTypeCR.isNull())
12231237
PromotionTypeCR = E->getComputationResultType();
12241238
OpInfo.Ty = PromotionTypeCR;
12251239
QualType ComplexElementTy =
12261240
OpInfo.Ty->castAs<ComplexType>()->getElementType();
1227-
QualType PromotionTypeRHS = getPromotionType(E->getRHS()->getType());
1241+
QualType PromotionTypeRHS = getPromotionType(
1242+
E->getStoredFPFeaturesOrDefault(), E->getRHS()->getType());
12281243

12291244
// The RHS should have been converted to the computation type.
12301245
if (E->getRHS()->getType()->isRealFloatingType()) {
@@ -1252,7 +1267,8 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E,
12521267

12531268
// Load from the l-value and convert it.
12541269
SourceLocation Loc = E->getExprLoc();
1255-
QualType PromotionTypeLHS = getPromotionType(E->getComputationLHSType());
1270+
QualType PromotionTypeLHS = getPromotionType(
1271+
E->getStoredFPFeaturesOrDefault(), E->getComputationLHSType());
12561272
if (LHSTy->isAnyComplexType()) {
12571273
ComplexPairTy LHSVal = EmitLoadOfLValue(LHS, Loc);
12581274
if (!PromotionTypeLHS.isNull())

clang/test/CodeGen/pragma-cx-limited-range.c

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -106,21 +106,17 @@ _Complex float pragma_on_div(_Complex float a, _Complex float b) {
106106
// IMPRVD-NEXT: fdiv float
107107
// IMPRVD-NEXT: fdiv float
108108

109-
// PRMTD: fpext float {{.*}} to double
110-
// PRMTD: fpext float {{.*}} to double
111-
// PRMTD: fmul double
112-
// PRMTD: fmul double
113-
// PRMTD: fadd double
114-
// PRMTD: fmul double
115-
// PRMTD: fmul double
116-
// PRMTD: fadd double
117-
// PRMTD: fmul double
118-
// PRMTD: fmul double
119-
// PRMTD: fsub double
120-
// PRMTD: fdiv double
121-
// PRMTD: fdiv double
122-
// PRMTD: fptrunc double
123-
// PRMTD: fptrunc double
109+
// PRMTD: fmul float
110+
// PRMTD-NEXT: fmul float
111+
// PRMTD-NEXT: fadd float
112+
// PRMTD-NEXT: fmul float
113+
// PRMTD-NEXT: fmul float
114+
// PRMTD-NEXT: fadd float
115+
// PRMTD-NEXT: fmul float
116+
// PRMTD-NEXT: fmul float
117+
// PRMTD-NEXT: fsub float
118+
// PRMTD-NEXT: fdiv float
119+
// PRMTD-NEXT: fdiv float
124120

125121
return a / b;
126122
}
@@ -135,7 +131,7 @@ _Complex float pragma_off_div(_Complex float a, _Complex float b) {
135131

136132
// IMPRVD: call {{.*}} @__divsc3
137133

138-
// PRMTD: call {{.*}} @__divdc3
134+
// PRMTD: call {{.*}} @__divsc3
139135

140136
return a / b;
141137
}

0 commit comments

Comments
 (0)