[clang] 321a0c0 - The pragma STDC CX_LIMITED_RANGE ON should have precedence. (#98520)

via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 17 11:05:54 PDT 2024


Author: Zahira Ammarguellat
Date: 2024-07-17T14:05:51-04:00
New Revision: 321a0c00425adeab84bce657cac85ae4634df910

URL: https://github.com/llvm/llvm-project/commit/321a0c00425adeab84bce657cac85ae4634df910
DIFF: https://github.com/llvm/llvm-project/commit/321a0c00425adeab84bce657cac85ae4634df910.diff

LOG: 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`.

Added: 
    

Modified: 
    clang/include/clang/AST/Expr.h
    clang/include/clang/AST/Stmt.h
    clang/lib/CodeGen/CGExprComplex.cpp
    clang/test/CodeGen/pragma-cx-limited-range.c

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index a8add9d1337c6..5b813bfc2faf9 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -2333,6 +2333,11 @@ class UnaryOperator final
     return getTrailingFPFeatures();
   }
 
+  /// Get the store FPOptionsOverride or default if not stored.
+  FPOptionsOverride getStoredFPFeaturesOrDefault() const {
+    return hasStoredFPFeatures() ? getStoredFPFeatures() : FPOptionsOverride();
+  }
+
 protected:
   /// Set FPFeatures in trailing storage, used by Serialization & ASTImporter.
   void setStoredFPFeatures(FPOptionsOverride F) { getTrailingFPFeatures() = F; }
@@ -3096,6 +3101,11 @@ class CallExpr : public Expr {
     *getTrailingFPFeatures() = F;
   }
 
+  /// Get the store FPOptionsOverride or default if not stored.
+  FPOptionsOverride getStoredFPFeaturesOrDefault() const {
+    return hasStoredFPFeatures() ? getStoredFPFeatures() : FPOptionsOverride();
+  }
+
   /// Get the FP features status of this operator. Only meaningful for
   /// operations on floating point types.
   FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
@@ -3592,6 +3602,11 @@ class CastExpr : public Expr {
     return *getTrailingFPFeatures();
   }
 
+  /// Get the store FPOptionsOverride or default if not stored.
+  FPOptionsOverride getStoredFPFeaturesOrDefault() const {
+    return hasStoredFPFeatures() ? getStoredFPFeatures() : FPOptionsOverride();
+  }
+
   /// Get the FP features status of this operation. Only meaningful for
   /// operations on floating point types.
   FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
@@ -4038,6 +4053,10 @@ class BinaryOperator : public Expr {
     assert(BinaryOperatorBits.HasFPFeatures);
     *getTrailingFPFeatures() = F;
   }
+  /// Get the store FPOptionsOverride or default if not stored.
+  FPOptionsOverride getStoredFPFeaturesOrDefault() const {
+    return hasStoredFPFeatures() ? getStoredFPFeatures() : FPOptionsOverride();
+  }
 
   /// Get the FP features status of this operator. Only meaningful for
   /// operations on floating point types.

diff  --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 9cd7a364cd3f1..e91e89d728ca0 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -1658,6 +1658,11 @@ class CompoundStmt final
     return *getTrailingObjects<FPOptionsOverride>();
   }
 
+  /// Get the store FPOptionsOverride or default if not stored.
+  FPOptionsOverride getStoredFPFeaturesOrDefault() const {
+    return hasStoredFPFeatures() ? getStoredFPFeatures() : FPOptionsOverride();
+  }
+
   using body_iterator = Stmt **;
   using body_range = llvm::iterator_range<body_iterator>;
 

diff  --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index 000d4ff5c0698..4d45f6d64c1cd 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -328,12 +328,20 @@ 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,7 +355,7 @@ class ComplexExprEmitter
 #define HANDLEBINOP(OP)                                                        \
   ComplexPairTy VisitBin##OP(const BinaryOperator *E) {                        \
     QualType promotionTy = getPromotionType(                                   \
-        E->getType(),                                                          \
+        E->getStoredFPFeaturesOrDefault(), E->getType(),                       \
         (E->getOpcode() == BinaryOperatorKind::BO_Div) ? true : false);        \
     ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy));            \
     if (!promotionTy.isNull())                                                 \
@@ -641,9 +649,12 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op,
 
 ComplexPairTy ComplexExprEmitter::VisitUnaryPlus(const UnaryOperator *E,
                                                  QualType PromotionType) {
-  QualType promotionTy = PromotionType.isNull()
-                             ? getPromotionType(E->getSubExpr()->getType())
-                             : PromotionType;
+  E->hasStoredFPFeatures();
+  QualType promotionTy =
+      PromotionType.isNull()
+          ? getPromotionType(E->getStoredFPFeaturesOrDefault(),
+                             E->getSubExpr()->getType())
+          : PromotionType;
   ComplexPairTy result = VisitPlus(E, promotionTy);
   if (!promotionTy.isNull())
     return CGF.EmitUnPromotedValue(result, E->getSubExpr()->getType());
@@ -661,9 +672,11 @@ ComplexPairTy ComplexExprEmitter::VisitPlus(const UnaryOperator *E,
 
 ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E,
                                                   QualType PromotionType) {
-  QualType promotionTy = PromotionType.isNull()
-                             ? getPromotionType(E->getSubExpr()->getType())
-                             : PromotionType;
+  QualType promotionTy =
+      PromotionType.isNull()
+          ? getPromotionType(E->getStoredFPFeaturesOrDefault(),
+                             E->getSubExpr()->getType())
+          : PromotionType;
   ComplexPairTy result = VisitMinus(E, promotionTy);
   if (!promotionTy.isNull())
     return CGF.EmitUnPromotedValue(result, E->getSubExpr()->getType());
@@ -1218,13 +1231,15 @@ 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->getStoredFPFeaturesOrDefault(),
+                                     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->getStoredFPFeaturesOrDefault(), E->getRHS()->getType());
 
   // The RHS should have been converted to the computation type.
   if (E->getRHS()->getType()->isRealFloatingType()) {
@@ -1252,7 +1267,8 @@ 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->getStoredFPFeaturesOrDefault(), 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;
 }


        


More information about the cfe-commits mailing list