Skip to content

Commit fa67568

Browse files
committed
[CIR] Upstream __imag__ for ComplexType
1 parent 9cbbfd2 commit fa67568

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,7 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
604604
mlir::Value VisitUnaryLNot(const UnaryOperator *e);
605605

606606
mlir::Value VisitUnaryReal(const UnaryOperator *e);
607+
mlir::Value VisitUnaryImag(const UnaryOperator *e);
607608

608609
mlir::Value VisitCXXThisExpr(CXXThisExpr *te) { return cgf.loadCXXThis(); }
609610

@@ -1912,6 +1913,25 @@ mlir::Value ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *e) {
19121913
return Visit(op);
19131914
}
19141915

1916+
mlir::Value ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *e) {
1917+
// TODO(cir): handle scalar promotion.
1918+
Expr *op = e->getSubExpr();
1919+
if (op->getType()->isAnyComplexType()) {
1920+
// If it's an l-value, load through the appropriate subobject l-value.
1921+
// Note that we have to ask E because Op might be an l-value that
1922+
// this won't work for, e.g. an Obj-C property.
1923+
if (e->isGLValue())
1924+
return cgf.emitLoadOfLValue(cgf.emitLValue(e), e->getExprLoc())
1925+
.getScalarVal();
1926+
1927+
// Otherwise, calculate and project.
1928+
cgf.cgm.errorNYI(e->getSourceRange(),
1929+
"VisitUnaryImag calculate and project");
1930+
}
1931+
1932+
return Visit(op);
1933+
}
1934+
19151935
/// Return the size or alignment of the type of argument of the sizeof
19161936
/// expression as an integer.
19171937
mlir::Value ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(

clang/test/CIR/CodeGen/complex.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,26 @@ void foo12() {
226226
// OGCG: %[[REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 0
227227
// OGCG: %[[REAL:.*]] = load double, ptr %[[REAL_PTR]], align 8
228228
// OGCG: store double %[[REAL]], ptr %[[INIT]], align 8
229+
230+
void foo13() {
231+
double _Complex c;
232+
double imag = __imag__ c;
233+
}
234+
235+
// CIR: %[[COMPLEX:.*]] = cir.alloca !cir.complex<!cir.double>, !cir.ptr<!cir.complex<!cir.double>>, ["c"]
236+
// CIR: %[[INIT:.*]] = cir.alloca !cir.double, !cir.ptr<!cir.double>, ["imag", init]
237+
// CIR: %[[IMAG_PTR:.*]] = cir.complex.imag_ptr %[[COMPLEX]] : !cir.ptr<!cir.complex<!cir.double>> -> !cir.ptr<!cir.double>
238+
// CIR: %[[IMAG:.*]] = cir.load{{.*}} %[[REAL_PTR]] : !cir.ptr<!cir.double>, !cir.double
239+
// CIR: cir.store{{.*}} %[[IMAG]], %[[INIT]] : !cir.double, !cir.ptr<!cir.double>
240+
241+
// LLVM: %[[COMPLEX:.*]] = alloca { double, double }, i64 1, align 8
242+
// LLVM: %[[INIT:.*]] = alloca double, i64 1, align 8
243+
// LLVM: %[[IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 1
244+
// LLVM: %[[IMAG:.*]] = load double, ptr %[[IMAG_PTR]], align 8
245+
// LLVM: store double %[[IMAG]], ptr %[[INIT]], align 8
246+
247+
// OGCG: %[[COMPLEX:.*]] = alloca { double, double }, align 8
248+
// OGCG: %[[INIT:.*]] = alloca double, align 8
249+
// OGCG: %[[IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 1
250+
// OGCG: %[[IMAG:.*]] = load double, ptr %[[IMAG_PTR]], align 8
251+
// OGCG: store double %[[IMAG]], ptr %[[INIT]], align 8

0 commit comments

Comments
 (0)