[LLVMdev] Casting from float to unsigned char - incorrect output?
ryan baird
ryanrbaird at gmail.com
Mon Aug 6 12:43:12 PDT 2012
I am compiling the following code for the MIPS architecture:
unsigned char trunc(float f) {
return (unsigned char) f;
}
and it produces the following assembly (directives removed for convenience:
trunc:
trunc.w.s $f0, $f12
mfc1 $2, $f0
jr $ra
nop
However, this does not seem to produce the correct output for negative
numbers. When I run the following code, I get -1 instead of 255 (which is
produced by compiling natively with gcc).
int trunc(float c);
int main() {
printf("%d\n", trunc(-1.0));
}
I am running the mips code on a PISA simulator (SimpleScalar's Simple-Sim
3.0) instead of a MIPS IV simulator, so there is a little bit of
translation occurring before I can simulate it; here is the revised code:
trunc:
cvt.w.s $f0, $f12
mfc1 $2, $f0
jr $ra
nop
the cvt.w.s function in PISA MIPS is rounding towards zero, so it should
meet the specification for trunc.w.s in MIPS IV.
Here are the commands I used to compile test.c (with the trunc function in
it):
clang -emit-llvm -mfloat-abi=hard -ccc-host-triple mipsel-unknown-linux
-ccc-clang-archs mipsel -O3 -S -o test_unopt.ll test.c
opt -std-compile-opts test_unopt.ll -o test.ll
llc -march=mipsel -mcpu=mips32 -float-abi=hard -relocation-model=static
test.ll -o test.s
Here is the llvm intermediate representation:
; ModuleID = 'test_unopt.ll'
target datalayout =
"e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"
target triple = "mipsel-unknown-linux"
define zeroext i8 @trunc(float %f) nounwind readnone {
entry:
%conv = fptoui float %f to i8
ret i8 %conv
}
This is the assembly produced by another compiler; it is more complex, but
it produces the expected output, matching with GCC: (directives removed for
convenience)
trunc:
mov.s $f4,$f12
la $2,L6
l.s $f6,($2)
c.lt.s $f12,$f6
bc1t .L3
sub.s $f0,$f12,$f6
cvt.w.s $f0,$f0
mfc1 $2,$f0
lui $3,32768
addu $3,$2,$3
j .L4
.L3:
cvt.w.s $f4,$f4
mfc1 $3,$f4
.L4:
sll $2,$3,24
srl $2,$2,24
sll $2,$2,24
srl $2,$2,24
j $31
.data
.align 4
L6:
.word 1325400064
Am I correct in my analysis that LLVM's assembly output is wrong? Is there
a way for me to get the correct output?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120806/50365ec6/attachment.html>
More information about the llvm-dev
mailing list