Skip to content

Commit fdbd9c1

Browse files
[CIR] Add support for unary operations on bitfield members (llvm#148083)
This PR introduces support for unary operations on bitfield members. Support for binary operations is planned for a future PR.
1 parent b54cfa4 commit fdbd9c1

File tree

2 files changed

+51
-5
lines changed

2 files changed

+51
-5
lines changed

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -520,12 +520,10 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
520520
cgf, cgf.getLoc(e->getSourceRange())};
521521

522522
// Store the updated result through the lvalue
523-
if (lv.isBitField()) {
524-
cgf.cgm.errorNYI(e->getSourceRange(), "Unary inc/dec bitfield");
525-
return {};
526-
} else {
523+
if (lv.isBitField())
524+
return cgf.emitStoreThroughBitfieldLValue(RValue::get(value), lv);
525+
else
527526
cgf.emitStoreThroughLValue(RValue::get(value), lv);
528-
}
529527

530528
// If this is a postinc, return the value read from memory, otherwise use
531529
// the updated value.

clang/test/CIR/CodeGen/bitfields.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,3 +267,51 @@ void set_volatile(V* v) {
267267
// OGCG: [[TMP3:%.*]] = and i64 [[TMP2]], -1095216660481
268268
// OGCG: [[TMP4:%.*]] = or i64 [[TMP3]], 12884901888
269269
// OGCG: store volatile i64 [[TMP4]], ptr [[TMP1]], align 4
270+
271+
void unOp(S* s) {
272+
s->d++;
273+
}
274+
275+
// CIR: cir.func {{.*@unOp}}
276+
// CIR: [[TMP0:%.*]] = cir.alloca !cir.ptr<!rec_S>, !cir.ptr<!cir.ptr<!rec_S>>, ["s", init] {alignment = 8 : i64}
277+
// CIR: [[TMP1:%.*]] = cir.load align(8) [[TMP0]] : !cir.ptr<!cir.ptr<!rec_S>>, !cir.ptr<!rec_S>
278+
// CIR: [[TMP2:%.*]] = cir.get_member [[TMP1]][0] {name = "d"} : !cir.ptr<!rec_S> -> !cir.ptr<!u64i>
279+
// CIR: [[TMP3:%.*]] = cir.get_bitfield(#bfi_d, [[TMP2]] : !cir.ptr<!u64i>) -> !s32i
280+
// CIR: [[TMP4:%.*]] = cir.unary(inc, [[TMP3]]) nsw : !s32i, !s32i
281+
// CIR: cir.set_bitfield(#bfi_d, [[TMP2]] : !cir.ptr<!u64i>, [[TMP4]] : !s32i)
282+
283+
// LLVM: define {{.*@unOp}}
284+
// LLVM: [[TMP0:%.*]] = getelementptr %struct.S, ptr [[LOAD0:%.*]], i32 0, i32 0
285+
// LLVM: [[TMP1:%.*]] = load i64, ptr [[TMP0]], align 8
286+
// LLVM: [[TMP2:%.*]] = shl i64 [[TMP1]], 13
287+
// LLVM: [[TMP3:%.*]] = ashr i64 [[TMP2]], 62
288+
// LLVM: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32
289+
// LLVM: [[TMP5:%.*]] = add nsw i32 [[TMP4]], 1
290+
// LLVM: [[TMP6:%.*]] = zext i32 [[TMP5]] to i64
291+
// LLVM: [[TMP7:%.*]] = load i64, ptr [[TMP0]], align 8
292+
// LLVM: [[TMP8:%.*]] = and i64 [[TMP6]], 3
293+
// LLVM: [[TMP9:%.*]] = shl i64 [[TMP8]], 49
294+
// LLVM: [[TMP10:%.*]] = and i64 [[TMP7]], -1688849860263937
295+
// LLVM: [[TMP11:%.*]] = or i64 [[TMP10]], [[TMP9]]
296+
// LLVM: store i64 [[TMP11]], ptr [[TMP0]], align 8
297+
// LLVM: [[TMP12:%.*]] = shl i64 [[TMP8]], 62
298+
// LLVM: [[TMP13:%.*]] = ashr i64 [[TMP12]], 62
299+
// LLVM: [[TMP14:%.*]] = trunc i64 [[TMP13]] to i32
300+
301+
// OGCG: define {{.*@unOp}}
302+
// OGCG: [[TMP0:%.*]] = load ptr, ptr %s.addr, align 8
303+
// OGCG: [[TMP1:%.*]] = load i64, ptr [[TMP0]], align 4
304+
// OGCG: [[TMP2:%.*]] = shl i64 [[TMP1]], 13
305+
// OGCG: [[TMP3:%.*]] = ashr i64 [[TMP2]], 62
306+
// OGCG: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32
307+
// OGCG: [[TMP5:%.*]] = add nsw i32 [[TMP4]], 1
308+
// OGCG: [[TMP6:%.*]] = zext i32 [[TMP5]] to i64
309+
// OGCG: [[TMP7:%.*]] = load i64, ptr [[TMP0]], align 4
310+
// OGCG: [[TMP8:%.*]] = and i64 [[TMP6]], 3
311+
// OGCG: [[TMP9:%.*]] = shl i64 [[TMP8]], 49
312+
// OGCG: [[TMP10:%.*]] = and i64 [[TMP7]], -1688849860263937
313+
// OGCG: [[TMP11:%.*]] = or i64 [[TMP10]], [[TMP9]]
314+
// OGCG: store i64 [[TMP11]], ptr [[TMP0]], align 4
315+
// OGCG: [[TMP12:%.*]] = shl i64 [[TMP8]], 62
316+
// OGCG: [[TMP13:%.*]] = ashr i64 [[TMP12]], 62
317+
// OGCG: [[TMP14:%.*]] = trunc i64 [[TMP13]] to i32

0 commit comments

Comments
 (0)