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

[Clang][CodeGen] Do not promote if complex divisor is real #131451

Merged
merged 1 commit into from
Mar 19, 2025

Conversation

Maetveis
Copy link
Contributor

Relates-to: #131129

@Maetveis Maetveis added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. labels Mar 15, 2025
@Maetveis Maetveis requested a review from rjmccall March 15, 2025 12:11
@llvmbot
Copy link
Member

llvmbot commented Mar 15, 2025

@llvm/pr-subscribers-clang-codegen

@llvm/pr-subscribers-clang

Author: Mészáros Gergely (Maetveis)

Changes

Relates-to: #131129


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

2 Files Affected:

  • (modified) clang/lib/CodeGen/CGExprComplex.cpp (+8-9)
  • (modified) clang/test/CodeGen/cx-complex-range-real.c (+16-36)
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index ff7c55be246cc..a8a65a2f956f8 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -286,8 +286,7 @@ class ComplexExprEmitter
   ComplexPairTy EmitComplexBinOpLibCall(StringRef LibCallName,
                                         const BinOpInfo &Op);
 
-  QualType HigherPrecisionTypeForComplexArithmetic(QualType ElementType,
-                                                   bool IsDivOpCode) {
+  QualType HigherPrecisionTypeForComplexArithmetic(QualType ElementType) {
     ASTContext &Ctx = CGF.getContext();
     const QualType HigherElementType =
         Ctx.GetHigherPrecisionFPType(ElementType);
@@ -314,7 +313,7 @@ class ComplexExprEmitter
   }
 
   QualType getPromotionType(FPOptionsOverride Features, QualType Ty,
-                            bool IsDivOpCode = false) {
+                            bool IsComplexDivisor = false) {
     if (auto *CT = Ty->getAs<ComplexType>()) {
       QualType ElementType = CT->getElementType();
       bool IsFloatingType = ElementType->isFloatingType();
@@ -325,10 +324,9 @@ class ComplexExprEmitter
                                      Features.getComplexRangeOverride() ==
                                          CGF.getLangOpts().getComplexRange();
 
-      if (IsDivOpCode && IsFloatingType && IsComplexRangePromoted &&
+      if (IsComplexDivisor && IsFloatingType && IsComplexRangePromoted &&
           (HasNoComplexRangeOverride || HasMatchingComplexRange))
-        return HigherPrecisionTypeForComplexArithmetic(ElementType,
-                                                       IsDivOpCode);
+        return HigherPrecisionTypeForComplexArithmetic(ElementType);
       if (ElementType.UseExcessPrecision(CGF.getContext()))
         return CGF.getContext().getComplexType(CGF.getContext().FloatTy);
     }
@@ -339,9 +337,10 @@ class ComplexExprEmitter
 
 #define HANDLEBINOP(OP)                                                        \
   ComplexPairTy VisitBin##OP(const BinaryOperator *E) {                        \
-    QualType promotionTy = getPromotionType(                                   \
-        E->getStoredFPFeaturesOrDefault(), E->getType(),                       \
-        (E->getOpcode() == BinaryOperatorKind::BO_Div) ? true : false);        \
+    QualType promotionTy =                                                     \
+        getPromotionType(E->getStoredFPFeaturesOrDefault(), E->getType(),      \
+                         (E->getOpcode() == BinaryOperatorKind::BO_Div &&      \
+                          E->getRHS()->getType()->isAnyComplexType()));        \
     ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy));            \
     if (!promotionTy.isNull())                                                 \
       result = CGF.EmitUnPromotedValue(result, E->getType());                  \
diff --git a/clang/test/CodeGen/cx-complex-range-real.c b/clang/test/CodeGen/cx-complex-range-real.c
index 1723075be30fd..94bc080d190bc 100644
--- a/clang/test/CodeGen/cx-complex-range-real.c
+++ b/clang/test/CodeGen/cx-complex-range-real.c
@@ -591,18 +591,13 @@ _Complex float mulbf(float a, _Complex float b) {
 // PRMTD-NEXT:    [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4
 // PRMTD-NEXT:    [[A_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1
 // PRMTD-NEXT:    [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4
-// PRMTD-NEXT:    [[EXT:%.*]] = fpext float [[A_REAL]] to double
-// PRMTD-NEXT:    [[EXT1:%.*]] = fpext float [[A_IMAG]] to double
 // PRMTD-NEXT:    [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
-// PRMTD-NEXT:    [[EXT2:%.*]] = fpext float [[TMP0]] to double
-// PRMTD-NEXT:    [[TMP1:%.*]] = fdiv double [[EXT]], [[EXT2]]
-// PRMTD-NEXT:    [[TMP2:%.*]] = fdiv double [[EXT1]], [[EXT2]]
-// PRMTD-NEXT:    [[UNPROMOTION:%.*]] = fptrunc double [[TMP1]] to float
-// PRMTD-NEXT:    [[UNPROMOTION3:%.*]] = fptrunc double [[TMP2]] to float
+// PRMTD-NEXT:    [[TMP1:%.*]] = fdiv float [[A_REAL]], [[TMP0]]
+// PRMTD-NEXT:    [[TMP2:%.*]] = fdiv float [[A_IMAG]], [[TMP0]]
 // PRMTD-NEXT:    [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
 // PRMTD-NEXT:    [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
-// PRMTD-NEXT:    store float [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 4
-// PRMTD-NEXT:    store float [[UNPROMOTION3]], ptr [[RETVAL_IMAGP]], align 4
+// PRMTD-NEXT:    store float [[TMP1]], ptr [[RETVAL_REALP]], align 4
+// PRMTD-NEXT:    store float [[TMP2]], ptr [[RETVAL_IMAGP]], align 4
 // PRMTD-NEXT:    [[TMP3:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
 // PRMTD-NEXT:    ret <2 x float> [[TMP3]]
 //
@@ -640,18 +635,13 @@ _Complex float mulbf(float a, _Complex float b) {
 // PRMTD_STRICT-NEXT:    [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4
 // PRMTD_STRICT-NEXT:    [[A_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1
 // PRMTD_STRICT-NEXT:    [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4
-// PRMTD_STRICT-NEXT:    [[EXT:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[A_REAL]], metadata !"fpexcept.strict") #[[ATTR3]]
-// PRMTD_STRICT-NEXT:    [[EXT1:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[A_IMAG]], metadata !"fpexcept.strict") #[[ATTR3]]
 // PRMTD_STRICT-NEXT:    [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
-// PRMTD_STRICT-NEXT:    [[EXT2:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP0]], metadata !"fpexcept.strict") #[[ATTR3]]
-// PRMTD_STRICT-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[EXT]], double [[EXT2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// PRMTD_STRICT-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[EXT1]], double [[EXT2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// PRMTD_STRICT-NEXT:    [[UNPROMOTION:%.*]] = call float @llvm.experimental.constrained.fptrunc.f32.f64(double [[TMP1]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// PRMTD_STRICT-NEXT:    [[UNPROMOTION3:%.*]] = call float @llvm.experimental.constrained.fptrunc.f32.f64(double [[TMP2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// PRMTD_STRICT-NEXT:    [[TMP1:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[A_REAL]], float [[TMP0]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// PRMTD_STRICT-NEXT:    [[TMP2:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[A_IMAG]], float [[TMP0]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
 // PRMTD_STRICT-NEXT:    [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
 // PRMTD_STRICT-NEXT:    [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
-// PRMTD_STRICT-NEXT:    store float [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 4
-// PRMTD_STRICT-NEXT:    store float [[UNPROMOTION3]], ptr [[RETVAL_IMAGP]], align 4
+// PRMTD_STRICT-NEXT:    store float [[TMP1]], ptr [[RETVAL_REALP]], align 4
+// PRMTD_STRICT-NEXT:    store float [[TMP2]], ptr [[RETVAL_IMAGP]], align 4
 // PRMTD_STRICT-NEXT:    [[TMP3:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
 // PRMTD_STRICT-NEXT:    ret <2 x float> [[TMP3]]
 //
@@ -1453,18 +1443,13 @@ _Complex float mulbd(double a, _Complex double b) {
 // PRMTD-NEXT:    [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
 // PRMTD-NEXT:    [[A_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
 // PRMTD-NEXT:    [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8
-// PRMTD-NEXT:    [[EXT:%.*]] = fpext double [[A_REAL]] to x86_fp80
-// PRMTD-NEXT:    [[EXT1:%.*]] = fpext double [[A_IMAG]] to x86_fp80
 // PRMTD-NEXT:    [[TMP2:%.*]] = load double, ptr [[B_ADDR]], align 8
-// PRMTD-NEXT:    [[EXT2:%.*]] = fpext double [[TMP2]] to x86_fp80
-// PRMTD-NEXT:    [[TMP3:%.*]] = fdiv x86_fp80 [[EXT]], [[EXT2]]
-// PRMTD-NEXT:    [[TMP4:%.*]] = fdiv x86_fp80 [[EXT1]], [[EXT2]]
-// PRMTD-NEXT:    [[UNPROMOTION:%.*]] = fptrunc x86_fp80 [[TMP3]] to double
-// PRMTD-NEXT:    [[UNPROMOTION3:%.*]] = fptrunc x86_fp80 [[TMP4]] to double
+// PRMTD-NEXT:    [[TMP3:%.*]] = fdiv double [[A_REAL]], [[TMP2]]
+// PRMTD-NEXT:    [[TMP4:%.*]] = fdiv double [[A_IMAG]], [[TMP2]]
 // PRMTD-NEXT:    [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 0
 // PRMTD-NEXT:    [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 1
-// PRMTD-NEXT:    store double [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 8
-// PRMTD-NEXT:    store double [[UNPROMOTION3]], ptr [[RETVAL_IMAGP]], align 8
+// PRMTD-NEXT:    store double [[TMP3]], ptr [[RETVAL_REALP]], align 8
+// PRMTD-NEXT:    store double [[TMP4]], ptr [[RETVAL_IMAGP]], align 8
 // PRMTD-NEXT:    [[TMP5:%.*]] = load { double, double }, ptr [[RETVAL]], align 8
 // PRMTD-NEXT:    ret { double, double } [[TMP5]]
 //
@@ -1508,18 +1493,13 @@ _Complex float mulbd(double a, _Complex double b) {
 // PRMTD_STRICT-NEXT:    [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
 // PRMTD_STRICT-NEXT:    [[A_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
 // PRMTD_STRICT-NEXT:    [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8
-// PRMTD_STRICT-NEXT:    [[EXT:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f64(double [[A_REAL]], metadata !"fpexcept.strict") #[[ATTR3]]
-// PRMTD_STRICT-NEXT:    [[EXT1:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f64(double [[A_IMAG]], metadata !"fpexcept.strict") #[[ATTR3]]
 // PRMTD_STRICT-NEXT:    [[TMP2:%.*]] = load double, ptr [[B_ADDR]], align 8
-// PRMTD_STRICT-NEXT:    [[EXT2:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f64(double [[TMP2]], metadata !"fpexcept.strict") #[[ATTR3]]
-// PRMTD_STRICT-NEXT:    [[TMP3:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[EXT]], x86_fp80 [[EXT2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// PRMTD_STRICT-NEXT:    [[TMP4:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[EXT1]], x86_fp80 [[EXT2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// PRMTD_STRICT-NEXT:    [[UNPROMOTION:%.*]] = call double @llvm.experimental.constrained.fptrunc.f64.f80(x86_fp80 [[TMP3]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
-// PRMTD_STRICT-NEXT:    [[UNPROMOTION3:%.*]] = call double @llvm.experimental.constrained.fptrunc.f64.f80(x86_fp80 [[TMP4]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// PRMTD_STRICT-NEXT:    [[TMP3:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A_REAL]], double [[TMP2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
+// PRMTD_STRICT-NEXT:    [[TMP4:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A_IMAG]], double [[TMP2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
 // PRMTD_STRICT-NEXT:    [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 0
 // PRMTD_STRICT-NEXT:    [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 1
-// PRMTD_STRICT-NEXT:    store double [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 8
-// PRMTD_STRICT-NEXT:    store double [[UNPROMOTION3]], ptr [[RETVAL_IMAGP]], align 8
+// PRMTD_STRICT-NEXT:    store double [[TMP3]], ptr [[RETVAL_REALP]], align 8
+// PRMTD_STRICT-NEXT:    store double [[TMP4]], ptr [[RETVAL_IMAGP]], align 8
 // PRMTD_STRICT-NEXT:    [[TMP5:%.*]] = load { double, double }, ptr [[RETVAL]], align 8
 // PRMTD_STRICT-NEXT:    ret { double, double } [[TMP5]]
 //

@Maetveis Maetveis requested a review from efriedma-quic March 15, 2025 12:11
@Maetveis Maetveis marked this pull request as ready for review March 15, 2025 12:13
Copy link
Collaborator

@efriedma-quic efriedma-quic left a comment

Choose a reason for hiding this comment

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

LGTM

@Maetveis Maetveis force-pushed the users/Maetveis/complex-promoted-fix-real branch 2 times, most recently from c6e05d7 to 549f55f Compare March 18, 2025 20:40
Base automatically changed from users/Maetveis/precommit-complex-test to main March 19, 2025 05:24
@Maetveis Maetveis force-pushed the users/Maetveis/complex-promoted-fix-real branch from 549f55f to 631db26 Compare March 19, 2025 06:19
Copy link
Contributor Author

Maetveis commented Mar 19, 2025

Merge activity

  • Mar 19, 2:22 AM EDT: A user started a stack merge that includes this pull request via Graphite.
  • Mar 19, 2:24 AM EDT: Graphite rebased this pull request as part of a merge.
  • Mar 19, 2:26 AM EDT: A user merged this pull request with Graphite.

@Maetveis Maetveis force-pushed the users/Maetveis/complex-promoted-fix-real branch from 631db26 to 5767414 Compare March 19, 2025 06:23
@Maetveis Maetveis merged commit 1bd6716 into main Mar 19, 2025
6 of 10 checks passed
@Maetveis Maetveis deleted the users/Maetveis/complex-promoted-fix-real branch March 19, 2025 06:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants