Skip to content
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

Merged
merged 8 commits into from
Jul 17, 2024

Conversation

zahiraam
Copy link
Contributor

@zahiraam zahiraam commented Jul 11, 2024

The pragma STDC CX_LIMITED_RANGE should have precedence over the command line -fcomplex-arithmetic.

@zahiraam zahiraam requested a review from andykaylor July 11, 2024 18:59
Copy link

github-actions bot commented Jul 11, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@zahiraam zahiraam changed the title The pragma STDC CX_LIMITED_RANGE ON should have precedence over The pragma STDC CX_LIMITED_RANGE ON should have precedence. Jul 11, 2024
// PRMTD-NEXT: fdiv double
// PRMTD-NEXT: fptrunc double {{.*}} to float
// PRMTD-NEXT: fptrunc double {{.*}} to float
// PRMTD: call{{.*}}float @llvm.fabs.f32(float {{.*}})
Copy link
Contributor

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).

Copy link
Contributor Author

@zahiraam zahiraam Jul 12, 2024

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.

@zahiraam zahiraam requested a review from andykaylor July 12, 2024 20:17
@zahiraam zahiraam marked this pull request as ready for review July 12, 2024 20:17
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen labels Jul 12, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Jul 12, 2024

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-codegen

Author: Zahira Ammarguellat (zahiraam)

Changes

The pragma STDC CX_LIMITED_RANGE should have precedence over the command line -fcomplex-arithmetic.


Full diff: https://github.com/llvm/llvm-project/pull/98520.diff

2 Files Affected:

  • (modified) clang/lib/CodeGen/CGExprComplex.cpp (+35-9)
  • (modified) clang/test/CodeGen/pragma-cx-limited-range.c (+12-16)
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;
 }

Comment on lines 335 to 341
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();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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();

@@ -347,6 +355,8 @@ class ComplexExprEmitter
#define HANDLEBINOP(OP) \
ComplexPairTy VisitBin##OP(const BinaryOperator *E) { \
QualType promotionTy = getPromotionType( \
(E->hasStoredFPFeatures() ? E->getStoredFPFeatures() \
Copy link
Collaborator

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?

@@ -344,10 +352,17 @@ class ComplexExprEmitter
return QualType();
}

template <typename T>
FPOptionsOverride getStoredFPFeaturesOrDefault(const T *E,
const CodeGenFunction &CGF) {
Copy link
Collaborator

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()?

Copy link
Contributor Author

@zahiraam zahiraam Jul 16, 2024

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.

@llvmbot llvmbot added the clang:frontend Language frontend issues, e.g. anything involving "Sema" label Jul 16, 2024
Copy link
Collaborator

@AaronBallman AaronBallman left a 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.

@zahiraam
Copy link
Contributor Author

Thanks @AaronBallman. I got thumbs up from @andykaylor offline. Merging this PR.

@zahiraam zahiraam merged commit 321a0c0 into llvm:main Jul 17, 2024
7 checks passed
sgundapa pushed a commit to sgundapa/upstream_effort that referenced this pull request Jul 23, 2024
The `pragma STDC CX_LIMITED_RANGE` should have precedence over the
command line `-fcomplex-arithmetic`.
yuxuanchen1997 pushed a commit that referenced this pull request Jul 25, 2024
The `pragma STDC CX_LIMITED_RANGE` should have precedence over the
command line `-fcomplex-arithmetic`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants