Bug 64255 - [5 Regression] failures with -O2 optimization on i >= 0 ? (unsigned long) i : - (unsigned long) i
Summary: [5 Regression] failures with -O2 optimization on i >= 0 ? (unsigned long) i :...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 5.0
: P1 normal
Target Milestone: 5.0
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on: 63917
Blocks:
  Show dependency treegraph
 
Reported: 2014-12-10 15:31 UTC by Vincent Lefèvre
Modified: 2014-12-12 12:44 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2014-12-10 00:00:00


Attachments
testcase part 1 (tst1.c) (179 bytes, text/x-csrc)
2014-12-10 16:51 UTC, Vincent Lefèvre
Details
testcase part 2 (tst2.c) (59 bytes, text/x-csrc)
2014-12-10 16:52 UTC, Vincent Lefèvre
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Vincent Lefèvre 2014-12-10 15:31:06 UTC
I get failures when building and testing MPFR with:

gcc (Debian 20141209-1) 5.0.0 20141209 (experimental) [trunk revision 218514]

on x86_64, using:

./configure --enable-assert=full CC=gcc-snapshot 'CFLAGS=-Wall -O2 -g'

Using -O1 only makes the problems disappear.

If I simplify the MPFR code to:

int
mpfr_set_si_2exp (mpfr_ptr x, long i, mpfr_exp_t e, mpfr_rnd_t rnd_mode)
{
  if (i == 0)
    {
      return 0;
    }
  else
    {
      unsigned long ai;

      ai = i >= 0 ? (unsigned long) i : - (unsigned long) i;
      if ((i >= 0 ? (unsigned long) i : - (unsigned long) i) != ai)
        printf ("Error!\n");
      printf ("i = %ld\n", i);
      printf ("ai = %lX\n", ai);
      return 0;
    }
}

in set_si_2exp.c, and call:

  mpfr_set_si_2exp (x, 1, 0, 0);

I get:

i = 1
ai = FFFFFFFFFFFFFFFF

If I remove the

      if ((i >= 0 ? (unsigned long) i : - (unsigned long) i) != ai)
        printf ("Error!\n");

test, I get:

i = 1
ai = 1

as expected.

I don't know why, but I didn't manage to get a standalone testcase.
Comment 1 Marek Polacek 2014-12-10 15:38:22 UTC
Without the standalone test case we can't do much, unfortunately.  Would you have at least the preprocessed source?
Comment 2 Vincent Lefèvre 2014-12-10 16:51:34 UTC
Created attachment 34242 [details]
testcase part 1 (tst1.c)
Comment 3 Vincent Lefèvre 2014-12-10 16:52:07 UTC
Created attachment 34243 [details]
testcase part 2 (tst2.c)
Comment 4 Vincent Lefèvre 2014-12-10 16:53:56 UTC
(In reply to Marek Polacek from comment #1)
> Without the standalone test case we can't do much, unfortunately.  Would you
> have at least the preprocessed source?

It was actually a standalone test case, but one needs separate compilation to run it:

$ gcc-snapshot -Wall -Wextra -O2 -c tst1.c
$ gcc-snapshot -Wall -Wextra -O2 -c tst2.c
$ gcc-snapshot tst1.o tst2.o -o tst
$ ./tst
i = 1
ai = FFFFFFFFFFFFFFFF
Comment 5 Markus Trippelsdorf 2014-12-10 17:29:53 UTC
Confirmed. Testcase can be combined to one file:

markus@x4 tmp % cat test.c
#include <stdio.h>

__attribute__((noinline))
int f (long i)
{
  if (i == 0)
    {
      return 0;
    }
  else
    {
      unsigned long ai;

      ai = i >= 0 ? (unsigned long) i : - (unsigned long) i;
      if ((i >= 0 ? (unsigned long) i : - (unsigned long) i) != ai)
        printf ("Error!\n");
      printf ("i = %ld\n", i);
      printf ("ai = %lX\n", ai);
      return 0;
    }
}
int main (void)
{
  f (1);
  return 0;
}
Comment 6 Marek Polacek 2014-12-10 17:37:16 UTC
A better version:

void __attribute__ ((noinline, noclone))
bar (long int i)
{
  asm ("");
}

int __attribute__ ((noinline, noclone))
f (long i)
{
  if (i == 0)
    return 0;
  else
    {
      unsigned long ai = i >= 0 ? (unsigned long) i : -(unsigned long) i;
      if ((i >= 0 ? (unsigned long) i : -(unsigned long) i) != ai)
        bar (0);
      bar (i);
      return ai;
    }
}

int
main (void)
{
  if (f (1) != 1)
    __builtin_abort ();
}
Comment 7 Marek Polacek 2014-12-10 17:43:57 UTC
-fno-if-conversion seems to help.
Comment 8 Jakub Jelinek 2014-12-10 17:45:10 UTC
I had:
__attribute__((noinline, noclone))
void
bar (long i, unsigned long j)
{
  if (i != 1 || j != 1)
    __builtin_abort ();
}

__attribute__((noinline, noclone))
void
foo (long i)
{
  unsigned long j;

  if (!i)
    return;
  j = i >= 0 ? (unsigned long) i : - (unsigned long) i;
  if ((i >= 0 ? (unsigned long) i : - (unsigned long) i) != j)
    __builtin_abort ();
  bar (i, j);
}

int
main ()
{
  foo (1);
  return 0;
}

In any case, regressed with r217646, works with -O0/-O1, or -O2 -m32, fails with -O2 (on x86_64-linux).
Comment 9 Andrew Pinski 2014-12-10 17:46:28 UTC
(In reply to Marek Polacek from comment #7)
> -fno-if-conversion seems to help.

Then this is most likely a Dup of another bug which has a few version of a patch posted now.
Comment 10 Markus Trippelsdorf 2014-12-10 18:04:05 UTC
(In reply to Andrew Pinski from comment #9)
> (In reply to Marek Polacek from comment #7)
> > -fno-if-conversion seems to help.
> 
> Then this is most likely a Dup of another bug which has a few version of a
> patch posted now.

PR63917?
Comment 11 Andrew Pinski 2014-12-10 18:15:12 UTC
(In reply to Markus Trippelsdorf from comment #10)
> > Then this is most likely a Dup of another bug which has a few version of a
> > patch posted now.
> 
> PR63917?
yes.
Comment 12 Markus Trippelsdorf 2014-12-12 09:01:05 UTC
Fixed by r218658.
Comment 13 Jakub Jelinek 2014-12-12 12:44:06 UTC
Author: jakub
Date: Fri Dec 12 12:43:34 2014
New Revision: 218665

URL: https://gcc.gnu.org/viewcvs?rev=218665&root=gcc&view=rev
Log:
	PR rtl-optimization/64255
	* gcc.c-torture/execute/pr64255.c: New test.

	PR rtl-optimization/64260
	* gcc.c-torture/execute/pr64260.c: New test.

Added:
    trunk/gcc/testsuite/gcc.c-torture/execute/pr64255.c
    trunk/gcc/testsuite/gcc.c-torture/execute/pr64260.c
Modified:
    trunk/gcc/testsuite/ChangeLog