Skip to content

Commit 44eeec2

Browse files
authored
[CIR] Implement support for __imag__ operator on complex rvalue (#1837)
Implement support for imag operator on complex rvalue
1 parent 73a1669 commit 44eeec2

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2076,16 +2076,18 @@ mlir::Value ScalarExprEmitter::VisitImag(const UnaryOperator *E) {
20762076

20772077
Expr *Op = E->getSubExpr();
20782078
if (Op->getType()->isAnyComplexType()) {
2079+
mlir::Location Loc = CGF.getLoc(E->getExprLoc());
2080+
20792081
// If it's an l-value, load through the appropriate subobject l-value.
20802082
// Note that we have to ask E because Op might be an l-value that
20812083
// this won't work for, e.g. an Obj-C property.
20822084
if (E->isGLValue()) {
2083-
mlir::Location Loc = CGF.getLoc(E->getExprLoc());
20842085
mlir::Value Complex = CGF.emitComplexExpr(Op);
20852086
return CGF.builder.createComplexImag(Loc, Complex);
20862087
}
2088+
20872089
// Otherwise, calculate and project.
2088-
llvm_unreachable("NYI");
2090+
return Builder.createComplexImag(Loc, CGF.emitComplexExpr(Op));
20892091
}
20902092

20912093
return Visit(Op);

clang/test/CIR/CodeGen/complex.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,27 @@ int _Complex complex_real_operator_on_rvalue() {
101101
// LLVM: store { i32, i32 } zeroinitializer, ptr %[[RET_ADDR]], align 4
102102
// LLVM: %[[TMP_RET:.*]] = load { i32, i32 }, ptr %[[RET_ADDR]], align 4
103103
// LLVM: ret { i32, i32 } %[[TMP_RET]]
104+
105+
int _Complex complex_imag_operator_on_rvalue() {
106+
int imag = __imag__ complex_imag_operator_on_rvalue();
107+
return {};
108+
}
109+
110+
// CIR: %[[RET_ADDR:.*]] = cir.alloca !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>, ["__retval"]
111+
// CIR: %[[IMAG_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["imag", init]
112+
// CIR: %[[CALL:.*]] = cir.call @_Z31complex_imag_operator_on_rvaluev() : () -> !cir.complex<!s32i>
113+
// CIR: %[[IMAG:.*]] = cir.complex.imag %[[CALL]] : !cir.complex<!s32i> -> !s32i
114+
// CIR: cir.store{{.*}} %[[IMAG]], %[[IMAG_ADDR]] : !s32i, !cir.ptr<!s32i>
115+
// CIR: %[[RET_COMPLEX:.*]] = cir.const #cir.complex<#cir.int<0> : !s32i, #cir.int<0> : !s32i> : !cir.complex<!s32i>
116+
// CIR: cir.store{{.*}} %[[RET_COMPLEX]], %[[RET_ADDR]] : !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>
117+
// CIR: %[[TMP_RET:.*]] = cir.load %[[RET_ADDR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
118+
// CIR: cir.return %[[TMP_RET]] : !cir.complex<!s32i>
119+
120+
// LLVM: %[[RET_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 4
121+
// LLVM: %[[IMAG_ADDR:.*]] = alloca i32, i64 1, align 4
122+
// LLVM: %[[CALL:.*]] = call { i32, i32 } @_Z31complex_imag_operator_on_rvaluev()
123+
// LLVM: %[[IMAG:.*]] = extractvalue { i32, i32 } %[[CALL]], 1
124+
// LLVM: store i32 %[[IMAG]], ptr %[[IMAG_ADDR]], align 4
125+
// LLVM: store { i32, i32 } zeroinitializer, ptr %[[RET_ADDR]], align 4
126+
// LLVM: %[[TMP_RET:.*]] = load { i32, i32 }, ptr %[[RET_ADDR]], align 4
127+
// LLVM: ret { i32, i32 } %[[TMP_RET]]

0 commit comments

Comments
 (0)