This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/61872] New: Assigning to "long double" causes memset to be improperly elided
- From: "coleb at eyesopen dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 21 Jul 2014 17:32:54 +0000
- Subject: [Bug c++/61872] New: Assigning to "long double" causes memset to be improperly elided
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61872
Bug ID: 61872
Summary: Assigning to "long double" causes memset to be
improperly elided
Product: gcc
Version: 4.8.2
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: coleb at eyesopen dot com
Created attachment 33169
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33169&action=edit
Intermediate file generated by the compiler for the above test case
The following code zeros out memory being used as a "long double" in order to
be able to memcmp the memory later. However, assigning to the long double later
causes the optimizer to omit the preceding memset of zero.
The following code boils this down to a simple test case:
#include <assert.h>
#include <string.h>
#include <iomanip>
#include <iostream>
void Dump( const void * mem, size_t n )
{
const unsigned char * p = reinterpret_cast< const unsigned char *>( mem );
for ( size_t i = 0; i < n; i++ )
{
std::cout << std::hex << std::setw(2) << std::setfill( std::cout.widen('0')
) << int(p[i]) << " ";
}
std::cout << std::endl;
}
int main()
{
long double a;
memset(&a, '\0', sizeof(long double));
//Dump(&a, sizeof(long double)); // Uncomment me to make the test pass
a = 1.0;
long double b;
memset(&b, '\0', sizeof(long double));
//Dump(&b, sizeof(long double)); // Uncomment me to make the test pass
b = 1.0;
std::cout << memcmp(&a, &b, sizeof(long double)) << std::endl;
Dump(&a, sizeof(long double));
Dump(&b, sizeof(long double));
assert(memcmp(&a, &b, sizeof(long double)) == 0);
}
Uncommenting the "Dump" function calls causing the test to pass, presumably
because the optimizer notices the zero'd out memory is now being used by Dump
before the assignment.
Note, this only occurs with -O1 or higher.
I've attached the associated .ii files from the following command:
coleb@rhel7:~> g++ -v -save-temps -O1 ./LongDoubleMemSetElided.cpp && ./a.out
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.2/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla
--enable-bootstrap --enable-shared --enable-threads=posix
--enable-checking=release --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-gnu-unique-object
--enable-linker-build-id --with-linker-hash-style=gnu
--enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin
--enable-initfini-array --disable-libgcj
--with-isl=/builddir/build/BUILD/gcc-4.8.2-20131106/obj-x86_64-redhat-linux/isl-install
--with-cloog=/builddir/build/BUILD/gcc-4.8.2-20131106/obj-x86_64-redhat-linux/cloog-install
--with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.8.2 20131106 (Red Hat 4.8.2-3) (GCC)
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O1' '-shared-libgcc' '-mtune=generic'
'-march=x86-64'
/usr/libexec/gcc/x86_64-redhat-linux/4.8.2/cc1plus -E -quiet -v -D_GNU_SOURCE
./LongDoubleMemSetElided.cpp -mtune=generic -march=x86-64 -O1 -fpch-preprocess
-o LongDoubleMemSetElided.ii
ignoring nonexistent directory
"/usr/lib/gcc/x86_64-redhat-linux/4.8.2/include-fixed"
ignoring nonexistent directory
"/usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../x86_64-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../include/c++/4.8.2
/usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../include/c++/4.8.2/x86_64-redhat-linux
/usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../include/c++/4.8.2/backward
/usr/lib/gcc/x86_64-redhat-linux/4.8.2/include
/usr/local/include
/usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O1' '-shared-libgcc' '-mtune=generic'
'-march=x86-64'
/usr/libexec/gcc/x86_64-redhat-linux/4.8.2/cc1plus -fpreprocessed
LongDoubleMemSetElided.ii -quiet -dumpbase LongDoubleMemSetElided.cpp
-mtune=generic -march=x86-64 -auxbase LongDoubleMemSetElided -O1 -version -o
LongDoubleMemSetElided.s
GNU C++ (GCC) version 4.8.2 20131106 (Red Hat 4.8.2-3) (x86_64-redhat-linux)
compiled by GNU C version 4.8.2 20131106 (Red Hat 4.8.2-3), GMP version
5.1.1, MPFR version 3.1.1, MPC version 1.0.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C++ (GCC) version 4.8.2 20131106 (Red Hat 4.8.2-3) (x86_64-redhat-linux)
compiled by GNU C version 4.8.2 20131106 (Red Hat 4.8.2-3), GMP version
5.1.1, MPFR version 3.1.1, MPC version 1.0.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 854a658c8d093bd199c43bf0150da7d8
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O1' '-shared-libgcc' '-mtune=generic'
'-march=x86-64'
as -v --64 -o LongDoubleMemSetElided.o LongDoubleMemSetElided.s
GNU assembler version 2.23.52.0.1 (x86_64-redhat-linux) using BFD version
version 2.23.52.0.1-12.el7 20130226
COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux/4.8.2/:/usr/libexec/gcc/x86_64-redhat-linux/4.8.2/:/usr/libexec/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/4.8.2/:/usr/lib/gcc/x86_64-redhat-linux/
LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/4.8.2/:/usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O1' '-shared-libgcc' '-mtune=generic'
'-march=x86-64'
/usr/libexec/gcc/x86_64-redhat-linux/4.8.2/collect2 --build-id --no-add-needed
--eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker
/lib64/ld-linux-x86-64.so.2
/usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../lib64/crt1.o
/usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../lib64/crti.o
/usr/lib/gcc/x86_64-redhat-linux/4.8.2/crtbegin.o
-L/usr/lib/gcc/x86_64-redhat-linux/4.8.2
-L/usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../lib64 -L/lib/../lib64
-L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../..
LongDoubleMemSetElided.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
/usr/lib/gcc/x86_64-redhat-linux/4.8.2/crtend.o
/usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../lib64/crtn.o
64
00 00 00 00 00 00 00 80 ff 3f 40 00 00 00 00 00
00 00 00 00 00 00 00 80 ff 3f 00 00 00 00 00 00
a.out: ./LongDoubleMemSetElided.cpp:33: int main(): Assertion `memcmp(&a, &b,
sizeof(long double)) == 0' failed.
Aborted (core dumped)
Thank you!