[clang] Fix complex long double division with -mno-x87. (PR #133152)
Zahira Ammarguellat via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 31 11:42:08 PDT 2025
https://github.com/zahiraam updated https://github.com/llvm/llvm-project/pull/133152
>From 56a000612da3f58928362229a46800c6f077cc71 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Wed, 26 Mar 2025 13:18:36 -0700
Subject: [PATCH 1/3] Fix complex long division with -mno-x87.
---
clang/lib/CodeGen/CGExprComplex.cpp | 4 ++
clang/lib/Sema/SemaExpr.cpp | 6 ++-
clang/test/CodeGen/promoted-complex-div.c | 49 +++++++++++++++++++++++
3 files changed, 57 insertions(+), 2 deletions(-)
create mode 100644 clang/test/CodeGen/promoted-complex-div.c
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index a7c8b96da6853..184a355734046 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -303,6 +303,10 @@ class ComplexExprEmitter
// doubles the exponent of SmallerType.LargestFiniteVal)
if (llvm::APFloat::semanticsMaxExponent(ElementTypeSemantics) * 2 + 1 <=
llvm::APFloat::semanticsMaxExponent(HigherElementTypeSemantics)) {
+ if (!Ctx.getTargetInfo().hasLongDoubleType() &&
+ HigherElementType.getCanonicalType().getUnqualifiedType() ==
+ Ctx.LongDoubleTy)
+ return QualType();
FPHasBeenPromoted = true;
return Ctx.getComplexType(HigherElementType);
} else {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 3af6d6c23438f..69a13aff14a00 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -15304,8 +15304,10 @@ static void DetectPrecisionLossInComplexDivision(Sema &S, SourceLocation OpLoc,
Ctx.getFloatTypeSemantics(ElementType);
const llvm::fltSemantics &HigherElementTypeSemantics =
Ctx.getFloatTypeSemantics(HigherElementType);
- if (llvm::APFloat::semanticsMaxExponent(ElementTypeSemantics) * 2 + 1 >
- llvm::APFloat::semanticsMaxExponent(HigherElementTypeSemantics)) {
+ if ((llvm::APFloat::semanticsMaxExponent(ElementTypeSemantics) * 2 + 1 >
+ llvm::APFloat::semanticsMaxExponent(HigherElementTypeSemantics)) ||
+ (HigherElementType == Ctx.LongDoubleTy &&
+ !Ctx.getTargetInfo().hasLongDoubleType())) {
// Retain the location of the first use of higher precision type.
if (!S.LocationOfExcessPrecisionNotSatisfied.isValid())
S.LocationOfExcessPrecisionNotSatisfied = OpLoc;
diff --git a/clang/test/CodeGen/promoted-complex-div.c b/clang/test/CodeGen/promoted-complex-div.c
new file mode 100644
index 0000000000000..02300126965ed
--- /dev/null
+++ b/clang/test/CodeGen/promoted-complex-div.c
@@ -0,0 +1,49 @@
+// RUN %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \
+// RUN -verify -complex-range=promoted -o - | FileCheck %s
+
+// RUN %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \
+// RUN -verify=nopromotion -complex-range=promoted -target-feature -x87 -o - | FileCheck %s --check-prefix=X87
+
+// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-windows \
+// RUN: -verify=nopromotion -complex-range=promoted -o - | FileCheck %s --check-prefix=X87
+
+// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-windows \
+// RUN: -verify=nopromotion -complex-range=promoted -target-feature -x87 -o - | FileCheck %s --check-prefix=X87
+
+
+
+// expected-no-diagnostics
+
+// CHECK-LABEL: define dso_local <2 x float> @divd
+_Complex float divd(_Complex float a, _Complex float b) {
+ // CHECK: fpext float {{.*}} to double
+ // CHECK: fpext float {{.*}} to double
+ // CHECK: fdiv double
+ // CHECK: fdiv double
+ // CHECK: fptrunc double {{.*}} to float
+ // CHECK: fptrunc double {{.*}} to float
+
+ // X87: fpext float {{.*}} to double
+ // X87: fpext float {{.*}} to double
+ // X87: fdiv double
+ // X87: fdiv double
+ // X87: fptrunc double {{.*}} to float
+ // X87: fptrunc double {{.*}} to float
+
+ return a / b;
+}
+
+// CHECK-LABEL: define dso_local { double, double } @divf
+_Complex double divf(_Complex double a, _Complex double b) {
+ // CHECK: fpext double {{.*}} to x86_fp80
+ // CHECK: fpext double {{.*}} to x86_fp80
+ // CHECK: fdiv x86_fp80
+ // CHECK: fdiv x86_fp80
+ // CHECK: fptrunc x86_fp80
+ // CHECK: fptrunc x86_fp80
+
+ // X87: fdiv double
+ // X87: fdiv double
+
+ return a / b; // nopromotion-warning{{excess precision is requested but the target does not support excess precision which may result in observable differences in complex division behavior}}
+}
>From 15396dc494ee1ea3c18b1221a3aaaf1532d7010d Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Mon, 31 Mar 2025 08:06:43 -0700
Subject: [PATCH 2/3] Addressed Josh's review comments.
---
clang/test/CodeGen/promoted-complex-div.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/clang/test/CodeGen/promoted-complex-div.c b/clang/test/CodeGen/promoted-complex-div.c
index 02300126965ed..ce520f93db4f1 100644
--- a/clang/test/CodeGen/promoted-complex-div.c
+++ b/clang/test/CodeGen/promoted-complex-div.c
@@ -2,13 +2,13 @@
// RUN -verify -complex-range=promoted -o - | FileCheck %s
// RUN %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \
-// RUN -verify=nopromotion -complex-range=promoted -target-feature -x87 -o - | FileCheck %s --check-prefix=X87
+// RUN -verify=nopromotion -complex-range=promoted -target-feature -x87 -o - | FileCheck %s --check-prefix=NOX87
// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-windows \
-// RUN: -verify=nopromotion -complex-range=promoted -o - | FileCheck %s --check-prefix=X87
+// RUN: -verify=nopromotion -complex-range=promoted -o - | FileCheck %s --check-prefix=NOX87
// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-windows \
-// RUN: -verify=nopromotion -complex-range=promoted -target-feature -x87 -o - | FileCheck %s --check-prefix=X87
+// RUN: -verify=nopromotion -complex-range=promoted -target-feature -x87 -o - | FileCheck %s --check-prefix=NOX87
@@ -23,12 +23,12 @@ _Complex float divd(_Complex float a, _Complex float b) {
// CHECK: fptrunc double {{.*}} to float
// CHECK: fptrunc double {{.*}} to float
- // X87: fpext float {{.*}} to double
- // X87: fpext float {{.*}} to double
- // X87: fdiv double
- // X87: fdiv double
- // X87: fptrunc double {{.*}} to float
- // X87: fptrunc double {{.*}} to float
+ // NOX87: fpext float {{.*}} to double
+ // NOX87: fpext float {{.*}} to double
+ // NOX87: fdiv double
+ // NOX87: fdiv double
+ // NOX87: fptrunc double {{.*}} to float
+ // NOX87: fptrunc double {{.*}} to float
return a / b;
}
@@ -42,8 +42,8 @@ _Complex double divf(_Complex double a, _Complex double b) {
// CHECK: fptrunc x86_fp80
// CHECK: fptrunc x86_fp80
- // X87: fdiv double
- // X87: fdiv double
+ // NOX87: fdiv double
+ // NOX87: fdiv double
return a / b; // nopromotion-warning{{excess precision is requested but the target does not support excess precision which may result in observable differences in complex division behavior}}
}
>From f83d792a5816cb984f9e39b224e319dc7deb7348 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <zahira.ammarguellat at intel.com>
Date: Mon, 31 Mar 2025 11:41:40 -0700
Subject: [PATCH 3/3] Added check line to LIT test.
---
clang/test/CodeGen/promoted-complex-div.c | 50 +++++++++++++++++++----
1 file changed, 42 insertions(+), 8 deletions(-)
diff --git a/clang/test/CodeGen/promoted-complex-div.c b/clang/test/CodeGen/promoted-complex-div.c
index ce520f93db4f1..7ed7b07db83ae 100644
--- a/clang/test/CodeGen/promoted-complex-div.c
+++ b/clang/test/CodeGen/promoted-complex-div.c
@@ -1,14 +1,17 @@
-// RUN %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \
-// RUN -verify -complex-range=promoted -o - | FileCheck %s
+// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \
+// RUN: -verify -complex-range=promoted -o - | FileCheck %s
-// RUN %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \
-// RUN -verify=nopromotion -complex-range=promoted -target-feature -x87 -o - | FileCheck %s --check-prefix=NOX87
+// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \
+// RUN: -verify=nopromotion -complex-range=promoted -target-feature -x87 \
+// RUN: -o - | FileCheck %s --check-prefix=NOX87
// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-windows \
-// RUN: -verify=nopromotion -complex-range=promoted -o - | FileCheck %s --check-prefix=NOX87
+// RUN: -verify=nopromotion -complex-range=promoted -o - \
+// RUN: | FileCheck %s --check-prefix=NOX87
// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-windows \
-// RUN: -verify=nopromotion -complex-range=promoted -target-feature -x87 -o - | FileCheck %s --check-prefix=NOX87
+// RUN: -verify=nopromotion -complex-range=promoted -target-feature -x87 \
+// RUN: -o - | FileCheck %s --check-prefix=NOX87
@@ -42,8 +45,39 @@ _Complex double divf(_Complex double a, _Complex double b) {
// CHECK: fptrunc x86_fp80
// CHECK: fptrunc x86_fp80
- // NOX87: fdiv double
- // NOX87: fdiv double
+ // NOX87: call double @llvm.fabs.f64(double {{.*}})
+ // NOX87-NEXT: call double @llvm.fabs.f64(double {{.*}})
+ // NOX87-NEXT: fcmp ugt double %{{.*}}, {{.*}}
+ // NOX87-NEXT: br i1 {{.*}}, label
+ // NOX87: abs_rhsr_greater_or_equal_abs_rhsi:
+ // NOX87-NEXT: fdiv double
+ // NOX87-NEXT: fmul double
+ // NOX87-NEXT: fadd double
+ // NOX87-NEXT: fmul double
+ // NOX87-NEXT: fadd double
+ // NOX87-NEXT: fdiv double
+ // NOX87-NEXT: fmul double
+ // NOX87-NEXT: fsub double
+ // NOX87-NEXT: fdiv double
+ // NOX87-NEXT: br label {{.*}}
+ // NOX87: abs_rhsr_less_than_abs_rhsi:
+ // NOX87-NEXT: fdiv double
+ // NOX87-NEXT: fmul double
+ // NOX87-NEXT: fadd double
+ // NOX87-NEXT: fmul double
+ // NOX87-NEXT: fadd double
+ // NOX87-NEXT: fdiv double
+ // NOX87-NEXT: fmul double
+ // NOX87-NEXT: fsub double
+ // NOX87-NEXT: fdiv double
+ // NOX87-NEXT: br label
+ // NOX87: complex_div:
+ // NOX87-NEXT: phi double
+ // NOX87-NEXT: phi double
+ // NOX87-NEXT: getelementptr inbounds nuw { double, double }, ptr {{.*}}, i32 0, i32 0
+ // NOX87-NEXT: getelementptr inbounds nuw { double, double }, ptr {{.*}}, i32 0, i32 1
+ // NOX87-NEXT: store double
+ // NOX87-NEXT: store double
return a / b; // nopromotion-warning{{excess precision is requested but the target does not support excess precision which may result in observable differences in complex division behavior}}
}
More information about the cfe-commits
mailing list