@@ -160,3 +160,82 @@ void store_field() {
160160// OGCG: [[TMP3:%.*]] = and i16 [[TMP2]], -32768
161161// OGCG: [[TMP4:%.*]] = or i16 [[TMP3]], 3
162162// OGCG: store i16 [[TMP4]], ptr [[TMP1]], align 4
163+
164+ void store_bitfield_to_bitfield () {
165+ S s ;
166+ s .a = s .c ;
167+ }
168+
169+ // CIR: cir.func {{.*@store_bitfield_to_bitfield}}
170+ // CIR: [[TMP0:%.*]] = cir.alloca !rec_S, !cir.ptr<!rec_S>, ["s"] {alignment = 4 : i64}
171+ // CIR: [[TMP1:%.*]] = cir.get_member [[TMP0]][0] {name = "c"} : !cir.ptr<!rec_S> -> !cir.ptr<!u64i>
172+ // CIR: [[TMP2:%.*]] = cir.get_bitfield(#bfi_c, [[TMP1]] : !cir.ptr<!u64i>) -> !s32i
173+ // CIR: [[TMP3:%.*]] = cir.get_member [[TMP0]][0] {name = "a"} : !cir.ptr<!rec_S> -> !cir.ptr<!u64i>
174+ // CIR: [[TMP4:%.*]] = cir.set_bitfield(#bfi_a, [[TMP3]] : !cir.ptr<!u64i>, [[TMP2]] : !s32i) -> !s32i
175+
176+ // LLVM: define dso_local void @store_bitfield_to_bitfield()
177+ // LLVM: [[TMP0:%.*]] = alloca %struct.S, i64 1, align 4
178+ // LLVM: [[TMP1:%.*]] = getelementptr %struct.S, ptr [[TMP0]], i32 0, i32 0
179+ // LLVM: [[TMP2:%.*]] = load i64, ptr [[TMP1]], align 8
180+ // LLVM: [[TMP3:%.*]] = shl i64 [[TMP2]], 15
181+ // LLVM: [[TMP4:%.*]] = ashr i64 [[TMP3]], 47
182+ // LLVM: [[TMP5:%.*]] = trunc i64 [[TMP4]] to i32
183+ // LLVM: [[TMP6:%.*]] = getelementptr %struct.S, ptr [[TMP0]], i32 0, i32 0
184+ // LLVM: [[TMP7:%.*]] = zext i32 [[TMP5]] to i64
185+ // LLVM: [[TMP8:%.*]] = load i64, ptr [[TMP6]], align 8
186+ // LLVM: [[TMP9:%.*]] = and i64 [[TMP7]], 15
187+ // LLVM: [[TMP10:%.*]] = and i64 [[TMP8]], -16
188+ // LLVM: [[TMP11:%.*]] = or i64 [[TMP10]], [[TMP9]]
189+ // LLVM: store i64 [[TMP11]], ptr [[TMP6]], align 8
190+ // LLVM: [[TMP12:%.*]] = shl i64 [[TMP9]], 60
191+ // LLVM: [[TMP13:%.*]] = ashr i64 [[TMP12]], 60
192+ // LLVM: [[TMP15:%.*]] = trunc i64 [[TMP13]] to i32
193+
194+ // OGCG: define dso_local void @store_bitfield_to_bitfield()
195+ // OGCG: [[TMP0:%.*]] = alloca %struct.S, align 4
196+ // OGCG: [[TMP1:%.*]] = load i64, ptr [[TMP0]], align 4
197+ // OGCG: [[TMP2:%.*]] = shl i64 [[TMP1]], 15
198+ // OGCG: [[TMP3:%.*]] = ashr i64 [[TMP2]], 47
199+ // OGCG: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32
200+ // OGCG: [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
201+ // OGCG: [[TMP6:%.*]] = load i64, ptr [[TMP0]], align 4
202+ // OGCG: [[TMP7:%.*]] = and i64 [[TMP5]], 15
203+ // OGCG: [[TMP8:%.*]] = and i64 [[TMP6]], -16
204+ // OGCG: [[TMP9:%.*]] = or i64 [[TMP8]], [[TMP7]]
205+ // OGCG: store i64 [[TMP9]], ptr [[TMP0]], align 4
206+ // OGCG: [[TMP10:%.*]] = shl i64 %bf.value, 60
207+ // OGCG: [[TMP11:%.*]] = ashr i64 [[TMP10]], 60
208+ // OGCG: [[TMP12:%.*]] = trunc i64 [[TMP11]] to i32
209+
210+ typedef struct {
211+ int a : 30 ;
212+ int volatile b : 8 ;
213+ int c ;
214+ } V ;
215+
216+ void set_volatile (V * v ) {
217+ v -> b = 3 ;
218+ }
219+ //CIR: cir.func dso_local @set_volatile
220+ //CIR: [[TMP0:%.*]] = cir.alloca !cir.ptr<!rec_V>, !cir.ptr<!cir.ptr<!rec_V>>, ["v", init] {alignment = 8 : i64}
221+ //CIR: [[TMP1:%.*]] = cir.const #cir.int<3> : !s32i
222+ //CIR: [[TMP2:%.*]] = cir.load align(8) [[TMP0]] : !cir.ptr<!cir.ptr<!rec_V>>, !cir.ptr<!rec_V>
223+ //CIR: [[TMP3:%.*]] = cir.get_member [[TMP2]][0] {name = "b"} : !cir.ptr<!rec_V> -> !cir.ptr<!u64i>
224+ //CIR: [[TMP4:%.*]] = cir.set_bitfield(#bfi_b, [[TMP3]] : !cir.ptr<!u64i>, [[TMP1]] : !s32i) {is_volatile} -> !s32i
225+
226+ // LLVM: define dso_local void @set_volatile
227+ // LLVM: [[TMP0:%.*]] = alloca ptr, i64 1, align 8
228+ // LLVM: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8
229+ // LLVM: [[TMP2:%.*]] = getelementptr %struct.V, ptr [[TMP1]], i32 0, i32 0
230+ // LLVM: [[TMP3:%.*]] = load volatile i64, ptr [[TMP2]], align 8
231+ // LLVM: [[TMP4:%.*]] = and i64 [[TMP3]], -1095216660481
232+ // LLVM: [[TMP5:%.*]] = or i64 [[TMP4]], 12884901888
233+ // LLVM: store volatile i64 [[TMP5]], ptr [[TMP2]], align 8
234+
235+ // OGCG: define dso_local void @set_volatile
236+ // OGCG: [[TMP0:%.*]] = alloca ptr, align 8
237+ // OGCG: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8
238+ // OGCG: [[TMP2:%.*]] = load volatile i64, ptr [[TMP1]], align 4
239+ // OGCG: [[TMP3:%.*]] = and i64 [[TMP2]], -1095216660481
240+ // OGCG: [[TMP4:%.*]] = or i64 [[TMP3]], 12884901888
241+ // OGCG: store volatile i64 [[TMP4]], ptr [[TMP1]], align 4
0 commit comments