From: jakub Date: Thu, 19 Nov 2015 08:49:59 +0000 (+0000) Subject: PR rtl-optimization/68376 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e9007d262d11bd1d9635051e1919aa2c52ef63f8;p=thirdparty%2Fgcc.git 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@230596 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ea632f60c19a..5eb064668952 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-11-19 Jakub Jelinek + + 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 PR middle-end/68117 diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 56e4ed425764..eb5cae5a7539 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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8c7746ff7294..319d1f3a2d3e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2015-11-19 Jakub Jelinek + 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. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr68376-1.c b/gcc/testsuite/gcc.c-torture/execute/pr68376-1.c new file mode 100644 index 000000000000..cb52657646cb --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr68376-1.c @@ -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; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr68376-2.c b/gcc/testsuite/gcc.c-torture/execute/pr68376-2.c new file mode 100644 index 000000000000..884571a89233 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr68376-2.c @@ -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; +}