re PR rtl-optimization/68376 (wrong code at -O1 and above on x86_64-linux-gnu)

PR rtl-optimization/68376
	* ifcvt.c (noce_try_abs): Disable one_cmpl optimization if
	encountering x <= 0 ? ~x : x or x > 0 ? ~x : x.

	* gcc.c-torture/execute/pr68376-1.c: New test.
	* gcc.c-torture/execute/pr68376-2.c: New test.

From-SVN: r230596
This commit is contained in:
Jakub Jelinek 2015-11-19 09:49:59 +01:00 committed by Jakub Jelinek
parent bb35ccb1ef
commit dfc3d7a8a2
5 changed files with 116 additions and 4 deletions

View file

@ -1,3 +1,9 @@
2015-11-19 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/68376
* ifcvt.c (noce_try_abs): Disable one_cmpl optimization if
encountering x <= 0 ? ~x : x or x > 0 ? ~x : x.
2015-11-19 Richard Biener <rguenther@suse.de>
PR middle-end/68117

View file

@ -2595,12 +2595,49 @@ noce_try_abs (struct noce_if_info *if_info)
/* Work around funny ideas get_condition has wrt canonicalization.
Note that these rtx constants are known to be CONST_INT, and
therefore imply integer comparisons. */
therefore imply integer comparisons.
The one_cmpl case is more complicated, as we want to handle
only x < 0 ? ~x : x or x >= 0 ? ~x : x but not
x <= 0 ? ~x : x or x > 0 ? ~x : x, as the latter two
have different result for x == 0. */
if (c == constm1_rtx && GET_CODE (cond) == GT)
;
{
if (one_cmpl && negate)
return FALSE;
}
else if (c == const1_rtx && GET_CODE (cond) == LT)
;
else if (c != CONST0_RTX (GET_MODE (b)))
{
if (one_cmpl && !negate)
return FALSE;
}
else if (c == CONST0_RTX (GET_MODE (b)))
{
if (one_cmpl)
switch (GET_CODE (cond))
{
case GT:
if (!negate)
return FALSE;
break;
case GE:
/* >= 0 is the same case as above > -1. */
if (negate)
return FALSE;
break;
case LT:
if (negate)
return FALSE;
break;
case LE:
/* <= 0 is the same case as above < 1. */
if (!negate)
return FALSE;
break;
default:
return FALSE;
}
}
else
return FALSE;
/* Determine what sort of operation this is. */

View file

@ -1,5 +1,9 @@
2015-11-19 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/68376
* gcc.c-torture/execute/pr68376-1.c: New test.
* gcc.c-torture/execute/pr68376-2.c: New test.
PR target/67770
* gcc.target/i386/pr67770.c: New test.

View file

@ -0,0 +1,24 @@
/* PR rtl-optimization/68376 */
int a, b, c = 1;
signed char d;
int
main ()
{
for (; a < 1; a++)
for (; b < 1; b++)
{
signed char e = ~d;
if (d < 1)
e = d;
d = e;
if (!c)
__builtin_abort ();
}
if (d != 0)
__builtin_abort ();
return 0;
}

View file

@ -0,0 +1,41 @@
/* PR rtl-optimization/68376 */
extern void abort (void);
__attribute__((noinline, noclone)) int
f1 (int x)
{
return x < 0 ? ~x : x;
}
__attribute__((noinline, noclone)) int
f2 (int x)
{
return x < 0 ? x : ~x;
}
__attribute__((noinline, noclone)) int
f3 (int x)
{
return x <= 0 ? ~x : x;
}
__attribute__((noinline, noclone)) int
f4 (int x)
{
return x <= 0 ? x : ~x;
}
int
main ()
{
if (f1 (5) != 5 || f1 (-5) != 4 || f1 (0) != 0)
abort ();
if (f2 (5) != -6 || f2 (-5) != -5 || f2 (0) != -1)
abort ();
if (f3 (5) != 5 || f3 (-5) != 4 || f3 (0) != -1)
abort ();
if (f4 (5) != -6 || f4 (-5) != -5 || f4 (0) != 0)
abort ();
return 0;
}