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> ??