-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Desugar complex element types for promoted complex division #168943
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
base: main
Are you sure you want to change the base?
Conversation
🐧 Linux x64 Test Results
|
|
@llvm/pr-subscribers-clang Author: Zahira Ammarguellat (zahiraam) ChangesThis patch fixes a crash in Clang that occurs when the compiler retrieves the element type of a complex type but receives a sugared type. See example here: https://godbolt.org/z/cdbdeMcaT Full diff: https://github.com/llvm/llvm-project/pull/168943.diff 3 Files Affected:
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index d281c4c20616a..f33e5d75296eb 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -320,7 +320,8 @@ class ComplexExprEmitter
QualType getPromotionType(FPOptionsOverride Features, QualType Ty,
bool IsComplexDivisor) {
if (auto *CT = Ty->getAs<ComplexType>()) {
- QualType ElementType = CT->getElementType();
+ QualType ElementType =
+ CT->getElementType().getDesugaredType(CGF.getContext());
bool IsFloatingType = ElementType->isFloatingType();
bool IsComplexRangePromoted = CGF.getLangOpts().getComplexRange() ==
LangOptions::ComplexRangeKind::CX_Promoted;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 10f0ec3010c6c..ea7937d551ddb 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -10726,13 +10726,13 @@ static void DetectPrecisionLossInComplexDivision(Sema &S, QualType DivisorTy,
if (!CT)
return;
- QualType ElementType = CT->getElementType();
+ ASTContext &Ctx = S.getASTContext();
+ QualType ElementType = CT->getElementType().getDesugaredType(Ctx);
bool IsComplexRangePromoted = S.getLangOpts().getComplexRange() ==
LangOptions::ComplexRangeKind::CX_Promoted;
if (!ElementType->isFloatingType() || !IsComplexRangePromoted)
return;
- ASTContext &Ctx = S.getASTContext();
QualType HigherElementType = Ctx.GetHigherPrecisionFPType(ElementType);
const llvm::fltSemantics &ElementTypeSemantics =
Ctx.getFloatTypeSemantics(ElementType);
diff --git a/clang/test/CodeGen/promoted-complex-div.c b/clang/test/CodeGen/promoted-complex-div.c
index 7ed7b07db83ae..006b5e334e6ea 100644
--- a/clang/test/CodeGen/promoted-complex-div.c
+++ b/clang/test/CodeGen/promoted-complex-div.c
@@ -81,3 +81,55 @@ _Complex double divf(_Complex double a, _Complex double b) {
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}}
}
+
+// This test ensures that Clang does not crash when complex element types
+// require desugaring under -complex-range=promoted. Previously, a sugared
+// typedef element type (e.g., 'typedef double a') caused a crash during
+// complex range evaluation in both Sema and CodeGen.
+typedef double a;
+_Complex double *b;
+// CHECK-LABEL: define dso_local void @DivideByComplexZero
+void DivideByComplexZero() {
+ // CHECK: fpext double {{.*}} to x86_fp80
+ // CHECK: fpext double {{.*}} to x86_fp80
+ // CHECK: fmul x86_fp80
+ // CHECK: fmul x86_fp80
+ // CHECK: fadd x86_fp80
+ // CHECK: fmul x86_fp80
+ // CHECK: fmul x86_fp80
+ // CHECK: fsub 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: 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: 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
+
+ *b /= 1.0iF * (a)0;
+}
|
|
@llvm/pr-subscribers-clang-codegen Author: Zahira Ammarguellat (zahiraam) ChangesThis patch fixes a crash in Clang that occurs when the compiler retrieves the element type of a complex type but receives a sugared type. See example here: https://godbolt.org/z/cdbdeMcaT Full diff: https://github.com/llvm/llvm-project/pull/168943.diff 3 Files Affected:
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index d281c4c20616a..f33e5d75296eb 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -320,7 +320,8 @@ class ComplexExprEmitter
QualType getPromotionType(FPOptionsOverride Features, QualType Ty,
bool IsComplexDivisor) {
if (auto *CT = Ty->getAs<ComplexType>()) {
- QualType ElementType = CT->getElementType();
+ QualType ElementType =
+ CT->getElementType().getDesugaredType(CGF.getContext());
bool IsFloatingType = ElementType->isFloatingType();
bool IsComplexRangePromoted = CGF.getLangOpts().getComplexRange() ==
LangOptions::ComplexRangeKind::CX_Promoted;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 10f0ec3010c6c..ea7937d551ddb 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -10726,13 +10726,13 @@ static void DetectPrecisionLossInComplexDivision(Sema &S, QualType DivisorTy,
if (!CT)
return;
- QualType ElementType = CT->getElementType();
+ ASTContext &Ctx = S.getASTContext();
+ QualType ElementType = CT->getElementType().getDesugaredType(Ctx);
bool IsComplexRangePromoted = S.getLangOpts().getComplexRange() ==
LangOptions::ComplexRangeKind::CX_Promoted;
if (!ElementType->isFloatingType() || !IsComplexRangePromoted)
return;
- ASTContext &Ctx = S.getASTContext();
QualType HigherElementType = Ctx.GetHigherPrecisionFPType(ElementType);
const llvm::fltSemantics &ElementTypeSemantics =
Ctx.getFloatTypeSemantics(ElementType);
diff --git a/clang/test/CodeGen/promoted-complex-div.c b/clang/test/CodeGen/promoted-complex-div.c
index 7ed7b07db83ae..006b5e334e6ea 100644
--- a/clang/test/CodeGen/promoted-complex-div.c
+++ b/clang/test/CodeGen/promoted-complex-div.c
@@ -81,3 +81,55 @@ _Complex double divf(_Complex double a, _Complex double b) {
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}}
}
+
+// This test ensures that Clang does not crash when complex element types
+// require desugaring under -complex-range=promoted. Previously, a sugared
+// typedef element type (e.g., 'typedef double a') caused a crash during
+// complex range evaluation in both Sema and CodeGen.
+typedef double a;
+_Complex double *b;
+// CHECK-LABEL: define dso_local void @DivideByComplexZero
+void DivideByComplexZero() {
+ // CHECK: fpext double {{.*}} to x86_fp80
+ // CHECK: fpext double {{.*}} to x86_fp80
+ // CHECK: fmul x86_fp80
+ // CHECK: fmul x86_fp80
+ // CHECK: fadd x86_fp80
+ // CHECK: fmul x86_fp80
+ // CHECK: fmul x86_fp80
+ // CHECK: fsub 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: 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: 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
+
+ *b /= 1.0iF * (a)0;
+}
|
| QualType getPromotionType(FPOptionsOverride Features, QualType Ty, | ||
| bool IsComplexDivisor) { | ||
| if (auto *CT = Ty->getAs<ComplexType>()) { | ||
| QualType ElementType = CT->getElementType(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just use the canonical type?
|
|
||
| QualType ElementType = CT->getElementType(); | ||
| ASTContext &Ctx = S.getASTContext(); | ||
| QualType ElementType = CT->getElementType().getDesugaredType(Ctx); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto
This patch fixes a crash in Clang that occurs when the compiler retrieves the element type of a complex type but receives a sugared type. See example here: https://godbolt.org/z/cdbdeMcaT
This patch fixes the crash.