Closed
Description
Reproduction
https://godbolt.org/z/PGK3PEf64
__attribute((noinline))
uint64_t LoadAsLong(uint32_t* __ptr32 foo) {
return static_cast<uint64_t>(*foo);
}
I expect that the LoadAsLong
will return 42
for the test case in the godbolt listing.
But it does not.
If do not use __ptr32
, then the LoadAsLong
returns 42
Investigation
Clang produces the following assembly for the LoadAsLong
function:
movslq %edi, %rax
movq (%rax), %rax
retq
the assembly loads 64 bit value but had to load 32 bits.
As far as I see llvm IR for the function is correct before isel:
define dso_local noundef i64 @LoadAsLong(unsigned int ptr32_sptr*)(ptr addrspace(270) nocapture noundef readonly %foo) local_unnamed_addr {
entry:
%0 = load i32, ptr addrspace(270) %foo, align 4
%conv = zext i32 %0 to i64
ret i64 %conv
}
but after isel:
# Machine code for function LoadAsLong(unsigned int ptr32_sptr*): IsSSA, TracksLiveness
Function Live Ins: $rdi in %0
bb.0.entry:
liveins: $rdi
%0:gr64 = COPY $rdi
%1:gr32 = COPY %0.sub_32bit:gr64
%2:gr64 = MOVSX64rr32 killed %1:gr32
%3:gr64 = MOV64rm killed %2:gr64, 1, $noreg, 0, $noreg :: (load (s64) from %ir.foo, align 4, addrspace 270)
$rax = COPY %3:gr64
RET 0, $rax
# End machine code for function LoadAsLong(unsigned int ptr32_sptr*).
there is load (s64) from %ir.foo, align 4, addrspace 270