Author: Zahira Ammarguellat Date: 2025-04-01T11:10:51-04:00 New Revision: aa73124e51d89a22b2ba89380d3a1403e4f1c385
URL: https://github.com/llvm/llvm-project/commit/aa73124e51d89a22b2ba89380d3a1403e4f1c385 DIFF: https://github.com/llvm/llvm-project/commit/aa73124e51d89a22b2ba89380d3a1403e4f1c385.diff LOG: Fix complex long double division with -mno-x87. (#133152) The combination of `-fcomplex-arithmetic=promoted` and `mno-x87` for `double` complex division is leading to a crash. See https://godbolt.org/z/189G957oY This patch fixes that. Added: clang/test/CodeGen/promoted-complex-div.c Modified: clang/lib/CodeGen/CGExprComplex.cpp clang/lib/Sema/SemaExpr.cpp Removed: ################################################################################ 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 48dab1c1c94a8..1c0ef39878d7f 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -15329,8 +15329,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..7ed7b07db83ae --- /dev/null +++ b/clang/test/CodeGen/promoted-complex-div.c @@ -0,0 +1,83 @@ +// 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 \ +// 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 - \ +// 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 \ +// RUN: -o - | FileCheck %s --check-prefix=NOX87 + + + +// 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 + + // 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; +} + +// 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 + + // 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 diff erences in complex division behavior}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits