diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp index 568cbdb06bb48..d6d226b3f75db 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp @@ -280,6 +280,7 @@ class AggExprEmitter : public StmtVisitor { void VisitUnaryDeref(UnaryOperator *e) { emitAggLoadOfLValue(e); } void VisitStringLiteral(StringLiteral *e) { emitAggLoadOfLValue(e); } void VisitCompoundLiteralExpr(CompoundLiteralExpr *e); + void VisitPredefinedExpr(const PredefinedExpr *e) { cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitPredefinedExpr"); @@ -670,7 +671,7 @@ void AggExprEmitter::emitNullInitializationToLValue(mlir::Location loc, return; } - cgf.cgm.errorNYI("emitStoreThroughBitfieldLValue"); + cgf.emitStoreThroughBitfieldLValue(RValue::get(null), lv); return; } diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 138082b59fecd..33eb748d72219 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -2041,8 +2041,9 @@ mlir::Value ScalarExprEmitter::VisitMemberExpr(MemberExpr *e) { assert(!cir::MissingFeatures::tryEmitAsConstant()); Expr::EvalResult result; if (e->EvaluateAsInt(result, cgf.getContext(), Expr::SE_AllowSideEffects)) { - cgf.cgm.errorNYI(e->getSourceRange(), "Constant interger member expr"); - // Fall through to emit this as a non-constant access. + llvm::APSInt value = result.Val.getInt(); + cgf.emitIgnoredExpr(e->getBase()); + return builder.getConstInt(cgf.getLoc(e->getExprLoc()), value); } return emitLoadOfLValue(e); } diff --git a/clang/test/CIR/CodeGen/struct.cpp b/clang/test/CIR/CodeGen/struct.cpp index 6d362c79c1c44..c8db71498e477 100644 --- a/clang/test/CIR/CodeGen/struct.cpp +++ b/clang/test/CIR/CodeGen/struct.cpp @@ -280,3 +280,67 @@ void bin_comma() { // OGCG: define{{.*}} void @_Z9bin_commav() // OGCG: %[[A_ADDR:.*]] = alloca %struct.CompleteS, align 4 // OGCG: call void @llvm.memset.p0.i64(ptr align 4 %[[A_ADDR]], i8 0, i64 8, i1 false) + +void compound_literal_expr() { CompleteS a = (CompleteS){}; } + +// CIR: %[[A_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr, ["a", init] +// CIR: %[[A_ELEM_0_PTR:.*]] = cir.get_member %[[A_ADDR]][0] {name = "a"} : !cir.ptr -> !cir.ptr +// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i +// CIR: cir.store{{.*}} %[[CONST_0]], %[[A_ELEM_0_PTR]] : !s32i, !cir.ptr +// CIR: %[[A_ELEM_1_PTR:.*]] = cir.get_member %[[A_ADDR]][1] {name = "b"} : !cir.ptr -> !cir.ptr +// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s8i +// CIR: cir.store{{.*}} %[[CONST_0]], %[[A_ELEM_1_PTR]] : !s8i, !cir.ptr + +// TODO(cir): zero-initialize the padding + +// LLVM: %[[A_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4 +// LLVM: %[[A_ELEM_0_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[A_ADDR]], i32 0, i32 0 +// LLVM: store i32 0, ptr %[[A_ELEM_0_PTR]], align 4 +// LLVM: %[[A_ELEM_1_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[A_ADDR]], i32 0, i32 1 +// LLVM: store i8 0, ptr %[[A_ELEM_1_PTR]], align 4 + +// OGCG: %[[A_ADDR:.*]] = alloca %struct.CompleteS, align 4 +// OGCG: call void @llvm.memset.p0.i64(ptr align 4 %[[A_ADDR]], i8 0, i64 8, i1 false) + +struct StructWithConstMember { + int a : 1; +}; + +void struct_with_const_member_expr() { + int a = (StructWithConstMember){}.a; +} + +// CIR: %[[A_ADDR:.*]] = cir.alloca !s32i, !cir.ptr, ["a", init] +// CIR: %[[RESULT:.*]] = cir.scope { +// CIR: %[[REF_ADDR:.*]] = cir.alloca !rec_StructWithConstMember, !cir.ptr, ["ref.tmp0"] +// CIR: %[[ELEM_0_PTR:.*]] = cir.get_member %[[REF_ADDR]][0] {name = "a"} : !cir.ptr -> !cir.ptr +// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i +// CIR: %[[SET_BF:.*]] = cir.set_bitfield{{.*}} (#bfi_a, %[[ELEM_0_PTR]] : !cir.ptr, %[[CONST_0]] : !s32i) -> !s32i +// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i +// CIR: cir.yield %[[CONST_0]] : !s32i +// CIR: } : !s32i +// CIR: cir.store{{.*}} %[[RESULT]], %[[A_ADDR]] : !s32i, !cir.ptr + +// TODO(cir): zero-initialize the padding + +// LLVM: %[[REF_ADDR:.*]] = alloca %struct.StructWithConstMember, i64 1, align 4 +// LLVM: %[[A_ADDR:.*]] = alloca i32, i64 1, align 4 +// LLVM: br label %[[BF_LABEL:.*]] +// LLVM: [[BF_LABEL]]: +// LLVM: %[[ELEM_0_PTR:.*]] = getelementptr %struct.StructWithConstMember, ptr %[[REF_ADDR]], i32 0, i32 0 +// LLVM: %[[TMP_REF:.*]] = load i8, ptr %[[ELEM_0_PTR]], align 4 +// LLVM: %[[BF_CLEAR:.*]] = and i8 %[[TMP_REF]], -2 +// LLVM: %[[BF_SET:.*]] = or i8 %[[BF_CLEAR]], 0 +// LLVM: store i8 %[[BF_SET]], ptr %[[ELEM_0_PTR]], align 4 +// LLVM: br label %[[RESULT_LABEL:.*]] +// LLVM: [[RESULT_LABEL]]: +// LLVM: %[[RESULT:.*]] = phi i32 [ 0, %[[BF_LABEL]] ] +// LLVM: store i32 %[[RESULT]], ptr %[[A_ADDR]], align 4 + +// OGCG: %[[A_ADDR:.*]] = alloca i32, align 4 +// OGCG: %[[REF_ADDR:.*]] = alloca %struct.StructWithConstMember, align 4 +// OGCG: %[[TMP_REF:.*]] = load i8, ptr %[[REF_ADDR]], align 4 +// OGCG: %[[BF_CLEAR:.*]] = and i8 %[[TMP_REF]], -2 +// OGCG: %[[BF_SET:.*]] = or i8 %[[BF_CLEAR]], 0 +// OGCG: store i8 %[[BF_SET]], ptr %[[REF_ADDR]], align 4 +// OGCG: store i32 0, ptr %[[A_ADDR]], align 4