Skip to content

Commit b02787d

Browse files
[CIR] Fix alignment when lowering set/get bitfield operations (#148999)
This PR fixes incorrect alignment when lowering `set` and `getBitField` operations to LLVM IR. The issue occurred because during lowering, the function was being called with an alignment of 0, which caused it to default to the alignment of the packed member. For example, if the bitfield was packed inside a `u64i`, it would use an alignment of 8. With this change, the generated code now matches what the classic codegen produces. In the assembly format, I changed to be similar to how it's done in loadOp. If there's a better approach, please feel free to point it out.
1 parent d63ab54 commit b02787d

File tree

7 files changed

+88
-75
lines changed

7 files changed

+88
-75
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1739,20 +1739,24 @@ def CIR_SetBitfieldOp : CIR_Op<"set_bitfield"> {
17391739
%2 = cir.load %0 : !cir.ptr<!cir.ptr<!record_type>>, !cir.ptr<!record_type>
17401740
%3 = cir.get_member %2[1] {name = "e"} : !cir.ptr<!record_type>
17411741
-> !cir.ptr<!u16i>
1742-
%4 = cir.set_bitfield(#bfi_e, %3 : !cir.ptr<!u16i>, %1 : !s32i) -> !s32i
1742+
%4 = cir.set_bitfield align(4) (#bfi_e, %3 : !cir.ptr<!u16i>, %1 : !s32i)
1743+
-> !s32i
17431744
```
17441745
}];
17451746

17461747
let arguments = (ins
17471748
Arg<CIR_PointerType, "the address to store the value", [MemWrite]>:$addr,
17481749
CIR_AnyType:$src,
17491750
BitfieldInfoAttr:$bitfield_info,
1751+
DefaultValuedOptionalAttr<I64Attr, "0">:$alignment,
17501752
UnitAttr:$is_volatile
17511753
);
17521754

17531755
let results = (outs CIR_IntType:$result);
17541756

1755-
let assemblyFormat = [{ `(`$bitfield_info`,` $addr`:`qualified(type($addr))`,`
1757+
let assemblyFormat = [{
1758+
(`align` `(` $alignment^ `)`)?
1759+
`(`$bitfield_info`,` $addr`:`qualified(type($addr))`,`
17561760
$src`:`type($src) `)` attr-dict `->` type($result) }];
17571761

17581762
let builders = [
@@ -1764,14 +1768,15 @@ def CIR_SetBitfieldOp : CIR_Op<"set_bitfield"> {
17641768
"unsigned":$size,
17651769
"unsigned":$offset,
17661770
"bool":$is_signed,
1767-
"bool":$is_volatile
1771+
"bool":$is_volatile,
1772+
CArg<"unsigned", "0">:$alignment
17681773
),
17691774
[{
17701775
BitfieldInfoAttr info =
17711776
BitfieldInfoAttr::get($_builder.getContext(),
17721777
name, storage_type,
17731778
size, offset, is_signed);
1774-
build($_builder, $_state, type, addr, src, info, is_volatile);
1779+
build($_builder, $_state, type, addr, src, info, alignment, is_volatile);
17751780
}]>
17761781
];
17771782
}
@@ -1823,20 +1828,23 @@ def CIR_GetBitfieldOp : CIR_Op<"get_bitfield"> {
18231828
%2 = cir.load %0 : !cir.ptr<!cir.ptr<!record_type>>, !cir.ptr<!record_type>
18241829
%3 = cir.get_member %2[1] {name = "e"} : !cir.ptr<!record_type>
18251830
-> !cir.ptr<!u16i>
1826-
%4 = cir.get_bitfield(#bfi_e, %3 : !cir.ptr<!u16i>) -> !s32i
1831+
%4 = cir.get_bitfield align(4) (#bfi_e, %3 : !cir.ptr<!u16i>) -> !s32i
18271832
```
18281833
}];
18291834

18301835
let arguments = (ins
18311836
Arg<CIR_PointerType, "the address to load from", [MemRead]>:$addr,
18321837
BitfieldInfoAttr:$bitfield_info,
1838+
DefaultValuedOptionalAttr<I64Attr, "0">:$alignment,
18331839
UnitAttr:$is_volatile
18341840
);
18351841

18361842
let results = (outs CIR_IntType:$result);
18371843

1838-
let assemblyFormat = [{ `(`$bitfield_info `,` $addr attr-dict `:`
1839-
qualified(type($addr)) `)` `->` type($result) }];
1844+
let assemblyFormat = [{
1845+
(`align` `(` $alignment^ `)`)?
1846+
`(`$bitfield_info `,` $addr attr-dict `:`
1847+
qualified(type($addr)) `)` `->` type($result) }];
18401848

18411849
let builders = [
18421850
OpBuilder<(ins "mlir::Type":$type,
@@ -1846,14 +1854,15 @@ def CIR_GetBitfieldOp : CIR_Op<"get_bitfield"> {
18461854
"unsigned":$size,
18471855
"unsigned":$offset,
18481856
"bool":$is_signed,
1849-
"bool":$is_volatile
1857+
"bool":$is_volatile,
1858+
CArg<"unsigned", "0">:$alignment
18501859
),
18511860
[{
18521861
BitfieldInfoAttr info =
18531862
BitfieldInfoAttr::get($_builder.getContext(),
18541863
name, storage_type,
18551864
size, offset, is_signed);
1856-
build($_builder, $_state, type, addr, info, is_volatile);
1865+
build($_builder, $_state, type, addr, info, alignment, is_volatile);
18571866
}]>
18581867
];
18591868
}

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -408,21 +408,23 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
408408
}
409409

410410
mlir::Value createSetBitfield(mlir::Location loc, mlir::Type resultType,
411-
mlir::Value dstAddr, mlir::Type storageType,
411+
Address dstAddr, mlir::Type storageType,
412412
mlir::Value src, const CIRGenBitFieldInfo &info,
413-
bool isLvalueVolatile, bool useVolatile) {
414-
return create<cir::SetBitfieldOp>(loc, resultType, dstAddr, storageType,
415-
src, info.name, info.size, info.offset,
416-
info.isSigned, isLvalueVolatile);
413+
bool isLvalueVolatile) {
414+
return create<cir::SetBitfieldOp>(
415+
loc, resultType, dstAddr.getPointer(), storageType, src, info.name,
416+
info.size, info.offset, info.isSigned, isLvalueVolatile,
417+
dstAddr.getAlignment().getAsAlign().value());
417418
}
418419

419420
mlir::Value createGetBitfield(mlir::Location loc, mlir::Type resultType,
420-
mlir::Value addr, mlir::Type storageType,
421+
Address addr, mlir::Type storageType,
421422
const CIRGenBitFieldInfo &info,
422-
bool isLvalueVolatile, bool useVolatile) {
423-
return create<cir::GetBitfieldOp>(loc, resultType, addr, storageType,
424-
info.name, info.size, info.offset,
425-
info.isSigned, isLvalueVolatile);
423+
bool isLvalueVolatile) {
424+
return create<cir::GetBitfieldOp>(
425+
loc, resultType, addr.getPointer(), storageType, info.name, info.size,
426+
info.offset, info.isSigned, isLvalueVolatile,
427+
addr.getAlignment().getAsAlign().value());
426428
}
427429
};
428430

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -333,13 +333,12 @@ mlir::Value CIRGenFunction::emitStoreThroughBitfieldLValue(RValue src,
333333
Address ptr = dst.getBitFieldAddress();
334334

335335
assert(!cir::MissingFeatures::armComputeVolatileBitfields());
336-
const bool useVolatile = false;
337336

338337
mlir::Value dstAddr = dst.getAddress().getPointer();
339338

340-
return builder.createSetBitfield(dstAddr.getLoc(), resLTy, dstAddr,
339+
return builder.createSetBitfield(dstAddr.getLoc(), resLTy, ptr,
341340
ptr.getElementType(), src.getValue(), info,
342-
dst.isVolatileQualified(), useVolatile);
341+
dst.isVolatileQualified());
343342
}
344343

345344
RValue CIRGenFunction::emitLoadOfBitfieldLValue(LValue lv, SourceLocation loc) {
@@ -352,8 +351,7 @@ RValue CIRGenFunction::emitLoadOfBitfieldLValue(LValue lv, SourceLocation loc) {
352351
assert(!cir::MissingFeatures::armComputeVolatileBitfields());
353352

354353
mlir::Value field = builder.createGetBitfield(
355-
getLoc(loc), resLTy, ptr.getPointer(), ptr.getElementType(), info,
356-
lv.isVolatile(), false);
354+
getLoc(loc), resLTy, ptr, ptr.getElementType(), info, lv.isVolatile());
357355
assert(!cir::MissingFeatures::opLoadEmitScalarRangeCheck() && "NYI");
358356
return RValue::get(field);
359357
}
@@ -366,7 +364,10 @@ Address CIRGenFunction::getAddrOfBitFieldStorage(LValue base,
366364
cir::PointerType fieldPtr = cir::PointerType::get(fieldType);
367365
cir::GetMemberOp sea = getBuilder().createGetMember(
368366
loc, fieldPtr, base.getPointer(), field->getName(), index);
369-
return Address(sea, CharUnits::One());
367+
auto rec = cast<cir::RecordType>(base.getAddress().getElementType());
368+
CharUnits offset = CharUnits::fromQuantity(
369+
rec.getElementOffset(cgm.getDataLayout().layout, index));
370+
return Address(sea, base.getAlignment().alignmentAtOffset(offset));
370371
}
371372

372373
LValue CIRGenFunction::emitLValueForBitField(LValue base,

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2571,7 +2571,7 @@ mlir::LogicalResult CIRToLLVMSetBitfieldOpLowering::matchAndRewrite(
25712571
assert(storageSize > size && "Invalid bitfield size.");
25722572

25732573
mlir::Value val = rewriter.create<mlir::LLVM::LoadOp>(
2574-
op.getLoc(), intType, adaptor.getAddr(), /* alignment */ 0,
2574+
op.getLoc(), intType, adaptor.getAddr(), op.getAlignment(),
25752575
op.getIsVolatile());
25762576

25772577
srcVal =
@@ -2588,7 +2588,7 @@ mlir::LogicalResult CIRToLLVMSetBitfieldOpLowering::matchAndRewrite(
25882588
}
25892589

25902590
rewriter.create<mlir::LLVM::StoreOp>(op.getLoc(), srcVal, adaptor.getAddr(),
2591-
/* alignment */ 0, op.getIsVolatile());
2591+
op.getAlignment(), op.getIsVolatile());
25922592

25932593
mlir::Type resultTy = getTypeConverter()->convertType(op.getType());
25942594

@@ -2662,7 +2662,8 @@ mlir::LogicalResult CIRToLLVMGetBitfieldOpLowering::matchAndRewrite(
26622662
computeBitfieldIntType(storageType, context, storageSize);
26632663

26642664
mlir::Value val = rewriter.create<mlir::LLVM::LoadOp>(
2665-
op.getLoc(), intType, adaptor.getAddr(), 0, op.getIsVolatile());
2665+
op.getLoc(), intType, adaptor.getAddr(), op.getAlignment(),
2666+
op.getIsVolatile());
26662667
val = rewriter.create<mlir::LLVM::BitcastOp>(op.getLoc(), intType, val);
26672668

26682669
if (info.getIsSigned()) {

clang/test/CIR/CodeGen/bitfields.c

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,14 @@ int load_field(S* s) {
8787
// CIR: [[TMP0:%.*]] = cir.alloca !cir.ptr<!rec_S>, !cir.ptr<!cir.ptr<!rec_S>>, ["s", init]
8888
// CIR: [[TMP1:%.*]] = cir.load{{.*}} [[TMP0]] : !cir.ptr<!cir.ptr<!rec_S>>, !cir.ptr<!rec_S>
8989
// CIR: [[TMP2:%.*]] = cir.get_member [[TMP1]][0] {name = "c"} : !cir.ptr<!rec_S> -> !cir.ptr<!u64i>
90-
// CIR: [[TMP3:%.*]] = cir.get_bitfield(#bfi_c, [[TMP2]] : !cir.ptr<!u64i>) -> !s32i
90+
// CIR: [[TMP3:%.*]] = cir.get_bitfield align(4) (#bfi_c, [[TMP2]] : !cir.ptr<!u64i>) -> !s32i
9191

9292
// LLVM: define dso_local i32 @load_field
9393
// LLVM: [[TMP0:%.*]] = alloca ptr, i64 1, align 8
9494
// LLVM: [[TMP1:%.*]] = alloca i32, i64 1, align 4
9595
// LLVM: [[TMP2:%.*]] = load ptr, ptr [[TMP0]], align 8
9696
// LLVM: [[TMP3:%.*]] = getelementptr %struct.S, ptr [[TMP2]], i32 0, i32 0
97-
// LLVM: [[TMP4:%.*]] = load i64, ptr [[TMP3]], align 8
97+
// LLVM: [[TMP4:%.*]] = load i64, ptr [[TMP3]], align 4
9898
// LLVM: [[TMP5:%.*]] = shl i64 [[TMP4]], 15
9999
// LLVM: [[TMP6:%.*]] = ashr i64 [[TMP5]], 47
100100
// LLVM: [[TMP7:%.*]] = trunc i64 [[TMP6]] to i32
@@ -115,13 +115,13 @@ unsigned int load_field_unsigned(A* s) {
115115
//CIR: [[TMP0:%.*]] = cir.alloca !cir.ptr<!rec_A>, !cir.ptr<!cir.ptr<!rec_A>>, ["s", init] {alignment = 8 : i64}
116116
//CIR: [[TMP1:%.*]] = cir.load align(8) [[TMP0]] : !cir.ptr<!cir.ptr<!rec_A>>, !cir.ptr<!rec_A>
117117
//CIR: [[TMP2:%.*]] = cir.get_member [[TMP1]][3] {name = "more_bits"} : !cir.ptr<!rec_A> -> !cir.ptr<!u16i>
118-
//CIR: [[TMP3:%.*]] = cir.get_bitfield(#bfi_more_bits, [[TMP2]] : !cir.ptr<!u16i>) -> !u32i
118+
//CIR: [[TMP3:%.*]] = cir.get_bitfield align(1) (#bfi_more_bits, [[TMP2]] : !cir.ptr<!u16i>) -> !u32i
119119

120120
//LLVM: define dso_local i32 @load_field_unsigned
121121
//LLVM: [[TMP0:%.*]] = alloca ptr, i64 1, align 8
122122
//LLVM: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8
123123
//LLVM: [[TMP2:%.*]] = getelementptr %struct.A, ptr [[TMP1]], i32 0, i32 3
124-
//LLVM: [[TMP3:%.*]] = load i16, ptr [[TMP2]], align 2
124+
//LLVM: [[TMP3:%.*]] = load i16, ptr [[TMP2]], align 1
125125
//LLVM: [[TMP4:%.*]] = lshr i16 [[TMP3]], 3
126126
//LLVM: [[TMP5:%.*]] = and i16 [[TMP4]], 15
127127
//LLVM: [[TMP6:%.*]] = zext i16 [[TMP5]] to i32
@@ -143,15 +143,15 @@ void store_field() {
143143
// CIR: [[TMP0:%.*]] = cir.alloca !rec_S, !cir.ptr<!rec_S>
144144
// CIR: [[TMP1:%.*]] = cir.const #cir.int<3> : !s32i
145145
// CIR: [[TMP2:%.*]] = cir.get_member [[TMP0]][1] {name = "e"} : !cir.ptr<!rec_S> -> !cir.ptr<!u16i>
146-
// CIR: cir.set_bitfield(#bfi_e, [[TMP2]] : !cir.ptr<!u16i>, [[TMP1]] : !s32i)
146+
// CIR: cir.set_bitfield align(4) (#bfi_e, [[TMP2]] : !cir.ptr<!u16i>, [[TMP1]] : !s32i)
147147

148148
// LLVM: define dso_local void @store_field()
149149
// LLVM: [[TMP0:%.*]] = alloca %struct.S, i64 1, align 4
150150
// LLVM: [[TMP1:%.*]] = getelementptr %struct.S, ptr [[TMP0]], i32 0, i32 1
151-
// LLVM: [[TMP2:%.*]] = load i16, ptr [[TMP1]], align 2
151+
// LLVM: [[TMP2:%.*]] = load i16, ptr [[TMP1]], align 4
152152
// LLVM: [[TMP3:%.*]] = and i16 [[TMP2]], -32768
153153
// LLVM: [[TMP4:%.*]] = or i16 [[TMP3]], 3
154-
// LLVM: store i16 [[TMP4]], ptr [[TMP1]], align 2
154+
// LLVM: store i16 [[TMP4]], ptr [[TMP1]], align 4
155155

156156
// OGCG: define dso_local void @store_field()
157157
// OGCG: [[TMP0:%.*]] = alloca %struct.S, align 4
@@ -169,24 +169,24 @@ void store_bitfield_to_bitfield() {
169169
// CIR: cir.func {{.*@store_bitfield_to_bitfield}}
170170
// CIR: [[TMP0:%.*]] = cir.alloca !rec_S, !cir.ptr<!rec_S>, ["s"] {alignment = 4 : i64}
171171
// 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
172+
// CIR: [[TMP2:%.*]] = cir.get_bitfield align(4) (#bfi_c, [[TMP1]] : !cir.ptr<!u64i>) -> !s32i
173173
// 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
174+
// CIR: [[TMP4:%.*]] = cir.set_bitfield align(4) (#bfi_a, [[TMP3]] : !cir.ptr<!u64i>, [[TMP2]] : !s32i) -> !s32i
175175

176176
// LLVM: define dso_local void @store_bitfield_to_bitfield()
177177
// LLVM: [[TMP0:%.*]] = alloca %struct.S, i64 1, align 4
178178
// LLVM: [[TMP1:%.*]] = getelementptr %struct.S, ptr [[TMP0]], i32 0, i32 0
179-
// LLVM: [[TMP2:%.*]] = load i64, ptr [[TMP1]], align 8
179+
// LLVM: [[TMP2:%.*]] = load i64, ptr [[TMP1]], align 4
180180
// LLVM: [[TMP3:%.*]] = shl i64 [[TMP2]], 15
181181
// LLVM: [[TMP4:%.*]] = ashr i64 [[TMP3]], 47
182182
// LLVM: [[TMP5:%.*]] = trunc i64 [[TMP4]] to i32
183183
// LLVM: [[TMP6:%.*]] = getelementptr %struct.S, ptr [[TMP0]], i32 0, i32 0
184184
// LLVM: [[TMP7:%.*]] = zext i32 [[TMP5]] to i64
185-
// LLVM: [[TMP8:%.*]] = load i64, ptr [[TMP6]], align 8
185+
// LLVM: [[TMP8:%.*]] = load i64, ptr [[TMP6]], align 4
186186
// LLVM: [[TMP9:%.*]] = and i64 [[TMP7]], 15
187187
// LLVM: [[TMP10:%.*]] = and i64 [[TMP8]], -16
188188
// LLVM: [[TMP11:%.*]] = or i64 [[TMP10]], [[TMP9]]
189-
// LLVM: store i64 [[TMP11]], ptr [[TMP6]], align 8
189+
// LLVM: store i64 [[TMP11]], ptr [[TMP6]], align 4
190190
// LLVM: [[TMP12:%.*]] = shl i64 [[TMP9]], 60
191191
// LLVM: [[TMP13:%.*]] = ashr i64 [[TMP12]], 60
192192
// LLVM: [[TMP15:%.*]] = trunc i64 [[TMP13]] to i32
@@ -222,16 +222,16 @@ void get_volatile(V* v) {
222222
// CIR: [[TMP1:%.*]] = cir.const #cir.int<3> : !s32i
223223
// CIR: [[TMP2:%.*]] = cir.load align(8) [[TMP0]] : !cir.ptr<!cir.ptr<!rec_V>>, !cir.ptr<!rec_V>
224224
// CIR: [[TMP3:%.*]] = cir.get_member [[TMP2]][0] {name = "b"} : !cir.ptr<!rec_V> -> !cir.ptr<!u64i>
225-
// CIR: [[TMP4:%.*]] = cir.set_bitfield(#bfi_b, [[TMP3]] : !cir.ptr<!u64i>, [[TMP1]] : !s32i) {is_volatile} -> !s32i
225+
// CIR: [[TMP4:%.*]] = cir.set_bitfield align(4) (#bfi_b, [[TMP3]] : !cir.ptr<!u64i>, [[TMP1]] : !s32i) {is_volatile} -> !s32i
226226

227227
// LLVM: define dso_local void @get_volatile
228228
// LLVM: [[TMP0:%.*]] = alloca ptr, i64 1, align 8
229229
// LLVM: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8
230230
// LLVM: [[TMP2:%.*]] = getelementptr %struct.V, ptr [[TMP1]], i32 0, i32 0
231-
// LLVM: [[TMP3:%.*]] = load volatile i64, ptr [[TMP2]], align 8
231+
// LLVM: [[TMP3:%.*]] = load volatile i64, ptr [[TMP2]], align 4
232232
// LLVM: [[TMP4:%.*]] = and i64 [[TMP3]], -1095216660481
233233
// LLVM: [[TMP5:%.*]] = or i64 [[TMP4]], 12884901888
234-
// LLVM: store volatile i64 [[TMP5]], ptr [[TMP2]], align 8
234+
// LLVM: store volatile i64 [[TMP5]], ptr [[TMP2]], align 4
235235

236236
// OCGC: define dso_local void @get_volatile
237237
// OCGC: [[TMP0:%.*]] = alloca ptr, align 8
@@ -249,16 +249,16 @@ void set_volatile(V* v) {
249249
//CIR: [[TMP1:%.*]] = cir.const #cir.int<3> : !s32i
250250
//CIR: [[TMP2:%.*]] = cir.load align(8) [[TMP0]] : !cir.ptr<!cir.ptr<!rec_V>>, !cir.ptr<!rec_V>
251251
//CIR: [[TMP3:%.*]] = cir.get_member [[TMP2]][0] {name = "b"} : !cir.ptr<!rec_V> -> !cir.ptr<!u64i>
252-
//CIR: [[TMP4:%.*]] = cir.set_bitfield(#bfi_b, [[TMP3]] : !cir.ptr<!u64i>, [[TMP1]] : !s32i) {is_volatile} -> !s32i
252+
//CIR: [[TMP4:%.*]] = cir.set_bitfield align(4) (#bfi_b, [[TMP3]] : !cir.ptr<!u64i>, [[TMP1]] : !s32i) {is_volatile} -> !s32i
253253

254254
// LLVM: define dso_local void @set_volatile
255255
// LLVM: [[TMP0:%.*]] = alloca ptr, i64 1, align 8
256256
// LLVM: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8
257257
// LLVM: [[TMP2:%.*]] = getelementptr %struct.V, ptr [[TMP1]], i32 0, i32 0
258-
// LLVM: [[TMP3:%.*]] = load volatile i64, ptr [[TMP2]], align 8
258+
// LLVM: [[TMP3:%.*]] = load volatile i64, ptr [[TMP2]], align 4
259259
// LLVM: [[TMP4:%.*]] = and i64 [[TMP3]], -1095216660481
260260
// LLVM: [[TMP5:%.*]] = or i64 [[TMP4]], 12884901888
261-
// LLVM: store volatile i64 [[TMP5]], ptr [[TMP2]], align 8
261+
// LLVM: store volatile i64 [[TMP5]], ptr [[TMP2]], align 4
262262

263263
// OGCG: define dso_local void @set_volatile
264264
// OGCG: [[TMP0:%.*]] = alloca ptr, align 8
@@ -276,24 +276,24 @@ void unOp(S* s) {
276276
// CIR: [[TMP0:%.*]] = cir.alloca !cir.ptr<!rec_S>, !cir.ptr<!cir.ptr<!rec_S>>, ["s", init] {alignment = 8 : i64}
277277
// CIR: [[TMP1:%.*]] = cir.load align(8) [[TMP0]] : !cir.ptr<!cir.ptr<!rec_S>>, !cir.ptr<!rec_S>
278278
// 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
279+
// CIR: [[TMP3:%.*]] = cir.get_bitfield align(4) (#bfi_d, [[TMP2]] : !cir.ptr<!u64i>) -> !s32i
280280
// CIR: [[TMP4:%.*]] = cir.unary(inc, [[TMP3]]) nsw : !s32i, !s32i
281-
// CIR: cir.set_bitfield(#bfi_d, [[TMP2]] : !cir.ptr<!u64i>, [[TMP4]] : !s32i)
281+
// CIR: cir.set_bitfield align(4) (#bfi_d, [[TMP2]] : !cir.ptr<!u64i>, [[TMP4]] : !s32i)
282282

283283
// LLVM: define {{.*@unOp}}
284284
// LLVM: [[TMP0:%.*]] = getelementptr %struct.S, ptr [[LOAD0:%.*]], i32 0, i32 0
285-
// LLVM: [[TMP1:%.*]] = load i64, ptr [[TMP0]], align 8
285+
// LLVM: [[TMP1:%.*]] = load i64, ptr [[TMP0]], align 4
286286
// LLVM: [[TMP2:%.*]] = shl i64 [[TMP1]], 13
287287
// LLVM: [[TMP3:%.*]] = ashr i64 [[TMP2]], 62
288288
// LLVM: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32
289289
// LLVM: [[TMP5:%.*]] = add nsw i32 [[TMP4]], 1
290290
// LLVM: [[TMP6:%.*]] = zext i32 [[TMP5]] to i64
291-
// LLVM: [[TMP7:%.*]] = load i64, ptr [[TMP0]], align 8
291+
// LLVM: [[TMP7:%.*]] = load i64, ptr [[TMP0]], align 4
292292
// LLVM: [[TMP8:%.*]] = and i64 [[TMP6]], 3
293293
// LLVM: [[TMP9:%.*]] = shl i64 [[TMP8]], 49
294294
// LLVM: [[TMP10:%.*]] = and i64 [[TMP7]], -1688849860263937
295295
// LLVM: [[TMP11:%.*]] = or i64 [[TMP10]], [[TMP9]]
296-
// LLVM: store i64 [[TMP11]], ptr [[TMP0]], align 8
296+
// LLVM: store i64 [[TMP11]], ptr [[TMP0]], align 4
297297
// LLVM: [[TMP12:%.*]] = shl i64 [[TMP8]], 62
298298
// LLVM: [[TMP13:%.*]] = ashr i64 [[TMP12]], 62
299299
// LLVM: [[TMP14:%.*]] = trunc i64 [[TMP13]] to i32

0 commit comments

Comments
 (0)