[LLVMdev] Trunc Load

Johannes Birgmeier e0902998 at student.tuwien.ac.at
Thu Oct 27 08:08:18 PDT 2011


Hello!

I have the following simple IR:

==================================
@l = common global i64 0, align 8

define void @hello() nounwind {
entry:
   store i64 -4919131755279862989, i64* @l
   ret void
}

define i32 @main(i32 %argc, i8** %argv) nounwind {
entry:
   call void @hello()
   %tmp = load i64* @l
   %conv = trunc i64 %tmp to i32
   ret i32 %conv
}
==================================

Of interest are the lines
   %tmp = load i64* @l
   %conv = trunc i64 %tmp to i32

... which LLVM automatically translates to "load singleword" from 
memory, instead of "load doubleword; then truncate". However, this 
(simply load a singleword) gives an erroneous result. On my 
architecture, this results in the high bits being loaded into the return 
register, instead of the low bits, as should happen with truncate.

Details: i64 's are stored in two adjacent 32 bit registers. So the 
store happens like this:
"stddw 0xBBBBBBBB33333333, *$ptr"
and the load should happen like this:
"lddw *$ptr, A5:A4"
. It is easy to see that if
"ldw *$ptr, A4"
is printed, then the high bits will be loaded into A4. Something like 
this would be correct just like the lddw variant:
"ldw *-$ptr(4), A4"

Is there a way to change this behavior (that (trunc (load doubleword)) 
is replaced by (load word))?
Or if you think the fault lies on my side, where is the right point to 
begin debugging?

Thanks for any kind of hint!
Johannes



More information about the llvm-dev mailing list