edA-qa mort-ora-y
2012-Dec-30 16:42 UTC
[LLVMdev] alignment issue, getting corrupt double values
I'm having an issue where a certain set of types and insert/extractvalue
are producing the incorrect values. It appears as though extractvalue
getting my sub-structure is not getting the correct data.
I have these types:
%outer = type { i32, %inner, i1 }
%inner = type { double, i32 }
The trouble is that when I have a value of type %outer then proceed to
extract the components of the contained %inner structure I get corrupt
values. If I don't have the "i1" type in there everything works
fine,
leading me to think it is something to do with alignment. I do the
extraction with code like this:
%o = call %outer @eval_expr()
%s = extractvalue %outer %o, 1
%s1 = extractvalue %inner %s, 0
The %s1 value is not correct (not what was inserted). I think extraction
is the problem and not insertion: in another version I store the value
to a global variable and dump the bytes of the structure, which can then
be properly extracted in C++ code. The value is produced with this code
(in a separate function):
%s0 = insertvalue %inner undef, double 1.500000e+00, 0
%s1 = insertvalue %inner %s0, i32 2, 1
%s2 = insertvalue %outer undef, i32 1, 0
%s3 = insertvalue %outer %s2, %inner %s1, 1
I've attached the full sample code which shows the error and where it
happens.
--
edA-qa mort-ora-y
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Sign: Please digitally sign your emails.
Encrypt: I'm also happy to receive encrypted mail.
-------------- next part --------------
; /opt/llvm/install/bin/llc types.ll -o types.s && clang -o foo types.s
&& ./foo
%outer = type { i32, %inner, i1 } ; REMOVE the i1 and it works
%inner = type { double, i32 }
define %outer @eval_expr() {
entry:
%s0 = insertvalue %inner undef, double 1.500000e+00, 0
%s1 = insertvalue %inner %s0, i32 2, 1
%s2 = insertvalue %outer undef, i32 1, 0
%s3 = insertvalue %outer %s2, %inner %s1, 1
;%s4 = insertvalue %outer %s3, i1 false, 2
ret %outer %s3
}
define void @main() {
entry:
%o = call %outer @eval_expr()
%s = extractvalue %outer %o, 1
%s1 = extractvalue %inner %s, 0 ;ERROR: this value is 0.0, expected 1.5
call void @trace_float(double %s1)
%s2 = extractvalue %inner %s, 1 ;ERROR: this value is 1073217536, expected 2
call void @trace_integer(i32 %s2)
ret void
}
; simple tracing functions
@.int_str = private unnamed_addr constant [4 x i8] c"%d\0A\00"
define void @trace_integer( i32 %i ) {
entry:
%sp = getelementptr [4 x i8]* @.int_str, i32 0, i32 0
call i32 (i8*, ...)* @printf(i8* %sp, i32 %i)
ret void
}
@.float_str = private unnamed_addr constant [4 x i8] c"%f\0A\00"
define void @trace_float( double %i ) {
entry:
%sp = getelementptr [4 x i8]* @.float_str, i32 0, i32 0
call i32 (i8*, ...)* @printf(i8* %sp, double %i)
ret void
}
declare i32 @printf(i8*, ...)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 261 bytes
Desc: OpenPGP digital signature
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20121230/b7f2a863/attachment.sig>
I also saw this issue before. Llvm seems have trouble returning general struct values from functions. One easy workaround is to use packed struct type. Hope this helps. -Peng On Sunday, December 30, 2012, edA-qa mort-ora-y wrote:> I'm having an issue where a certain set of types and insert/extractvalue > are producing the incorrect values. It appears as though extractvalue > getting my sub-structure is not getting the correct data. > > I have these types: > > %outer = type { i32, %inner, i1 } > %inner = type { double, i32 } > > The trouble is that when I have a value of type %outer then proceed to > extract the components of the contained %inner structure I get corrupt > values. If I don't have the "i1" type in there everything works fine, > leading me to think it is something to do with alignment. I do the > extraction with code like this: > > %o = call %outer @eval_expr() > %s = extractvalue %outer %o, 1 > %s1 = extractvalue %inner %s, 0 > > The %s1 value is not correct (not what was inserted). I think extraction > is the problem and not insertion: in another version I store the value > to a global variable and dump the bytes of the structure, which can then > be properly extracted in C++ code. The value is produced with this code > (in a separate function): > > %s0 = insertvalue %inner undef, double 1.500000e+00, 0 > %s1 = insertvalue %inner %s0, i32 2, 1 > %s2 = insertvalue %outer undef, i32 1, 0 > %s3 = insertvalue %outer %s2, %inner %s1, 1 > > > I've attached the full sample code which shows the error and where it > happens. > > -- > edA-qa mort-ora-y > -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- > Sign: Please digitally sign your emails. > Encrypt: I'm also happy to receive encrypted mail. >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20121230/be3bdbef/attachment.html>
edA-qa mort-ora-y
2012-Dec-30 18:10 UTC
[LLVMdev] alignment issue, getting corrupt double values
I can confirm that if I generate the value directly (not via a return) then the expected values are extracted from the structure. So it is perhaps a return value issue. On 30/12/12 19:04, Peng Cheng wrote:> I also saw this issue before. Llvm seems have trouble returning general > struct values from functions. One easy workaround is to use packed > struct type. > > Hope this helps. > > -Peng > > On Sunday, December 30, 2012, edA-qa mort-ora-y wrote: > > I'm having an issue where a certain set of types and insert/extractvalue > are producing the incorrect values. It appears as though extractvalue > getting my sub-structure is not getting the correct data. > > I have these types: > > %outer = type { i32, %inner, i1 } > %inner = type { double, i32 } > > The trouble is that when I have a value of type %outer then proceed to > extract the components of the contained %inner structure I get corrupt > values. If I don't have the "i1" type in there everything works fine, > leading me to think it is something to do with alignment. I do the > extraction with code like this: > > %o = call %outer @eval_expr() > %s = extractvalue %outer %o, 1 > %s1 = extractvalue %inner %s, 0 > > The %s1 value is not correct (not what was inserted). I think extraction > is the problem and not insertion: in another version I store the value > to a global variable and dump the bytes of the structure, which can then > be properly extracted in C++ code. The value is produced with this code > (in a separate function): > > %s0 = insertvalue %inner undef, double 1.500000e+00, 0 > %s1 = insertvalue %inner %s0, i32 2, 1 > %s2 = insertvalue %outer undef, i32 1, 0 > %s3 = insertvalue %outer %s2, %inner %s1, 1 > > > I've attached the full sample code which shows the error and where it > happens. > > -- > edA-qa mort-ora-y > -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- > Sign: Please digitally sign your emails. > Encrypt: I'm also happy to receive encrypted mail. >-- edA-qa mort-ora-y -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Sign: Please digitally sign your emails. Encrypt: I'm also happy to receive encrypted mail. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 261 bytes Desc: OpenPGP digital signature URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20121230/0a47f8bc/attachment.sig>
Apparently Analagous Threads
- [LLVMdev] alignment issue, getting corrupt double values
- [LLVMdev] alignment issue, getting corrupt double values
- [LLVMdev] Inlined call properly optimized, but not function itself
- [LLVMdev] Missed optimisation opportunities?
- [LLVMdev] Instruction does not dominate all uses! <badref> ??