On 06/06/2025 10:21 pm, Tom Lane wrote:
Konstantin Knizhnik <knizh...@garret.ru> writes:
There is really essential difference in code generated by clang 15
(working) and 16 (not working).
It's a mistake to think that this is a compiler bug.  The C standard
explicitly allows compilers to use word-wide operations to access
bit-field struct members.

Sorry, I have not said that I have found compiler bug.
The generated code (clang 16) overwrites all three bitfields but looks like is doing it in correct way (old values of state and target are preserved). My first thought was that compiler moves forward assignment of state from `pgaio_io_update_state`. But it is not true: it just reads and writes old value of `state` field.

It is also possible to expect that `pgaio_io_update_state` somehow "resurrects" old value of `op` field.
But it is also not true:


```

postgres`pgaio_io_update_state:
...

postgres[0x100699070] <+372>: dmb    ish ; memory write barrier
postgres[0x100699074] <+376>: ldur   w10, [x29, #-0xc] ; w10 = state
postgres[0x100699078] <+380>: ldur   x9, [x29, #-0x8]  ; x9 = ioh
postgres[0x10069907c] <+384>: ldrh   w8, [x9]    ; w8 = ioh->state, ioh->target
postgres[0x100699080] <+388>: ldrb   w11, [x9, #0x2] ; w11 = ioh->op
postgres[0x100699084] <+392>: orr    w8, w8, w11, lsl #16 ; w8 = ioh->state, ioh->target, ioh->op
postgres[0x100699088] <+396>: and    w10, w10, #0xff      ; w10 &= 0xff
postgres[0x10069908c] <+400>: and    w8, w8, #0xffffff00  ; w8 &= ~0xff
postgres[0x100699090] <+404>: orr    w10, w8, w10          ; w10 = state, ioh->target, ioh->op
postgres[0x100699094] <+408>: lsr    w8, w10, #16         ; w8 = ioh->op
postgres[0x100699098] <+412>: strh   w10, [x9]
postgres[0x10069909c] <+416>: strb   w8, [x9, #0x2]
postgres[0x1006990a0] <+420>: ldp    x29, x30, [sp, #0x60]
postgres[0x1006990a4] <+424>: add    sp, sp, #0x70
postgres[0x1006990a8] <+428>: ret
```




Reply via email to