Skip to content

Commit afb2454

Browse files
author
git apple-llvm automerger
committed
Merge commit '952d4b4c0bc9' from llvm.org/main into next
2 parents 3f6b2e7 + 952d4b4 commit afb2454

File tree

4 files changed

+126
-6
lines changed

4 files changed

+126
-6
lines changed

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1630,7 +1630,7 @@ RValue CIRGenFunction::emitAnyExpr(const Expr *e, AggValueSlot aggSlot,
16301630
bool ignoreResult) {
16311631
switch (CIRGenFunction::getEvaluationKind(e->getType())) {
16321632
case cir::TEK_Scalar:
1633-
return RValue::get(emitScalarExpr(e));
1633+
return RValue::get(emitScalarExpr(e, ignoreResult));
16341634
case cir::TEK_Complex:
16351635
return RValue::getComplex(emitComplexExpr(e));
16361636
case cir::TEK_Aggregate: {

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,15 @@ struct BinOpInfo {
7878
class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
7979
CIRGenFunction &cgf;
8080
CIRGenBuilderTy &builder;
81+
// Unlike classic codegen we set this to false or use std::exchange to read
82+
// the value instead of calling TestAndClearIgnoreResultAssign to make it
83+
// explicit when the value is used
8184
bool ignoreResultAssign;
8285

8386
public:
84-
ScalarExprEmitter(CIRGenFunction &cgf, CIRGenBuilderTy &builder)
85-
: cgf(cgf), builder(builder) {}
87+
ScalarExprEmitter(CIRGenFunction &cgf, CIRGenBuilderTy &builder,
88+
bool ignoreResultAssign = false)
89+
: cgf(cgf), builder(builder), ignoreResultAssign(ignoreResultAssign) {}
8690

8791
//===--------------------------------------------------------------------===//
8892
// Utilities
@@ -221,6 +225,8 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
221225
}
222226

223227
mlir::Value VisitArraySubscriptExpr(ArraySubscriptExpr *e) {
228+
ignoreResultAssign = false;
229+
224230
if (e->getBase()->getType()->isVectorType()) {
225231
assert(!cir::MissingFeatures::scalableVectors());
226232

@@ -839,6 +845,7 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
839845

840846
BinOpInfo emitBinOps(const BinaryOperator *e,
841847
QualType promotionType = QualType()) {
848+
ignoreResultAssign = false;
842849
BinOpInfo result;
843850
result.lhs = cgf.emitPromotedScalarExpr(e->getLHS(), promotionType);
844851
result.rhs = cgf.emitPromotedScalarExpr(e->getRHS(), promotionType);
@@ -924,6 +931,7 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
924931
#undef HANDLEBINOP
925932

926933
mlir::Value emitCmp(const BinaryOperator *e) {
934+
ignoreResultAssign = false;
927935
const mlir::Location loc = cgf.getLoc(e->getExprLoc());
928936
mlir::Value result;
929937
QualType lhsTy = e->getLHS()->getType();
@@ -1406,11 +1414,13 @@ CIRGenFunction::emitCompoundAssignmentLValue(const CompoundAssignOperator *e) {
14061414
}
14071415

14081416
/// Emit the computation of the specified expression of scalar type.
1409-
mlir::Value CIRGenFunction::emitScalarExpr(const Expr *e) {
1417+
mlir::Value CIRGenFunction::emitScalarExpr(const Expr *e,
1418+
bool ignoreResultAssign) {
14101419
assert(e && hasScalarEvaluationKind(e->getType()) &&
14111420
"Invalid scalar expression to emit");
14121421

1413-
return ScalarExprEmitter(*this, builder).Visit(const_cast<Expr *>(e));
1422+
return ScalarExprEmitter(*this, builder, ignoreResultAssign)
1423+
.Visit(const_cast<Expr *>(e));
14141424
}
14151425

14161426
mlir::Value CIRGenFunction::emitPromotedScalarExpr(const Expr *e,
@@ -2054,6 +2064,11 @@ mlir::Value ScalarExprEmitter::VisitMemberExpr(MemberExpr *e) {
20542064
mlir::Value ScalarExprEmitter::VisitInitListExpr(InitListExpr *e) {
20552065
const unsigned numInitElements = e->getNumInits();
20562066

2067+
[[maybe_unused]] const bool ignore = std::exchange(ignoreResultAssign, false);
2068+
assert((ignore == false ||
2069+
(numInitElements == 0 && e->getType()->isVoidType())) &&
2070+
"init list ignored");
2071+
20572072
if (e->hadArrayRangeDesignator()) {
20582073
cgf.cgm.errorNYI(e->getSourceRange(), "ArrayRangeDesignator");
20592074
return {};

clang/lib/CIR/CodeGen/CIRGenFunction.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1501,7 +1501,8 @@ class CIRGenFunction : public CIRGenTypeCache {
15011501
llvm::ArrayRef<mlir::Value> args = {});
15021502

15031503
/// Emit the computation of the specified expression of scalar type.
1504-
mlir::Value emitScalarExpr(const clang::Expr *e);
1504+
mlir::Value emitScalarExpr(const clang::Expr *e,
1505+
bool ignoreResultAssign = false);
15051506

15061507
mlir::Value emitScalarPrePostIncDec(const UnaryOperator *e, LValue lv,
15071508
cir::UnaryOpKind kind, bool isPre);

clang/test/CIR/CodeGen/binassign.c

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,107 @@ void binary_assign_struct() {
100100
// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[LS_PTR]], ptr align 4 @gs, i64 8, i1 false)
101101
// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[LSV_PTR]], ptr align 4 @gsv, i64 8, i1 true)
102102
// OGCG: ret void
103+
104+
int ignore_result_assign() {
105+
int arr[10];
106+
int i, j;
107+
j = i = 123, 0;
108+
j = arr[i = 5];
109+
int *p, *q = 0;
110+
if(p = q)
111+
return 1;
112+
return 0;
113+
}
114+
115+
// CIR-LABEL: cir.func{{.*}} @ignore_result_assign() -> !s32i
116+
// CIR: %[[RETVAL:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
117+
// CIR: %[[ARR:.*]] = cir.alloca !cir.array<!s32i x 10>, !cir.ptr<!cir.array<!s32i x 10>>, ["arr"]
118+
// CIR: %[[I:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["i"]
119+
// CIR: %[[J:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["j"]
120+
// CIR: %[[P:.*]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["p"]
121+
// CIR: %[[Q:.*]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["q", init]
122+
// CIR: %[[VAL_123:.*]] = cir.const #cir.int<123> : !s32i
123+
// CIR: cir.store{{.*}} %[[VAL_123]], %[[I]] : !s32i, !cir.ptr<!s32i>
124+
// CIR: cir.store{{.*}} %[[VAL_123]], %[[J]] : !s32i, !cir.ptr<!s32i>
125+
// CIR: %[[VAL_0:.*]] = cir.const #cir.int<0> : !s32i
126+
// CIR: %[[VAL_5:.*]] = cir.const #cir.int<5> : !s32i
127+
// CIR: cir.store{{.*}} %[[VAL_5]], %[[I]] : !s32i, !cir.ptr<!s32i>
128+
// CIR: %[[ARR_DECAY:.*]] = cir.cast array_to_ptrdecay %[[ARR]] : !cir.ptr<!cir.array<!s32i x 10>> -> !cir.ptr<!s32i>
129+
// CIR: %[[ARR_ELEM:.*]] = cir.ptr_stride %[[ARR_DECAY]], %[[VAL_5]] : (!cir.ptr<!s32i>, !s32i) -> !cir.ptr<!s32i>
130+
// CIR: %[[ARR_LOAD:.*]] = cir.load{{.*}} %[[ARR_ELEM]] : !cir.ptr<!s32i>, !s32i
131+
// CIR: cir.store{{.*}} %[[ARR_LOAD]], %[[J]] : !s32i, !cir.ptr<!s32i>
132+
// CIR: %[[NULL:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!s32i>
133+
// CIR: cir.store{{.*}} %[[NULL]], %[[Q]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
134+
// CIR: cir.scope {
135+
// CIR: %[[Q_VAL:.*]] = cir.load{{.*}} %[[Q]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
136+
// CIR: cir.store{{.*}} %[[Q_VAL]], %[[P]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
137+
// CIR: %[[COND:.*]] = cir.cast ptr_to_bool %[[Q_VAL]] : !cir.ptr<!s32i> -> !cir.bool
138+
// CIR: cir.if %[[COND]] {
139+
// CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i
140+
// CIR: cir.store %[[ONE]], %[[RETVAL]] : !s32i, !cir.ptr<!s32i>
141+
// CIR: %{{.*}} = cir.load %[[RETVAL]] : !cir.ptr<!s32i>, !s32i
142+
// CIR: cir.return
143+
// CIR: }
144+
// CIR: }
145+
// CIR: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i
146+
// CIR: cir.store %[[ZERO]], %[[RETVAL]] : !s32i, !cir.ptr<!s32i>
147+
// CIR: %{{.*}} = cir.load %[[RETVAL]] : !cir.ptr<!s32i>, !s32i
148+
// CIR: cir.return
149+
150+
// LLVM-LABEL: define {{.*}}i32 @ignore_result_assign()
151+
// LLVM: %[[RETVAL_PTR:.*]] = alloca i32
152+
// LLVM: %[[ARR_PTR:.*]] = alloca [10 x i32]
153+
// LLVM: %[[I_PTR:.*]] = alloca i32
154+
// LLVM: %[[J_PTR:.*]] = alloca i32
155+
// LLVM: %[[P_PTR:.*]] = alloca ptr
156+
// LLVM: %[[Q_PTR:.*]] = alloca ptr
157+
// LLVM: store i32 123, ptr %[[I_PTR]]
158+
// LLVM: store i32 123, ptr %[[J_PTR]]
159+
// LLVM: store i32 5, ptr %[[I_PTR]]
160+
// LLVM: %[[GEP1:.*]] = getelementptr i32, ptr %[[ARR_PTR]], i32 0
161+
// LLVM: %[[GEP2:.*]] = getelementptr i32, ptr %[[GEP1]], i64 5
162+
// LLVM: %[[ARR_VAL:.*]] = load i32, ptr %[[GEP2]]
163+
// LLVM: store i32 %[[ARR_VAL]], ptr %[[J_PTR]]
164+
// LLVM: store ptr null, ptr %[[Q_PTR]]
165+
// LLVM: br label
166+
// LLVM: %[[Q_VAL:.*]] = load ptr, ptr %[[Q_PTR]]
167+
// LLVM: store ptr %[[Q_VAL]], ptr %[[P_PTR]]
168+
// LLVM: %[[CMP:.*]] = icmp ne ptr %[[Q_VAL]], null
169+
// LLVM: br i1 %[[CMP]], label %[[THEN:.*]], label %[[ELSE:.*]]
170+
// LLVM: [[THEN]]:
171+
// LLVM: store i32 1, ptr %[[RETVAL_PTR]]
172+
// LLVM: %{{.*}} = load i32, ptr %[[RETVAL_PTR]]
173+
// LLVM: ret i32
174+
// LLVM: [[ELSE]]:
175+
// LLVM: br label
176+
// LLVM: store i32 0, ptr %[[RETVAL_PTR]]
177+
// LLVM: %{{.*}} = load i32, ptr %[[RETVAL_PTR]]
178+
// LLVM: ret i32
179+
180+
// OGCG-LABEL: define {{.*}}i32 @ignore_result_assign()
181+
// OGCG: %[[RETVAL:.*]] = alloca i32
182+
// OGCG: %[[ARR:.*]] = alloca [10 x i32]
183+
// OGCG: %[[I:.*]] = alloca i32
184+
// OGCG: %[[J:.*]] = alloca i32
185+
// OGCG: %[[P:.*]] = alloca ptr
186+
// OGCG: %[[Q:.*]] = alloca ptr
187+
// OGCG: store i32 123, ptr %[[I]]
188+
// OGCG: store i32 123, ptr %[[J]]
189+
// OGCG: store i32 5, ptr %[[I]]
190+
// OGCG: %[[ARRAYIDX:.*]] = getelementptr inbounds [10 x i32], ptr %[[ARR]], i64 0, i64 5
191+
// OGCG: %[[ARR_VAL:.*]] = load i32, ptr %[[ARRAYIDX]]
192+
// OGCG: store i32 %[[ARR_VAL]], ptr %[[J]]
193+
// OGCG: store ptr null, ptr %[[Q]]
194+
// OGCG: %[[Q_VAL:.*]] = load ptr, ptr %[[Q]]
195+
// OGCG: store ptr %[[Q_VAL]], ptr %[[P]]
196+
// OGCG: %[[TOBOOL:.*]] = icmp ne ptr %[[Q_VAL]], null
197+
// OGCG: br i1 %[[TOBOOL]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
198+
// OGCG: [[IF_THEN]]:
199+
// OGCG: store i32 1, ptr %[[RETVAL]]
200+
// OGCG: br label %[[RETURN:.*]]
201+
// OGCG: [[IF_END]]:
202+
// OGCG: store i32 0, ptr %[[RETVAL]]
203+
// OGCG: br label %[[RETURN]]
204+
// OGCG: [[RETURN]]:
205+
// OGCG: %{{.*}} = load i32, ptr %[[RETVAL]]
206+
// OGCG: ret i32

0 commit comments

Comments
 (0)