[clang] fdbd9c1 - [CIR] Add support for unary operations on bitfield members (#148083)

via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 14 10:57:41 PDT 2025


Author: Andres-Salamanca
Date: 2025-07-14T12:57:38-05:00
New Revision: fdbd9c19c9baf9c6007161a4ac6d961e1e0474f2

URL: https://github.com/llvm/llvm-project/commit/fdbd9c19c9baf9c6007161a4ac6d961e1e0474f2
DIFF: https://github.com/llvm/llvm-project/commit/fdbd9c19c9baf9c6007161a4ac6d961e1e0474f2.diff

LOG: [CIR] Add support for unary operations on bitfield members (#148083)

This PR introduces support for unary operations on bitfield members.
Support for binary operations is planned for a future PR.

Added: 
    

Modified: 
    clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
    clang/test/CIR/CodeGen/bitfields.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 10c485c85e22a..9e13b4c83e3a8 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -520,12 +520,10 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
         cgf, cgf.getLoc(e->getSourceRange())};
 
     // Store the updated result through the lvalue
-    if (lv.isBitField()) {
-      cgf.cgm.errorNYI(e->getSourceRange(), "Unary inc/dec bitfield");
-      return {};
-    } else {
+    if (lv.isBitField())
+      return cgf.emitStoreThroughBitfieldLValue(RValue::get(value), lv);
+    else
       cgf.emitStoreThroughLValue(RValue::get(value), lv);
-    }
 
     // If this is a postinc, return the value read from memory, otherwise use
     // the updated value.

diff  --git a/clang/test/CIR/CodeGen/bitfields.c b/clang/test/CIR/CodeGen/bitfields.c
index fc688fb4cdcaa..896acbfc854a4 100644
--- a/clang/test/CIR/CodeGen/bitfields.c
+++ b/clang/test/CIR/CodeGen/bitfields.c
@@ -267,3 +267,51 @@ void set_volatile(V* v) {
 // OGCG:   [[TMP3:%.*]] = and i64 [[TMP2]], -1095216660481
 // OGCG:   [[TMP4:%.*]] = or i64 [[TMP3]], 12884901888
 // OGCG:   store volatile i64 [[TMP4]], ptr [[TMP1]], align 4
+
+void unOp(S* s) {
+  s->d++;
+}
+
+// CIR: cir.func {{.*@unOp}}
+// CIR:   [[TMP0:%.*]] = cir.alloca !cir.ptr<!rec_S>, !cir.ptr<!cir.ptr<!rec_S>>, ["s", init] {alignment = 8 : i64}
+// CIR:   [[TMP1:%.*]] = cir.load align(8) [[TMP0]] : !cir.ptr<!cir.ptr<!rec_S>>, !cir.ptr<!rec_S>
+// CIR:   [[TMP2:%.*]] = cir.get_member [[TMP1]][0] {name = "d"} : !cir.ptr<!rec_S> -> !cir.ptr<!u64i>
+// CIR:   [[TMP3:%.*]] = cir.get_bitfield(#bfi_d, [[TMP2]] : !cir.ptr<!u64i>) -> !s32i
+// CIR:   [[TMP4:%.*]] = cir.unary(inc, [[TMP3]]) nsw : !s32i, !s32i
+// CIR:   cir.set_bitfield(#bfi_d, [[TMP2]] : !cir.ptr<!u64i>, [[TMP4]] : !s32i)
+
+// LLVM: define {{.*@unOp}}
+// LLVM:   [[TMP0:%.*]] = getelementptr %struct.S, ptr [[LOAD0:%.*]], i32 0, i32 0
+// LLVM:   [[TMP1:%.*]] = load i64, ptr [[TMP0]], align 8
+// LLVM:   [[TMP2:%.*]] = shl i64 [[TMP1]], 13
+// LLVM:   [[TMP3:%.*]] = ashr i64 [[TMP2]], 62
+// LLVM:   [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32
+// LLVM:   [[TMP5:%.*]] = add nsw i32 [[TMP4]], 1
+// LLVM:   [[TMP6:%.*]] = zext i32 [[TMP5]] to i64
+// LLVM:   [[TMP7:%.*]] = load i64, ptr [[TMP0]], align 8
+// LLVM:   [[TMP8:%.*]] = and i64 [[TMP6]], 3
+// LLVM:   [[TMP9:%.*]] = shl i64 [[TMP8]], 49
+// LLVM:   [[TMP10:%.*]] = and i64 [[TMP7]], -1688849860263937
+// LLVM:   [[TMP11:%.*]] = or i64 [[TMP10]], [[TMP9]]
+// LLVM:   store i64 [[TMP11]], ptr [[TMP0]], align 8
+// LLVM:   [[TMP12:%.*]] = shl i64 [[TMP8]], 62
+// LLVM:   [[TMP13:%.*]] = ashr i64 [[TMP12]], 62
+// LLVM:   [[TMP14:%.*]] = trunc i64 [[TMP13]] to i32
+
+// OGCG: define {{.*@unOp}}
+// OGCG:   [[TMP0:%.*]] = load ptr, ptr %s.addr, align 8
+// OGCG:   [[TMP1:%.*]] = load i64, ptr [[TMP0]], align 4
+// OGCG:   [[TMP2:%.*]] = shl i64 [[TMP1]], 13
+// OGCG:   [[TMP3:%.*]] = ashr i64 [[TMP2]], 62
+// OGCG:   [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32
+// OGCG:   [[TMP5:%.*]] = add nsw i32 [[TMP4]], 1
+// OGCG:   [[TMP6:%.*]] = zext i32 [[TMP5]] to i64
+// OGCG:   [[TMP7:%.*]] = load i64, ptr [[TMP0]], align 4
+// OGCG:   [[TMP8:%.*]] = and i64 [[TMP6]], 3
+// OGCG:   [[TMP9:%.*]] = shl i64 [[TMP8]], 49
+// OGCG:   [[TMP10:%.*]] = and i64 [[TMP7]], -1688849860263937
+// OGCG:   [[TMP11:%.*]] = or i64 [[TMP10]], [[TMP9]]
+// OGCG:   store i64 [[TMP11]], ptr [[TMP0]], align 4
+// OGCG:   [[TMP12:%.*]] = shl i64 [[TMP8]], 62
+// OGCG:   [[TMP13:%.*]] = ashr i64 [[TMP12]], 62
+// OGCG:   [[TMP14:%.*]] = trunc i64 [[TMP13]] to i32


        


More information about the cfe-commits mailing list