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

Zahira Ammarguellat via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 15 08:52:09 PDT 2024


https://github.com/zahiraam updated https://github.com/llvm/llvm-project/pull/98520

>From da863999000a6b12f2930247de9df3daf0e5a608 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Thu, 11 Jul 2024 11:54:13 -0700
Subject: [PATCH 1/5] The pragma STDC CX_LIMITED_RANGE ON should have
 precedence over command line -fcomplex-arithmetic.

---
 clang/lib/CodeGen/CGExprComplex.cpp          | 35 ++++++---
 clang/test/CodeGen/pragma-cx-limited-range.c | 75 ++++++++++----------
 2 files changed, 64 insertions(+), 46 deletions(-)

diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index 84ad3b566b647..44e04b323db6b 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -328,12 +328,14 @@ 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)
+              LangOptions::ComplexRangeKind::CX_Promoted &&
+          !Features.hasComplexRangeOverride())
         return HigherPrecisionTypeForComplexArithmetic(ElementType,
                                                        IsDivOpCode);
       if (ElementType.UseExcessPrecision(CGF.getContext()))
@@ -347,7 +349,9 @@ class ComplexExprEmitter
 #define HANDLEBINOP(OP)                                                        \
   ComplexPairTy VisitBin##OP(const BinaryOperator *E) {                        \
     QualType promotionTy = getPromotionType(                                   \
-        E->getType(),                                                          \
+        (E->hasStoredFPFeatures() ? E->getStoredFPFeatures()                   \
+                                  : FPOptionsOverride()),                      \
+          E->getType(),                                                        \
         (E->getOpcode() == BinaryOperatorKind::BO_Div) ? true : false);        \
     ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy));            \
     if (!promotionTy.isNull())                                                 \
@@ -642,7 +646,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 +669,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 +1233,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 +1273,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..7732db1dc616d 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;
 }
@@ -218,28 +214,31 @@ _Complex float pragma_default_div(_Complex float a, _Complex float b) {
   // IMPRVD-NEXT: fsub float
   // IMPRVD-NEXT: fdiv float
 
-  // PRMTD: load float, ptr {{.*}}
-  // PRMTD: fpext float {{.*}} to double
-  // PRMTD-NEXT: fpext float {{.*}} to double
-  // PRMTD-NEXT: getelementptr inbounds { float, float }, ptr {{.*}}, i32 0, i32 0
-  // PRMTD-NEXT: load float, ptr {{.*}}
-  // PRMTD-NEXT: getelementptr inbounds { float, float }, ptr {{.*}}, i32 0, i32 1
-  // PRMTD-NEXT: load float, ptr {{.*}}
-  // PRMTD-NEXT: fpext float {{.*}} to double
-  // PRMTD-NEXT: fpext float {{.*}} to double
-  // PRMTD-NEXT: fmul double
-  // PRMTD-NEXT: fmul double
-  // PRMTD-NEXT: fadd double
-  // PRMTD-NEXT: fmul double
-  // PRMTD-NEXT: fmul double
-  // PRMTD-NEXT: fadd double
-  // PRMTD-NEXT: fmul double
-  // PRMTD-NEXT: fmul double
-  // PRMTD-NEXT: fsub double
-  // PRMTD-NEXT: fdiv double
-  // PRMTD-NEXT: fdiv double
-  // PRMTD-NEXT: fptrunc double {{.*}} to float
-  // PRMTD-NEXT: fptrunc double {{.*}} to float
+  // PRMTD: call{{.*}}float @llvm.fabs.f32(float {{.*}})
+  // PRMTD-NEXT: call{{.*}}float @llvm.fabs.f32(float {{.*}})
+  // PRMTD-NEXT: fcmp{{.*}}ugt float {{.*}}, {{.*}}
+  // PRMTD-NEXT:   br i1 {{.*}}, label
+  // PRMTD:  abs_rhsr_greater_or_equal_abs_rhsi:
+  // PRMTD-NEXT: fdiv float
+  // PRMTD-NEXT: fmul float
+  // PRMTD-NEXT: fadd float
+  // PRMTD-NEXT: fmul float
+  // PRMTD-NEXT: fadd float
+  // PRMTD-NEXT: fdiv float
+  // PRMTD-NEXT: fmul float
+  // PRMTD-NEXT: fsub float
+  // PRMTD-NEXT: fdiv float
+  // PRMTD-NEXT: br label
+  // PRMTD: abs_rhsr_less_than_abs_rhsi:
+  // PRMTD-NEXT: fdiv float
+  // PRMTD-NEXT: fmul float
+  // PRMTD-NEXT: fadd float
+  // PRMTD-NEXT: fmul float
+  // PRMTD-NEXT: fadd float
+  // PRMTD-NEXT: fdiv float
+  // PRMTD-NEXT: fmul float
+  // PRMTD-NEXT: fsub float
+  // PRMTD-NEXT: fdiv float
 
   return a / b;
 }

>From 1e59c26b411747483cf4dda968501247e8ea411a Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Thu, 11 Jul 2024 12:09:06 -0700
Subject: [PATCH 2/5] Fix format.

---
 clang/lib/CodeGen/CGExprComplex.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index 44e04b323db6b..9dc82afb6606e 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -351,7 +351,7 @@ class ComplexExprEmitter
     QualType promotionTy = getPromotionType(                                   \
         (E->hasStoredFPFeatures() ? E->getStoredFPFeatures()                   \
                                   : FPOptionsOverride()),                      \
-          E->getType(),                                                        \
+        E->getType(),                                                          \
         (E->getOpcode() == BinaryOperatorKind::BO_Div) ? true : false);        \
     ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy));            \
     if (!promotionTy.isNull())                                                 \

>From 102fa19d8062d13824f184a357e6139b2a8aa637 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Fri, 12 Jul 2024 13:16:40 -0700
Subject: [PATCH 3/5] Addressed review comments.

---
 clang/lib/CodeGen/CGExprComplex.cpp          | 15 +++++--
 clang/test/CodeGen/pragma-cx-limited-range.c | 47 +++++++++-----------
 2 files changed, 33 insertions(+), 29 deletions(-)

diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index 9dc82afb6606e..de526a74b0f2d 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -332,10 +332,17 @@ class ComplexExprEmitter
                             bool IsDivOpCode = false) {
     if (auto *CT = Ty->getAs<ComplexType>()) {
       QualType ElementType = CT->getElementType();
-      if (IsDivOpCode && ElementType->isFloatingType() &&
-          CGF.getLangOpts().getComplexRange() ==
-              LangOptions::ComplexRangeKind::CX_Promoted &&
-          !Features.hasComplexRangeOverride())
+      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()))
diff --git a/clang/test/CodeGen/pragma-cx-limited-range.c b/clang/test/CodeGen/pragma-cx-limited-range.c
index 7732db1dc616d..1c9bf40fd714f 100644
--- a/clang/test/CodeGen/pragma-cx-limited-range.c
+++ b/clang/test/CodeGen/pragma-cx-limited-range.c
@@ -214,31 +214,28 @@ _Complex float pragma_default_div(_Complex float a, _Complex float b) {
   // IMPRVD-NEXT: fsub float
   // IMPRVD-NEXT: fdiv float
 
-  // PRMTD: call{{.*}}float @llvm.fabs.f32(float {{.*}})
-  // PRMTD-NEXT: call{{.*}}float @llvm.fabs.f32(float {{.*}})
-  // PRMTD-NEXT: fcmp{{.*}}ugt float {{.*}}, {{.*}}
-  // PRMTD-NEXT:   br i1 {{.*}}, label
-  // PRMTD:  abs_rhsr_greater_or_equal_abs_rhsi:
-  // PRMTD-NEXT: fdiv float
-  // PRMTD-NEXT: fmul float
-  // PRMTD-NEXT: fadd float
-  // PRMTD-NEXT: fmul float
-  // PRMTD-NEXT: fadd float
-  // PRMTD-NEXT: fdiv float
-  // PRMTD-NEXT: fmul float
-  // PRMTD-NEXT: fsub float
-  // PRMTD-NEXT: fdiv float
-  // PRMTD-NEXT: br label
-  // PRMTD: abs_rhsr_less_than_abs_rhsi:
-  // PRMTD-NEXT: fdiv float
-  // PRMTD-NEXT: fmul float
-  // PRMTD-NEXT: fadd float
-  // PRMTD-NEXT: fmul float
-  // PRMTD-NEXT: fadd float
-  // PRMTD-NEXT: fdiv float
-  // PRMTD-NEXT: fmul float
-  // PRMTD-NEXT: fsub float
-  // PRMTD-NEXT: fdiv float
+  // PRMTD: load float, ptr {{.*}}
+  // PRMTD: fpext float {{.*}} to double
+  // PRMTD-NEXT: fpext float {{.*}} to double
+  // PRMTD-NEXT: getelementptr inbounds { float, float }, ptr {{.*}}, i32 0, i32 0
+  // PRMTD-NEXT: load float, ptr {{.*}}
+  // PRMTD-NEXT: getelementptr inbounds { float, float }, ptr {{.*}}, i32 0, i32 1
+  // PRMTD-NEXT: load float, ptr {{.*}}
+  // PRMTD-NEXT: fpext float {{.*}} to double
+  // PRMTD-NEXT: fpext float {{.*}} to double
+  // PRMTD-NEXT: fmul double
+  // PRMTD-NEXT: fmul double
+  // PRMTD-NEXT: fadd double
+  // PRMTD-NEXT: fmul double
+  // PRMTD-NEXT: fmul double
+  // PRMTD-NEXT: fadd double
+  // PRMTD-NEXT: fmul double
+  // PRMTD-NEXT: fmul double
+  // PRMTD-NEXT: fsub double
+  // PRMTD-NEXT: fdiv double
+  // PRMTD-NEXT: fdiv double
+  // PRMTD-NEXT: fptrunc double {{.*}} to float
+  // PRMTD-NEXT: fptrunc double {{.*}} to float
 
   return a / b;
 }

>From 24cb25aae2e8954574aa85a6746d84a5d80e1b90 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Fri, 12 Jul 2024 13:25:03 -0700
Subject: [PATCH 4/5] Fix format.

---
 clang/lib/CodeGen/CGExprComplex.cpp | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index de526a74b0f2d..fc3382983c5a6 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -336,10 +336,9 @@ class ComplexExprEmitter
       bool isComplexRangePromoted = CGF.getLangOpts().getComplexRange() ==
                                     LangOptions::ComplexRangeKind::CX_Promoted;
       bool hasNoComplexRangeOverride = !Features.hasComplexRangeOverride();
-      bool hasMatchingComplexRange =
-          Features.hasComplexRangeOverride() &&
-          Features.getComplexRangeOverride() ==
-              CGF.getLangOpts().getComplexRange();
+      bool hasMatchingComplexRange = Features.hasComplexRangeOverride() &&
+                                     Features.getComplexRangeOverride() ==
+                                         CGF.getLangOpts().getComplexRange();
 
       if (IsDivOpCode && isFloatingType && isComplexRangePromoted &&
           (hasNoComplexRangeOverride || hasMatchingComplexRange))

>From e75c1778660fd8536e37bbe145e856e5f6ef13ec Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Mon, 15 Jul 2024 08:51:44 -0700
Subject: [PATCH 5/5] Addressed revew comments.

---
 clang/lib/CodeGen/CGExprComplex.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index fc3382983c5a6..7877081c6d7db 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -332,16 +332,16 @@ class ComplexExprEmitter
                             bool IsDivOpCode = false) {
     if (auto *CT = Ty->getAs<ComplexType>()) {
       QualType ElementType = CT->getElementType();
-      bool isFloatingType = ElementType->isFloatingType();
-      bool isComplexRangePromoted = CGF.getLangOpts().getComplexRange() ==
+      bool IsFloatingType = ElementType->isFloatingType();
+      bool IsComplexRangePromoted = CGF.getLangOpts().getComplexRange() ==
                                     LangOptions::ComplexRangeKind::CX_Promoted;
-      bool hasNoComplexRangeOverride = !Features.hasComplexRangeOverride();
-      bool hasMatchingComplexRange = Features.hasComplexRangeOverride() &&
+      bool HasNoComplexRangeOverride = !Features.hasComplexRangeOverride();
+      bool HasMatchingComplexRange = Features.hasComplexRangeOverride() &&
                                      Features.getComplexRangeOverride() ==
                                          CGF.getLangOpts().getComplexRange();
 
-      if (IsDivOpCode && isFloatingType && isComplexRangePromoted &&
-          (hasNoComplexRangeOverride || hasMatchingComplexRange))
+      if (IsDivOpCode && IsFloatingType && IsComplexRangePromoted &&
+          (HasNoComplexRangeOverride || HasMatchingComplexRange))
         return HigherPrecisionTypeForComplexArithmetic(ElementType,
                                                        IsDivOpCode);
       if (ElementType.UseExcessPrecision(CGF.getContext()))



More information about the cfe-commits mailing list