Bug 66191 - GCC optimizes away if clause checking similar but not same condition
Summary: GCC optimizes away if clause checking similar but not same condition
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.9.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-05-18 11:54 UTC by Nenad Mikša
Modified: 2015-05-18 12:24 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Program that causes issue, executable, preprocessed output, GCC info, etc. (291.89 KB, application/x-gzip)
2015-05-18 11:54 UTC, Nenad Mikša
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Nenad Mikša 2015-05-18 11:54:28 UTC
Created attachment 35561 [details]
Program that causes issue, executable, preprocessed output, GCC info, etc.

Hello everyone,

this is my first GCC bug report so please tell me if something is missing. I've added all required by 'https://gcc.gnu.org/bugs/' in provided tar.gz file.

The bug happens when using optimization level O2 or higher.

Consider this chunk of code:

static const double double0_15[]={0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0};
static double _int2double(unsigned i){
   if (i<16)
       return double0_15[i];
   else
       return _int2double(i/16)*16.0+double0_15[i%16];
}

double int2double(int i){
    if (i<0)
       return -_int2double(-i);
    else
       return _int2double(i);
}

If 'int2double' is called with negative value (see attached tar.gz for complete example that reproduces the bug) then if clause in '_int2double' is skipped which causes a segfault if i<-16.

The code chunk is taken from free computer algebra system Giac (http://www-fourier.ujf-grenoble.fr/~parisse/giac.html).

In attached tar.gz you can find the minimal program that reproduces the issue, preprocessed outputs (.ii, .o and .s files) and invocation log (everything GCC prints to stderr while working, including build configuration, correct version etc.). The system is fully updated ArchLinux with GCC 4.9.2.

I've also attached full debug output of clang compiler for convenience because the same program can be compiled with clang without causing error.
Comment 1 Markus Trippelsdorf 2015-05-18 12:12:56 UTC
Well, you invoke undefined behavior when negate INT_MIN.
Comment 2 Jakub Jelinek 2015-05-18 12:13:48 UTC
Yeah.  You should have used e.g.
  return -_int2double(-(unsigned)i);
instead.
Comment 3 Nenad Mikša 2015-05-18 12:14:54 UTC
Thanks for info.
Comment 4 Jonathan Wakely 2015-05-18 12:24:32 UTC
Both GCC and Clang provide ubsan (via -fsanitize=undefined) which will find this error:

proba2.cpp:14:28: runtime error: negation of -2147483648 cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself