static cast from float to int not working on ARM hardfp

Bug #1272024 reported by Nathan West
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
GNU Radio
New
Undecided
auto-nathan.west
Linaro GCC
New
Undecided
Unassigned

Bug Description

Hi, I spoke with a couple of you on IRC (as n|west) about this. There's a bug we're seeing (only on ARM hardfp; AFAIK it's only been tested on armv7 and of course various x86) in a complex file that is doing a static cast from a float received from the function call to an int. Much later the casted value is used as a tolerance in a comparison between two values in another templated function. The templated function instantiates several types of ints for comparison.

In the one case this bug affects us the value passed in as a float is 1.0. We static cast it to an int, and we know the difference between the values we are comparing is 1. The comparison 'difference > tolerance' is being made as 1 > 0 (true). If we add a print statement right after the static cast the behavior changes such that the comparison is what we expect to happen 'difference > tolerance' is 1 > 1 (false). In place of the print statement I added a function void lv_test_cast(int tolerance) that does the same kind of comparison. This function works as expected and when it is in place the comparison we care about behaves as expected.

$ /opt/oecore-x86_64/sysroots/x86_64-oesdk-linux/usr/bin/arm-oe-linux-gnueabi/arm-oe-linux-gnueabi-g++ --version
arm-oe-linux-gnueabi-g++ (GCC) 4.8.2

This particular file is compiled using
$ /opt/oecore-x86_64/sysroots/x86_64-oesdk-linux/usr/bin/arm-oe-linux-gnueabi/arm-oe-linux-gnueabi-g++ -march=armv7-a -marm -mthumb-interwork -mfloat-abi=hard -mfpu=neon --sysroot=/opt/oecore-x86_64/sysroots/armv7ahf-vfp-neon-oe-linux-gnueabi -DHAVE_DLFCN_H -DHAVE_FENV_H -O2 -pipe -g -feliminate-unused-debug-types -fpermissive -O3 -DNDEBUG -I/opt/builds/gnuradio-armv7ahf/volk/include -I/home/nathan/code/gnuradio/volk/include -I/home/nathan/code/gnuradio/volk/kernels -I/opt/builds/gnuradio-armv7ahf/volk/lib -I/home/nathan/code/gnuradio/volk/lib -I/opt/oecore-x86_64/sysroots/armv7ahf-vfp-neon-oe-linux-gnueabi/usr/include/orc-0.4 -I/opt/oecore-x86_64/sysroots/armv7ahf-vfp-neon-oe-linux-gnueabi/usr/include -fvisibility=hidden -Wsign-compare -Wall -Wno-uninitialized -fvisibility=hidden -o CMakeFiles/test_all.dir/qa_utils.cc.o -c /home/nathan/code/gnuradio/volk/lib/qa_utils.cc

The original source is part of a GNU Radio library called VOLK, and I haven't been able to show the same behavior with anything simpler than the full version. The attached tar contains the original source file, pre-processed source, and a .S that come from adding -save-temps to the above g++ command. The cast in question is static_cast<int>tol; In the original source line 297 contains the cast in question and line 260 is the comparison (in function icompare). For preprocessed source those same lines are 83058 for the cast and 83021 for the comparison.

Revision history for this message
Nathan West (nate-ewest) wrote :
Revision history for this message
Christophe Lyon (christophe-lyon) wrote :
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Bug attachments

Remote bug watches

Bug watches keep track of this bug in other bug trackers.