================ @@ -239,3 +239,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 ---------------- Andres-Salamanca wrote:
The reason this happens is because during lowering of `get_bitfield`, we call `load` with an alignment of zero here: https://github.com/llvm/llvm-project/blob/f168175d01247af53e3ab243486065facc18fa49/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp#L2630-L2631 When `load` is called with zero alignment, it defaults to the alignment of the type being loaded. In this example, the type is `u64`, since the member `d` is packed inside the following record: `!rec_S = !cir.record<struct "S" {!u64i, !u16i, !u32i}>` So the load uses the alignment of u64 https://github.com/llvm/llvm-project/blob/f168175d01247af53e3ab243486065facc18fa49/llvm/include/llvm/IR/IRBuilder.h#L1879-L1886 In contrast, classic CodeGen passes the alignment of the *struct*. Since the struct in this example only contains `int` members, its alignment is 4, and the load honors that. If we change the struct to include a `long`, classic CodeGen adjusts and uses an alignment of 8 accordingly as shown here: https://godbolt.org/z/3a3Yhdjzr [https://github.com/llvm/llvm-project/blob/f168175d01247af53e3ab243486065facc18fa49/clang/lib/CodeGen/CGExpr.cpp#L2341-L2343](https://github.com/llvm/llvm-project/blob/f168175d01247af53e3ab243486065facc18fa49/clang/lib/CodeGen/CGExpr.cpp#L2341-L2343) [https://github.com/llvm/llvm-project/blob/f168175d01247af53e3ab243486065facc18fa49/clang/lib/CodeGen/CGBuilder.h#L124-L129](https://github.com/llvm/llvm-project/blob/f168175d01247af53e3ab243486065facc18fa49/clang/lib/CodeGen/CGBuilder.h#L124-L129) The issue is that by the time we reach lowering, we no longer retain the original source-level struct alignment info, so the default alignment ends up coming from the storage type instead. we could extend `BitFieldInfoAttr` to store the original type of the field.? https://github.com/llvm/llvm-project/pull/148083 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits