[LLVMdev] alignment issue, getting corrupt double values

edA-qa mort-ora-y eda-qa at disemia.com
Sun Dec 30 08:42:13 PST 2012


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>


More information about the llvm-dev mailing list