================
@@ -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

Reply via email to