Skip to content

Commit 9cbbfd2

Browse files
committed
[CIR] Upstream __real__ for ComplexType
1 parent dc824e4 commit 9cbbfd2

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,8 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
603603

604604
mlir::Value VisitUnaryLNot(const UnaryOperator *e);
605605

606+
mlir::Value VisitUnaryReal(const UnaryOperator *e);
607+
606608
mlir::Value VisitCXXThisExpr(CXXThisExpr *te) { return cgf.loadCXXThis(); }
607609

608610
/// Emit a conversion from the specified type to the specified destination
@@ -1891,6 +1893,25 @@ mlir::Value ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *e) {
18911893
return maybePromoteBoolResult(boolVal, cgf.convertType(e->getType()));
18921894
}
18931895

1896+
mlir::Value ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *e) {
1897+
// TODO(cir): handle scalar promotion.
1898+
Expr *op = e->getSubExpr();
1899+
if (op->getType()->isAnyComplexType()) {
1900+
// If it's an l-value, load through the appropriate subobject l-value.
1901+
// Note that we have to ask E because Op might be an l-value that
1902+
// this won't work for, e.g. an Obj-C property.
1903+
if (e->isGLValue())
1904+
return cgf.emitLoadOfLValue(cgf.emitLValue(e), e->getExprLoc())
1905+
.getScalarVal();
1906+
1907+
// Otherwise, calculate and project.
1908+
cgf.cgm.errorNYI(e->getSourceRange(),
1909+
"VisitUnaryReal calculate and project");
1910+
}
1911+
1912+
return Visit(op);
1913+
}
1914+
18941915
/// Return the size or alignment of the type of argument of the sizeof
18951916
/// expression as an integer.
18961917
mlir::Value ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(

clang/test/CIR/CodeGen/complex.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,26 @@ void foo11() {
203203

204204
// OGCG: %[[COMPLEX:.*]] = alloca { double, double }, align 8
205205
// OGCG: %[[IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 1
206+
207+
void foo12() {
208+
double _Complex c;
209+
double real = __real__ c;
210+
}
211+
212+
// CIR: %[[COMPLEX:.*]] = cir.alloca !cir.complex<!cir.double>, !cir.ptr<!cir.complex<!cir.double>>, ["c"]
213+
// CIR: %[[INIT:.*]] = cir.alloca !cir.double, !cir.ptr<!cir.double>, ["real", init]
214+
// CIR: %[[REAL_PTR:.*]] = cir.complex.real_ptr %[[COMPLEX]] : !cir.ptr<!cir.complex<!cir.double>> -> !cir.ptr<!cir.double>
215+
// CIR: %[[REAL:.*]] = cir.load{{.*}} %[[REAL_PTR]] : !cir.ptr<!cir.double>, !cir.double
216+
// CIR: cir.store{{.*}} %[[REAL]], %[[INIT]] : !cir.double, !cir.ptr<!cir.double>
217+
218+
// LLVM: %[[COMPLEX:.*]] = alloca { double, double }, i64 1, align 8
219+
// LLVM: %[[INIT:.*]] = alloca double, i64 1, align 8
220+
// LLVM: %[[REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 0
221+
// LLVM: %[[REAL:.*]] = load double, ptr %[[REAL_PTR]], align 8
222+
// LLVM: store double %[[REAL]], ptr %[[INIT]], align 8
223+
224+
// OGCG: %[[COMPLEX:.*]] = alloca { double, double }, align 8
225+
// OGCG: %[[INIT:.*]] = alloca double, align 8
226+
// OGCG: %[[REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 0
227+
// OGCG: %[[REAL:.*]] = load double, ptr %[[REAL_PTR]], align 8
228+
// OGCG: store double %[[REAL]], ptr %[[INIT]], align 8

0 commit comments

Comments
 (0)