[CIR] Implement MemberExpr support for ComplexType (#154027)
This change adds support for the MemberExpr ComplexType Issue: https://github.com/llvm/llvm-project/issues/141365
This commit is contained in:
parent
13d8ba7dea
commit
5581e34bd9
@ -2067,8 +2067,8 @@ cir::AllocaOp CIRGenFunction::createTempAlloca(mlir::Type ty,
|
|||||||
///
|
///
|
||||||
/// For named members of enums, this is the only way they are emitted.
|
/// For named members of enums, this is the only way they are emitted.
|
||||||
CIRGenFunction::ConstantEmission
|
CIRGenFunction::ConstantEmission
|
||||||
CIRGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) {
|
CIRGenFunction::tryEmitAsConstant(const DeclRefExpr *refExpr) {
|
||||||
ValueDecl *value = refExpr->getDecl();
|
const ValueDecl *value = refExpr->getDecl();
|
||||||
|
|
||||||
// There is a lot more to do here, but for now only EnumConstantDecl is
|
// There is a lot more to do here, but for now only EnumConstantDecl is
|
||||||
// supported.
|
// supported.
|
||||||
@ -2101,6 +2101,25 @@ CIRGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) {
|
|||||||
return ConstantEmission::forValue(cstToEmit);
|
return ConstantEmission::forValue(cstToEmit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DeclRefExpr *tryToConvertMemberExprToDeclRefExpr(CIRGenFunction &cgf,
|
||||||
|
const MemberExpr *me) {
|
||||||
|
if (auto *vd = dyn_cast<VarDecl>(me->getMemberDecl())) {
|
||||||
|
// Try to emit static variable member expressions as DREs.
|
||||||
|
return DeclRefExpr::Create(
|
||||||
|
cgf.getContext(), NestedNameSpecifierLoc(), SourceLocation(), vd,
|
||||||
|
/*RefersToEnclosingVariableOrCapture=*/false, me->getExprLoc(),
|
||||||
|
me->getType(), me->getValueKind(), nullptr, nullptr, me->isNonOdrUse());
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
CIRGenFunction::ConstantEmission
|
||||||
|
CIRGenFunction::tryEmitAsConstant(const MemberExpr *me) {
|
||||||
|
if (DeclRefExpr *dre = tryToConvertMemberExprToDeclRefExpr(*this, me))
|
||||||
|
return tryEmitAsConstant(dre);
|
||||||
|
return ConstantEmission();
|
||||||
|
}
|
||||||
|
|
||||||
mlir::Value CIRGenFunction::emitScalarConstant(
|
mlir::Value CIRGenFunction::emitScalarConstant(
|
||||||
const CIRGenFunction::ConstantEmission &constant, Expr *e) {
|
const CIRGenFunction::ConstantEmission &constant, Expr *e) {
|
||||||
assert(constant && "not a constant");
|
assert(constant && "not a constant");
|
||||||
|
@ -62,6 +62,14 @@ public:
|
|||||||
mlir::Value VisitImplicitCastExpr(ImplicitCastExpr *e);
|
mlir::Value VisitImplicitCastExpr(ImplicitCastExpr *e);
|
||||||
mlir::Value VisitInitListExpr(InitListExpr *e);
|
mlir::Value VisitInitListExpr(InitListExpr *e);
|
||||||
|
|
||||||
|
mlir::Value VisitMemberExpr(MemberExpr *me) {
|
||||||
|
if (CIRGenFunction::ConstantEmission constant = cgf.tryEmitAsConstant(me)) {
|
||||||
|
cgf.cgm.errorNYI("VisitMemberExpr tryEmitAsConstant");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return emitLoadOfLValue(me);
|
||||||
|
}
|
||||||
|
|
||||||
mlir::Value VisitCompoundLiteralExpr(CompoundLiteralExpr *e) {
|
mlir::Value VisitCompoundLiteralExpr(CompoundLiteralExpr *e) {
|
||||||
return emitLoadOfLValue(e);
|
return emitLoadOfLValue(e);
|
||||||
}
|
}
|
||||||
|
@ -452,7 +452,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr);
|
ConstantEmission tryEmitAsConstant(const DeclRefExpr *refExpr);
|
||||||
|
ConstantEmission tryEmitAsConstant(const MemberExpr *me);
|
||||||
|
|
||||||
struct AutoVarEmission {
|
struct AutoVarEmission {
|
||||||
const clang::VarDecl *Variable;
|
const clang::VarDecl *Variable;
|
||||||
|
@ -799,3 +799,33 @@ void foo30() {
|
|||||||
// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[A_ADDR]], i32 0, i32 1
|
// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[A_ADDR]], i32 0, i32 1
|
||||||
// OGCG: store float 1.000000e+00, ptr %[[A_REAL_PTR]], align 4
|
// OGCG: store float 1.000000e+00, ptr %[[A_REAL_PTR]], align 4
|
||||||
// OGCG: store float 0.000000e+00, ptr %[[A_IMAG_PTR]], align 4
|
// OGCG: store float 0.000000e+00, ptr %[[A_IMAG_PTR]], align 4
|
||||||
|
|
||||||
|
void foo31() {
|
||||||
|
struct Wrapper {
|
||||||
|
int _Complex c;
|
||||||
|
};
|
||||||
|
|
||||||
|
Wrapper w;
|
||||||
|
int r = __real__ w.c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CIR: %[[W_ADDR:.*]] = cir.alloca !rec_Wrapper, !cir.ptr<!rec_Wrapper>, ["w"]
|
||||||
|
// CIR: %[[REAL_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["r", init]
|
||||||
|
// CIR: %[[ELEM_PTR:.*]] = cir.get_member %[[W_ADDR]][0] {name = "c"} : !cir.ptr<!rec_Wrapper> -> !cir.ptr<!cir.complex<!s32i>>
|
||||||
|
// CIR: %[[TMP_ELEM_PTR:.*]] = cir.load{{.*}} %[[ELEM_PTR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
|
||||||
|
// CIR: %[[REAL:.*]] = cir.complex.real %[[TMP_ELEM_PTR]] : !cir.complex<!s32i> -> !s32i
|
||||||
|
// CIR: cir.store{{.*}} %[[REAL]], %[[REAL_ADDR]] : !s32i, !cir.ptr<!s32i>
|
||||||
|
|
||||||
|
// LLVM: %[[W_ADDR:.*]] = alloca %struct.Wrapper, i64 1, align 4
|
||||||
|
// LLVM: %[[REAL_ADDR:.*]] = alloca i32, i64 1, align 4
|
||||||
|
// LLVM: %[[ELEM_PTR:.*]] = getelementptr %struct.Wrapper, ptr %[[W_ADDR]], i32 0, i32 0
|
||||||
|
// LLVM: %[[TMP_ELEM_PTR:.*]] = load { i32, i32 }, ptr %[[ELEM_PTR]], align 4
|
||||||
|
// LLVM: %[[REAL:.*]] = extractvalue { i32, i32 } %[[TMP_ELEM_PTR]], 0
|
||||||
|
// LLVM: store i32 %[[REAL]], ptr %[[REAL_ADDR]], align 4
|
||||||
|
|
||||||
|
// OGCG: %[[W_ADDR:.*]] = alloca %struct.Wrapper, align 4
|
||||||
|
// OGCG: %[[REAL_ADDR:.*]] = alloca i32, align 4
|
||||||
|
// OGCG: %[[ELEM_PTR:.*]] = getelementptr inbounds nuw %struct.Wrapper, ptr %[[W_ADDR]], i32 0, i32 0
|
||||||
|
// OGCG: %[[REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[ELEM_PTR]], i32 0, i32 0
|
||||||
|
// OGCG: %[[REAL:.*]] = load i32, ptr %[[REAL_PTR]], align 4
|
||||||
|
// OGCG: store i32 %[[REAL]], ptr %[[REAL_ADDR]], align 4
|
||||||
|
Loading…
x
Reference in New Issue
Block a user