[clang] __builtin_bit_cast / std::bit_cast drop volatile from load
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
I'm not sure if this is intended behavior, but it is certainly unexpected.
Given a load from a volatile pointer that is then bitcasted to a different type, clang currently drops the "volatile" part of the load.
With the following code, clang does not emit a volatile load from "volatile_ptr":
```c++
#include
extern volatile float* volatile_ptr;
int main(int, char**) {
return std::bit_cast(volatile_ptr[0]); // alternatively: return __builtin_bit_cast(int, volatile_ptr[0]);
}
```
results in:
```llvm
define dso_local noundef i32 @main(i32 noundef %0, ptr noundef readnone captures(none) %1) local_unnamed_addr #0 !dbg !12 {
%3 = load ptr, ptr @volatile_ptr, align 8, !dbg !23
%4 = load i32, ptr %3, align 4, !dbg !45
ret i32 %4, !dbg !47
}
```
I would expect the bitcast code to be (more or less) semantically equivalent to this:
```c++
extern volatile float* volatile_ptr;
int main(int, char**) {
return *(volatile int*)&volatile_ptr[0];
}
```
which of course results in a volatile load:
```llvm
define dso_local noundef i32 @main(i32 noundef %0, ptr noundef readnone captures(none) %1) local_unnamed_addr #0 !dbg !14 {
%3 = load ptr, ptr @volatile_ptr, align 8, !dbg !25
%4 = load volatile i32, ptr %3, align 4, !dbg !31
ret i32 %4, !dbg !34
}
```
Looking at the code, shouldn't the emitted memcpy here not be volatile if the source address is volatile?
https://github.com/llvm/llvm-project/blob/3a1111d6681f69f502952e1bd39c79b4f3bedca8/clang/lib/CodeGen/CGExprAgg.cpp#L882
For testing: https://godbolt.org/z/zvf64761T
Contributor guide
Assessment
This issue has not been assessed yet.