[Bug tree-optimization/88240] Potential optimization bug: invalid pre-load of floating-point value could cause SIGFPE-underflow if value is integer

2019-03-26 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88240
Bug 88240 depends on bug 86554, which changed state.

Bug 86554 Summary: [7 Regression] Incorrect code generation with 
signed/unsigned comparison
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86554

   What|Removed |Added

 Status|ASSIGNED|RESOLVED
 Resolution|--- |FIXED

[Bug tree-optimization/88240] Potential optimization bug: invalid pre-load of floating-point value could cause SIGFPE-underflow if value is integer

2019-01-22 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88240

Richard Biener  changed:

   What|Removed |Added

   Keywords||wrong-code
 Status|UNCONFIRMED |ASSIGNED
   Last reconfirmed||2019-01-22
   Assignee|unassigned at gcc dot gnu.org  |rguenth at gcc dot 
gnu.org
 Ever confirmed|0   |1

--- Comment #12 from Richard Biener  ---
Yes, IMHO the bug is valid.  I've ment to assign myself (though don't hold your
breath for a fix).

[Bug tree-optimization/88240] Potential optimization bug: invalid pre-load of floating-point value could cause SIGFPE-underflow if value is integer

2019-01-22 Thread patrickdepinguin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88240

--- Comment #11 from Thomas De Schampheleire  ---
Any feedback? With the reduced testcase qemu is out of the picture.
Do you agree that this is a bug in gcc?

[Bug tree-optimization/88240] Potential optimization bug: invalid pre-load of floating-point value could cause SIGFPE-underflow if value is integer

2018-12-06 Thread patrickdepinguin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88240

--- Comment #10 from Thomas De Schampheleire  ---
I was able to further investigate and reduce the problem.
Qemu is now out of the picture, I can reproduce the issue directly on a real
CPU. All I need to do is enable the 'underflow' exception bit using
feenableexcept. Note that, as you will see below in the gdb output, the
denormal exception is not enabled.

Toolchain is still the same: gcc 7.3.0, glibc 2.27, binutils 2.30. See details
in bug description.

Below is the simplified test program, based on [1] with the addition of the
exception enabling code.


#define _GNU_SOURCE
#include 
#include 
#include 

static int callback(void *NotUsed, int argc, char **argv, char **azColName){
  int i;
  for(i=0; i end of added code

  rc = sqlite3_open(argv[2], &db);
  if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return(1);
  }
  rc = sqlite3_exec(db, argv[3], callback, 0, &zErrMsg);
  if( rc!=SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
  }
  sqlite3_close(db);
  return 0;
}


I compiled this code and sqlite3 (version 321, but I don't think the exact
version matters much) with the mentioned toolchain.

Compilation command used for the test program:
/home/tdescham/repo/isam/buildroot-qemu/output/host/opt/ext-toolchain/bin/i686-pc-linux-gnu-gcc
--sysroot
/home/tdescham/repo/isam/buildroot-qemu/output/host/i686-buildroot-linux-gnu/sysroot
-march=pentiumpro -o sqlite-test sqlite-test.c -lsqlite3 -lm -g -O0

To reproduce, first create a simple database, not yet enabling exceptions:

$ env
LD_LIBRARY_PATH=/home/tdescham/repo/isam/buildroot-qemu/output/staging/usr/lib
./sqlite-test 0 /tmp/foo.db "create table foobar (id int primary key, name
text)"
Not enabling exceptions.
fctrl = 037f


Now, we can trigger the bug by showing some SQL output, if we enable the
underflow exception:

$ env
LD_LIBRARY_PATH=/home/tdescham/repo/isam/buildroot-qemu/output/staging/usr/lib
./sqlite-test 1 /tmp/foo.db "select sql from sqlite_master where sql not NULL;"
Enabling exception: FE_UNDERFLOW
fctrl = 036f
fish: Job 2, 'env LD_LIBRARY_PATH=/home/tdesc…' terminated by signal SIGFPE
(Floating point exception)


If we do not enable the underflow exception, everything is fine:

$ env
LD_LIBRARY_PATH=/home/tdescham/repo/isam/buildroot-qemu/output/staging/usr/lib
./sqlite-test 0 /tmp/foo.db "select sql from sqlite_master where sql not NULL;"
Not enabling exceptions.
fctrl = 037f
sql = CREATE TABLE foobar (id int primary key, name text)



Here is the output of a debug session using gdb:


$ env
LD_LIBRARY_PATH=/home/tdescham/repo/isam/buildroot-qemu/output/staging/usr/lib
gdb ./sqlite-test
GNU gdb (Gentoo 8.1 p1) 8.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./sqlite-test...done.
(gdb) display $fctrl
1: $fctrl = 
(gdb) display $fstat
2: $fstat = 
(gdb) display $ftag
3: $ftag = 
(gdb) display $fop
4: $fop = 
(gdb) display $st0
5: $st0 = 
(gdb) display $st1
6: $st1 = 
(gdb) display $st2
7: $st2 = 
(gdb) break sqlite3VdbeMemStringify
Function "sqlite3VdbeMemStringify" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (sqlite3VdbeMemStringify) pending.

(gdb) run 1 /tmp/test.db "select sql from sqlite_master where sql not NULL;"
Starting program: /tmp/x86/sqlite-test 1 /tmp/test.db "select sql from
sqlite_master where sql not NULL;"
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Enabling exception: FE_UNDERFLOW
fctrl = 036f

Breakpoint 1, sqlite3VdbeMemStringify (pMem=0x8064290, enc=0x1, bForce=0x0)
at sqlite3.c:70725
70725   SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8
bForce){
1: $fctrl = 0x36f
2: $fstat = 0x0
3: $ftag = 0x
4: $fop = 0x0
5: $st0 = 0
6: $st1 = 0
7: $st2 = 0

(gdb) break *(&sqlite3VdbeMemStringify + 68)
Breakpoint 2 at 0xf7f53bd4: file sqlite3.c, line 70748.

##
## NOTE: Showing disassembly of this function for context.
## Bug will occur at offset 68, but only after passing it the second time.
##

(gdb) disassemble /m
Dump of assembler code for function sqlite3VdbeMemStringify:
70725   SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8
bForce){
=> 0xf7f53b90 <+0>:   

[Bug tree-optimization/88240] Potential optimization bug: invalid pre-load of floating-point value could cause SIGFPE-underflow if value is integer

2018-11-29 Thread fw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88240

--- Comment #9 from Florian Weimer  ---
(In reply to Thomas De Schampheleire from comment #6)
> (In reply to Florian Weimer from comment #5)
> > This is QEMU with TCG, right?  It could be an i387 emulation bug.
> 
> I don't think so. Isn't it so that KVM and TCG are mutually exclusive
> choices?
> We see the problem if we pass --enable-kvm and don't see the problem if we
> don't pass that flag. From my limited understanding of qemu, not paying the
> flag means that the default TCG emulation is used. Am I wrong?

Right, my mistake.

[Bug tree-optimization/88240] Potential optimization bug: invalid pre-load of floating-point value could cause SIGFPE-underflow if value is integer

2018-11-28 Thread patrickdepinguin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88240

--- Comment #8 from Thomas De Schampheleire  
---
To clarify the situation with underflow / denormal exception I will debug the
issue again and inspect the corresponding registers.

I'm not familiar with 'NaNs': is it a specific value that I can see in the
union variable? During debugging, the union value was '3'.

[Bug tree-optimization/88240] Potential optimization bug: invalid pre-load of floating-point value could cause SIGFPE-underflow if value is integer

2018-11-28 Thread joseph at codesourcery dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88240

--- Comment #7 from joseph at codesourcery dot com  ---
As discussed, the load instructions should never raise underflow 
exceptions, and having traps enabled for the nonstandard denormal operand 
exception is clearly outside the scope of what code generation should 
support.  So the underflow exception being raised by a load seems like 
some kind of issue with the instruction implementation (but you should 
test the instruction directly on hardware without qemu involved).

*But* the issue definitely exists with loads of signaling NaNs converting 
them to quiet NaNs and raising "invalid", so modifying data (if the result 
gets stored back) as well as raising spurious exceptions.  See bug 58416 
(which as discussed there, is an issue even with -fno-signaling-nans, 
because it's perfectly valid to have the sNaN patterns in a union with 
-fno-signaling-nans if you don't actually access them as float/double).

So I think any bug here is a combination of a duplicate of bug 58416, 
possibly with some kind of qemu bug resulting in "underflow" being raised 
when "denormal operand" should actually be raised instead.

[Bug tree-optimization/88240] Potential optimization bug: invalid pre-load of floating-point value could cause SIGFPE-underflow if value is integer

2018-11-28 Thread patrickdepinguin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88240

--- Comment #6 from Thomas De Schampheleire  
---
(In reply to Florian Weimer from comment #5)
> (In reply to Thomas De Schampheleire from comment #4)
> > When analyzing this problem with gdb, we looked at the floating-point status
> > register before the fldl call, then after, and only the underflow bit was
> > new. But there were already other bits present, we probably should have set
> > the register to 0 first. Nevertheless, the underflow bit got set.
> 
> This is QEMU with TCG, right?  It could be an i387 emulation bug.

I don't think so. Isn't it so that KVM and TCG are mutually exclusive choices?
We see the problem if we pass --enable-kvm and don't see the problem if we
don't pass that flag. From my limited understanding of qemu, not paying the
flag means that the default TCG emulation is used. Am I wrong?

[Bug tree-optimization/88240] Potential optimization bug: invalid pre-load of floating-point value could cause SIGFPE-underflow if value is integer

2018-11-28 Thread fw at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88240

Florian Weimer  changed:

   What|Removed |Added

 CC||fw at gcc dot gnu.org

--- Comment #5 from Florian Weimer  ---
(In reply to Thomas De Schampheleire from comment #4)
> When analyzing this problem with gdb, we looked at the floating-point status
> register before the fldl call, then after, and only the underflow bit was
> new. But there were already other bits present, we probably should have set
> the register to 0 first. Nevertheless, the underflow bit got set.

This is QEMU with TCG, right?  It could be an i387 emulation bug.

[Bug tree-optimization/88240] Potential optimization bug: invalid pre-load of floating-point value could cause SIGFPE-underflow if value is integer

2018-11-28 Thread patrickdepinguin at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88240

--- Comment #4 from Thomas De Schampheleire  
---
(In reply to Uroš Bizjak from comment #2)
> (In reply to Thomas De Schampheleire from comment #0)
> > gcc 7.3.0 optimizes below code in a way that may cause a floating-point
> > underflow (SIGFPE with underflow flag) on x86. The underflow occurs on an
> > 'fldl' instruction.
> 
> FLD will generate _denormal_ (#DE) exception for denormal single and double
> FP operand ([1], 8.5.2). This is a non-standard exception, and has to be
> distinguished from numeric underflow exception (#UE). Is there a reason for
> denormal exception to be unmasked? 
> 
> [1] http://home.agh.edu.pl/~amrozek/x87.pdf

I don't think we intentionally set any such flags from the application code.
How would the denormal exception be enabled? Is that with feenableexcept ?

When analyzing this problem with gdb, we looked at the floating-point status
register before the fldl call, then after, and only the underflow bit was new.
But there were already other bits present, we probably should have set the
register to 0 first. Nevertheless, the underflow bit got set.

[Bug tree-optimization/88240] Potential optimization bug: invalid pre-load of floating-point value could cause SIGFPE-underflow if value is integer

2018-11-28 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88240

Richard Biener  changed:

   What|Removed |Added

 CC||rguenth at gcc dot gnu.org
  Component|other   |tree-optimization
 Depends on||86554

--- Comment #3 from Richard Biener  ---
The following culd be massaged into a testcase:

int flag;
union { float f; int i; } u;
int main()
{
  if (flag)
__builtin_printf("%d", u.i);
  else
__builtin_printf("%f", u.f);
  return 0;
}

It is PRE / code hoisting that hoists the loaded value (and it chooses the
float variant).  -fno-code-hoisting should mitigate this.  PR86554 is a
related issue.

main ()
{
  int flag.0_1;
  double _4;
  float pretmp_10;
  int _11;

   [100.00%]:
  flag.0_1 = flag;
  pretmp_10 = u.f;
  if (flag.0_1 != 0)
goto ; [46.00%]
  else
goto ; [54.00%]

   [46.00%]:
  _11 = VIEW_CONVERT_EXPR(pretmp_10);
  __builtin_printf ("%d", _11);
  goto ; [100.00%]

   [54.00%]:
  _4 = (double) pretmp_10;
  __builtin_printf ("%f", _4);


Given the intention of the optimization is to CSE loading the memory contents
and we elsewhere avoid using floats for such operation the bug is probably
valid.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86554
[Bug 86554] [7/8/9 Regression] Incorrect code generation with signed/unsigned
comparison