https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89604
Bug ID: 89604
Summary: Type conversion from signed char to a wider integer
generates wrong assembly for ARM,
Product: gcc
Version: 8.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: driver
Assignee: unassigned at gcc dot gnu.org
Reporter: christalization at gmail dot com
Target Milestone: ---
Created attachment 45902
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45902&action=edit
Preprocessed file
So I've stumbled upon this bug when compiling a project on the Raspberry pi.
I created a barebone test project to verify that nothing else was causing it,
and indeed, I got the same result.
What happens is that when you're converting a signed char type to a signed
integer, the conversion fails to move the sign bit, instead it just extends the
bits like it would with an unsigned conversion.
I've verified that this does not happen on x86/64 builds so it appears to be
specific for ARM builds. Compiling exactly the same piece of code on Windows
yields the correct result:
int main()
{
char c = -40;
double s = c;
printf("%f", s);
return 0;
}
Windows: -40
Raspbian: 226
226 is what you get when interpreting the bits of the char as unsigned.
I got around the problem for now by explicitly moving the sign bit as such:
((int)c & ~0x80) | ~0x7FFFFFFF
Here is the compiler output along with the commandline arguments:
g++ -v -save-temps test.cpp -o test
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/6/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Raspbian
6.3.0-18+rpi1+deb9u1' --with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs
--enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-6 --program-prefix=arm-linux-gnueabihf- --enable-shared
--enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext
--enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/
--enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes
--with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libitm
--disable-libquadmath --enable-plugin --with-system-zlib
--disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo
--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-6-armhf/jre --enable-java-home
--with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-6-armhf
--with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-6-armhf
--with-arch-directory=arm --with-ecj-jar=/usr/share/java/eclipse-ecj.jar
--with-target-system-zlib --enable-objc-gc=auto --enable-multiarch
--disable-sjlj-exceptions --with-arch=armv6 --with-fpu=vfp --with-float=hard
--enable-checking=release --build=arm-linux-gnueabihf
--host=arm-linux-gnueabihf --target=arm-linux-gnueabihf
Thread model: posix
gcc version 6.3.0 20170516 (Raspbian 6.3.0-18+rpi1+deb9u1)
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'test' '-shared-libgcc'
'-march=armv6' '-mfloat-abi=hard' '-mfpu=vfp' '-mtls-dialect=gnu'
/usr/lib/gcc/arm-linux-gnueabihf/6/cc1plus -E -quiet -v -imultilib .
-imultiarch arm-linux-gnueabihf -D_GNU_SOURCE test.cpp -march=armv6
-mfloat-abi=hard -mfpu=vfp -mtls-dialect=gnu -fpch-preprocess -o test.ii
ignoring duplicate directory "/usr/include/arm-linux-gnueabihf/c++/6"
ignoring nonexistent directory "/usr/local/include/arm-linux-gnueabihf"
ignoring nonexistent directory
"/usr/lib/gcc/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/include/c++/6
/usr/include/arm-linux-gnueabihf/c++/6
/usr/include/c++/6/backward
/usr/lib/gcc/arm-linux-gnueabihf/6/include
/usr/local/include
/usr/lib/gcc/arm-linux-gnueabihf/6/include-fixed
/usr/include/arm-linux-gnueabihf
/usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'test' '-shared-libgcc'
'-march=armv6' '-mfloat-abi=hard' '-mfpu=vfp' '-mtls-dialect=gnu'
/usr/lib/gcc/arm-linux-gnueabihf/6/cc1plus -fpreprocessed test.ii -quiet
-dumpbase test.cpp -march=armv6 -mfloat-abi=hard -mfpu=vfp -mtls-dialect=gnu
-auxbase test -version -o test.s
GNU C++14 (Raspbian 6.3.0-18+rpi1+deb9u1) version 6.3.0 20170516
(arm-linux-gnueabihf)
compiled by GNU C version 6.3.0 20170516, GMP version 6.1.2, MPFR
version 3.1.5, MPC version 1.0.3, isl version 0.15
GGC heuristics: --param ggc-min-expand=93 --param ggc-min-heapsize=118680
GNU C++14 (Raspbian 6.3.0-18+rpi1+deb9u1) version 6.3.0 20170516
(arm-linux-gnueabihf)
compiled by GNU C version 6.3.0 20170516, GMP version 6.1.2, MPFR
version 3.1.5, MPC version 1.0.3, isl version 0.15
GGC heuristics: --param ggc-min-expand=93 --param ggc-min-heapsize=118680
Compiler executable checksum: 79dca666fccaa96025c9107a8b3f60f3
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'test' '-shared-libgcc'
'-march=armv6' '-mfloat-abi=hard' '-mfpu=vfp' '-mtls-dialect=gnu'
as -v -march=armv6 -mfloat-abi=hard -mfpu=vfp -meabi=5 -o test.o test.s
GNU assembler version 2.28 (arm-linux-gnueabihf) using BFD version (GNU
Binutils for Raspbian) 2.28
COMPILER_PATH=/usr/lib/gcc/arm-linux-gnueabihf/6/:/usr/lib/gcc/arm-linux-gnueabihf/6/:/usr/lib/gcc/arm-linux-gnueabihf/:/usr/lib/gcc/arm-linux-gnueabihf/6/:/usr/lib/gcc/arm-linux-gnueabihf/
LIBRARY_PATH=/usr/lib/gcc/arm-linux-gnueabihf/6/:/usr/lib/gcc/arm-linux-gnueabihf/6/../../../arm-linux-gnueabihf/:/usr/lib/gcc/arm-linux-gnueabihf/6/../../../:/lib/arm-linux-gnueabihf/:/lib/:/usr/lib/arm-linux-gnueabihf/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'test' '-shared-libgcc'
'-march=armv6' '-mfloat-abi=hard' '-mfpu=vfp' '-mtls-dialect=gnu'
/usr/lib/gcc/arm-linux-gnueabihf/6/collect2 -plugin
/usr/lib/gcc/arm-linux-gnueabihf/6/liblto_plugin.so
-plugin-opt=/usr/lib/gcc/arm-linux-gnueabihf/6/lto-wrapper
-plugin-opt=-fresolution=test.res -plugin-opt=-pass-through=-lgcc_s
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc
-plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --sysroot=/
--build-id --eh-frame-hdr -dynamic-linker /lib/ld-linux-armhf.so.3 -X
--hash-style=gnu -m armelf_linux_eabi -o test
/usr/lib/gcc/arm-linux-gnueabihf/6/../../../arm-linux-gnueabihf/crt1.o
/usr/lib/gcc/arm-linux-gnueabihf/6/../../../arm-linux-gnueabihf/crti.o
/usr/lib/gcc/arm-linux-gnueabihf/6/crtbegin.o
-L/usr/lib/gcc/arm-linux-gnueabihf/6
-L/usr/lib/gcc/arm-linux-gnueabihf/6/../../../arm-linux-gnueabihf
-L/usr/lib/gcc/arm-linux-gnueabihf/6/../../.. -L/lib/arm-linux-gnueabihf
-L/usr/lib/arm-linux-gnueabihf test.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s
-lgcc /usr/lib/gcc/arm-linux-gnueabihf/6/crtend.o
/usr/lib/gcc/arm-linux-gnueabihf/6/../../../arm-linux-gnueabihf/crtn.o
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'test' '-shared-libgcc'
'-march=armv6' '-mfloat-abi=hard' '-mfpu=vfp' '-mtls-dialect=gnu'