From dfc3d7a8a25f7235578a4f4547aa95dacf53fcb6 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 19 Nov 2015 09:49:59 +0100 Subject: 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 --- gcc/ifcvt.c | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) (limited to 'gcc/ifcvt.c') diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 56e4ed42..eb5cae5 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -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. */ -- cgit v1.1