Skip to content

Commit e33f721

Browse files
authored
[CIR] Backport MemberExpr support for ComplexType (#1838)
Backporting MemberExpr support for ComplexType from the upstream
1 parent 87b772a commit e33f721

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3272,7 +3272,9 @@ CIRGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) {
32723272

32733273
CIRGenFunction::ConstantEmission
32743274
CIRGenFunction::tryEmitAsConstant(const MemberExpr *ME) {
3275-
llvm_unreachable("NYI");
3275+
if (DeclRefExpr *dre = tryToConvertMemberExprToDeclRefExpr(*this, ME))
3276+
return tryEmitAsConstant(dre);
3277+
return ConstantEmission();
32763278
}
32773279

32783280
mlir::Value CIRGenFunction::emitScalarConstant(

clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,14 @@ class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
109109
llvm_unreachable("NYI");
110110
}
111111
mlir::Value VisitArraySubscriptExpr(Expr *E) { return emitLoadOfLValue(E); }
112-
mlir::Value VisitMemberExpr(MemberExpr *ME) { llvm_unreachable("NYI"); }
112+
113+
mlir::Value VisitMemberExpr(MemberExpr *ME) {
114+
if (CIRGenFunction::ConstantEmission constant = CGF.tryEmitAsConstant(ME)) {
115+
llvm_unreachable("VisitMemberExpr tryEmitAsConstant");
116+
}
117+
return emitLoadOfLValue(ME);
118+
}
119+
113120
mlir::Value VisitOpaqueValueExpr(OpaqueValueExpr *E) {
114121
llvm_unreachable("NYI");
115122
}

clang/test/CIR/CodeGen/complex.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,29 @@ int _Complex complex_real_operator_on_rvalue() {
102102
// LLVM: %[[TMP_RET:.*]] = load { i32, i32 }, ptr %[[RET_ADDR]], align 4
103103
// LLVM: ret { i32, i32 } %[[TMP_RET]]
104104

105+
void complex_member_expr() {
106+
struct Wrapper {
107+
int _Complex c;
108+
};
109+
110+
Wrapper w;
111+
int r = __real__ w.c;
112+
}
113+
114+
// CIR: %[[W_ADDR:.*]] = cir.alloca !rec_Wrapper, !cir.ptr<!rec_Wrapper>, ["w"]
115+
// CIR: %[[REAL_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["r", init]
116+
// CIR: %[[ELEM_PTR:.*]] = cir.get_member %[[W_ADDR]][0] {name = "c"} : !cir.ptr<!rec_Wrapper> -> !cir.ptr<!cir.complex<!s32i>>
117+
// CIR: %[[TMP_ELEM_PTR:.*]] = cir.load{{.*}} %[[ELEM_PTR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
118+
// CIR: %[[REAL:.*]] = cir.complex.real %[[TMP_ELEM_PTR]] : !cir.complex<!s32i> -> !s32i
119+
// CIR: cir.store{{.*}} %[[REAL]], %[[REAL_ADDR]] : !s32i, !cir.ptr<!s32i>
120+
121+
// LLVM: %[[W_ADDR:.*]] = alloca %struct.Wrapper, i64 1, align 4
122+
// LLVM: %[[REAL_ADDR:.*]] = alloca i32, i64 1, align 4
123+
// LLVM: %[[ELEM_PTR:.*]] = getelementptr %struct.Wrapper, ptr %[[W_ADDR]], i32 0, i32 0
124+
// LLVM: %[[TMP_ELEM_PTR:.*]] = load { i32, i32 }, ptr %[[ELEM_PTR]], align 4
125+
// LLVM: %[[REAL:.*]] = extractvalue { i32, i32 } %[[TMP_ELEM_PTR]], 0
126+
// LLVM: store i32 %[[REAL]], ptr %[[REAL_ADDR]], align 4
127+
105128
int _Complex complex_imag_operator_on_rvalue() {
106129
int imag = __imag__ complex_imag_operator_on_rvalue();
107130
return {};

0 commit comments

Comments
 (0)