Skip to content

Commit d8b4f9f

Browse files
AmrDeveloperaokblast
authored andcommitted
[CIR] Const member expr for struct type (llvm#164172)
Upstream support the const member expr for struct type
1 parent 764c614 commit d8b4f9f

File tree

3 files changed

+69
-3
lines changed

3 files changed

+69
-3
lines changed

clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
280280
void VisitUnaryDeref(UnaryOperator *e) { emitAggLoadOfLValue(e); }
281281
void VisitStringLiteral(StringLiteral *e) { emitAggLoadOfLValue(e); }
282282
void VisitCompoundLiteralExpr(CompoundLiteralExpr *e);
283+
283284
void VisitPredefinedExpr(const PredefinedExpr *e) {
284285
cgf.cgm.errorNYI(e->getSourceRange(),
285286
"AggExprEmitter: VisitPredefinedExpr");
@@ -670,7 +671,7 @@ void AggExprEmitter::emitNullInitializationToLValue(mlir::Location loc,
670671
return;
671672
}
672673

673-
cgf.cgm.errorNYI("emitStoreThroughBitfieldLValue");
674+
cgf.emitStoreThroughBitfieldLValue(RValue::get(null), lv);
674675
return;
675676
}
676677

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2041,8 +2041,9 @@ mlir::Value ScalarExprEmitter::VisitMemberExpr(MemberExpr *e) {
20412041
assert(!cir::MissingFeatures::tryEmitAsConstant());
20422042
Expr::EvalResult result;
20432043
if (e->EvaluateAsInt(result, cgf.getContext(), Expr::SE_AllowSideEffects)) {
2044-
cgf.cgm.errorNYI(e->getSourceRange(), "Constant interger member expr");
2045-
// Fall through to emit this as a non-constant access.
2044+
llvm::APSInt value = result.Val.getInt();
2045+
cgf.emitIgnoredExpr(e->getBase());
2046+
return builder.getConstInt(cgf.getLoc(e->getExprLoc()), value);
20462047
}
20472048
return emitLoadOfLValue(e);
20482049
}

clang/test/CIR/CodeGen/struct.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,3 +280,67 @@ void bin_comma() {
280280
// OGCG: define{{.*}} void @_Z9bin_commav()
281281
// OGCG: %[[A_ADDR:.*]] = alloca %struct.CompleteS, align 4
282282
// OGCG: call void @llvm.memset.p0.i64(ptr align 4 %[[A_ADDR]], i8 0, i64 8, i1 false)
283+
284+
void compound_literal_expr() { CompleteS a = (CompleteS){}; }
285+
286+
// CIR: %[[A_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["a", init]
287+
// CIR: %[[A_ELEM_0_PTR:.*]] = cir.get_member %[[A_ADDR]][0] {name = "a"} : !cir.ptr<!rec_CompleteS> -> !cir.ptr<!s32i>
288+
// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i
289+
// CIR: cir.store{{.*}} %[[CONST_0]], %[[A_ELEM_0_PTR]] : !s32i, !cir.ptr<!s32i>
290+
// CIR: %[[A_ELEM_1_PTR:.*]] = cir.get_member %[[A_ADDR]][1] {name = "b"} : !cir.ptr<!rec_CompleteS> -> !cir.ptr<!s8i>
291+
// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s8i
292+
// CIR: cir.store{{.*}} %[[CONST_0]], %[[A_ELEM_1_PTR]] : !s8i, !cir.ptr<!s8i>
293+
294+
// TODO(cir): zero-initialize the padding
295+
296+
// LLVM: %[[A_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4
297+
// LLVM: %[[A_ELEM_0_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[A_ADDR]], i32 0, i32 0
298+
// LLVM: store i32 0, ptr %[[A_ELEM_0_PTR]], align 4
299+
// LLVM: %[[A_ELEM_1_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[A_ADDR]], i32 0, i32 1
300+
// LLVM: store i8 0, ptr %[[A_ELEM_1_PTR]], align 4
301+
302+
// OGCG: %[[A_ADDR:.*]] = alloca %struct.CompleteS, align 4
303+
// OGCG: call void @llvm.memset.p0.i64(ptr align 4 %[[A_ADDR]], i8 0, i64 8, i1 false)
304+
305+
struct StructWithConstMember {
306+
int a : 1;
307+
};
308+
309+
void struct_with_const_member_expr() {
310+
int a = (StructWithConstMember){}.a;
311+
}
312+
313+
// CIR: %[[A_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]
314+
// CIR: %[[RESULT:.*]] = cir.scope {
315+
// CIR: %[[REF_ADDR:.*]] = cir.alloca !rec_StructWithConstMember, !cir.ptr<!rec_StructWithConstMember>, ["ref.tmp0"]
316+
// CIR: %[[ELEM_0_PTR:.*]] = cir.get_member %[[REF_ADDR]][0] {name = "a"} : !cir.ptr<!rec_StructWithConstMember> -> !cir.ptr<!u8i>
317+
// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i
318+
// CIR: %[[SET_BF:.*]] = cir.set_bitfield{{.*}} (#bfi_a, %[[ELEM_0_PTR]] : !cir.ptr<!u8i>, %[[CONST_0]] : !s32i) -> !s32i
319+
// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i
320+
// CIR: cir.yield %[[CONST_0]] : !s32i
321+
// CIR: } : !s32i
322+
// CIR: cir.store{{.*}} %[[RESULT]], %[[A_ADDR]] : !s32i, !cir.ptr<!s32i>
323+
324+
// TODO(cir): zero-initialize the padding
325+
326+
// LLVM: %[[REF_ADDR:.*]] = alloca %struct.StructWithConstMember, i64 1, align 4
327+
// LLVM: %[[A_ADDR:.*]] = alloca i32, i64 1, align 4
328+
// LLVM: br label %[[BF_LABEL:.*]]
329+
// LLVM: [[BF_LABEL]]:
330+
// LLVM: %[[ELEM_0_PTR:.*]] = getelementptr %struct.StructWithConstMember, ptr %[[REF_ADDR]], i32 0, i32 0
331+
// LLVM: %[[TMP_REF:.*]] = load i8, ptr %[[ELEM_0_PTR]], align 4
332+
// LLVM: %[[BF_CLEAR:.*]] = and i8 %[[TMP_REF]], -2
333+
// LLVM: %[[BF_SET:.*]] = or i8 %[[BF_CLEAR]], 0
334+
// LLVM: store i8 %[[BF_SET]], ptr %[[ELEM_0_PTR]], align 4
335+
// LLVM: br label %[[RESULT_LABEL:.*]]
336+
// LLVM: [[RESULT_LABEL]]:
337+
// LLVM: %[[RESULT:.*]] = phi i32 [ 0, %[[BF_LABEL]] ]
338+
// LLVM: store i32 %[[RESULT]], ptr %[[A_ADDR]], align 4
339+
340+
// OGCG: %[[A_ADDR:.*]] = alloca i32, align 4
341+
// OGCG: %[[REF_ADDR:.*]] = alloca %struct.StructWithConstMember, align 4
342+
// OGCG: %[[TMP_REF:.*]] = load i8, ptr %[[REF_ADDR]], align 4
343+
// OGCG: %[[BF_CLEAR:.*]] = and i8 %[[TMP_REF]], -2
344+
// OGCG: %[[BF_SET:.*]] = or i8 %[[BF_CLEAR]], 0
345+
// OGCG: store i8 %[[BF_SET]], ptr %[[REF_ADDR]], align 4
346+
// OGCG: store i32 0, ptr %[[A_ADDR]], align 4

0 commit comments

Comments
 (0)