Bug 39867 - [4.4/4.5 Regression] Wrong result of conditional operator exp < 2 ? 2U : (unsigned int) exp
Summary: [4.4/4.5 Regression] Wrong result of conditional operator exp < 2 ? 2U : (uns...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.4.0
: P3 major
Target Milestone: 4.4.1
Assignee: Paolo Bonzini
URL:
Keywords: wrong-code
: 40524 (view as bug list)
Depends on:
Blocks:
 
Reported: 2009-04-23 13:33 UTC by Vincent Lefèvre
Modified: 2009-06-23 09:43 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2009-04-23 15:52:19


Attachments
patch (586 bytes, patch)
2009-04-23 15:22 UTC, Paolo Bonzini
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Vincent Lefèvre 2009-04-23 13:33:45 UTC
With GCC 4.4.0, the following program outputs 4294967295 instead of 2:

#include <stdio.h>

int main (void)
{
  int exp = -1;
  printf ("%u\n", exp < 2 ? 2U : (unsigned int) exp);
  return 0;
}

Note: I've tried with gcc-snapshot under a Debian/unstable x86_64 Linux machine, but the same bug was reported to me, with gcc-4.4.0 (it was found by Philippe Theveny, who works on MPFR, and the MPFR tests fail because of that).

GCC 4.3.3 does not have this problem.
Comment 1 Vincent Lefèvre 2009-04-23 13:44:59 UTC
I forgot to say: the bug occurs whether one compiles with optimizations or not.
Comment 2 Richard Biener 2009-04-23 13:46:39 UTC
We fold it to

  return (int) MAX_EXPR <(unsigned int) exp, 2>;

which is obviously bogus.  4.3 produced

  return NON_LVALUE_EXPR <MAX_EXPR <exp, 2>>;

which is correct (well, but has likely mismatched types if the 2 is still unsigned).

Confirmed.
Comment 3 Paolo Bonzini 2009-04-23 15:22:54 UTC
Created attachment 17684 [details]
patch

Bootstrapped but not yet regtested.  Testcase:

/* { dg-do link } */
/* { dg-options "-O2" } */

int main (void)
{
  int exp = -1;
  /* Wrong folding of the LHS to an unsigned MAX leads to 4294967295 > 2.  */
  if (("%u\n", exp < 2 ? 2U : (unsigned int) exp) > 2)
    link_error ();
  return 0;
}
Comment 4 Paolo Bonzini 2009-04-24 10:29:37 UTC
Subject: Bug 39867

Author: bonzini
Date: Fri Apr 24 10:29:18 2009
New Revision: 146695

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=146695
Log:
2009-04-24  Paolo Bonzini  <bonzini@gnu.org>

	PR middle-end/39867
	* fold-const.c (fold_cond_expr_with_comparison): When folding
	> and >= to MAX, make sure the MAX uses the same type as the
	comparison operands.

testsuite:
2009-04-24  Paolo Bonzini  <bonzini@gnu.org>

	PR middle-end/39867
	* gcc.dg/pr39867.c: New.


Added:
    trunk/gcc/testsuite/gcc.dg/pr39867.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/fold-const.c
    trunk/gcc/testsuite/ChangeLog

Comment 5 Paolo Bonzini 2009-04-24 11:35:23 UTC
Subject: Bug 39867

Author: bonzini
Date: Fri Apr 24 11:34:59 2009
New Revision: 146702

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=146702
Log:
2009-04-24  Paolo Bonzini  <bonzini@gnu.org>

	PR middle-end/39867
	* fold-const.c (fold_cond_expr_with_comparison): When folding
	> and >= to MAX, make sure the MAX uses the same type as the
	comparison's operands.

testsuite:
2009-04-24  Paolo Bonzini  <bonzini@gnu.org>

	PR middle-end/39867
	* gcc.dg/pr39867.c: New.


Added:
    branches/gcc-4_4-branch/gcc/testsuite/gcc.dg/pr39867.c
      - copied unchanged from r146695, trunk/gcc/testsuite/gcc.dg/pr39867.c
Modified:
    branches/gcc-4_4-branch/gcc/ChangeLog
    branches/gcc-4_4-branch/gcc/fold-const.c
    branches/gcc-4_4-branch/gcc/testsuite/ChangeLog

Comment 6 Paolo Bonzini 2009-04-24 11:35:23 UTC
committed to both branches.
Comment 7 Richard Biener 2009-06-23 09:43:46 UTC
*** Bug 40524 has been marked as a duplicate of this bug. ***