From: Jakub Jelinek Date: Wed, 7 May 2014 16:05:38 +0000 (+0200) Subject: backport: re PR middle-end/58564 (possible wrong code bug at -O0) X-Git-Tag: releases/gcc-4.7.4~102 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=11d82e337418fa5502adb8edd3ef4a51b30e8991;p=thirdparty%2Fgcc.git backport: re PR middle-end/58564 (possible wrong code bug at -O0) Backported from mainline 2013-09-30 Jakub Jelinek PR middle-end/58564 * fold-const.c (fold_ternary_loc): For A < 0 : : 0 optimization, punt if sign_bit_p looked through any zero extension. * gcc.c-torture/execute/pr58564.c: New test. From-SVN: r210174 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 139a579103a8..940ed0fb7c06 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,12 @@ 2014-05-07 Jakub Jelinek Backported from mainline + 2013-09-30 Jakub Jelinek + + PR middle-end/58564 + * fold-const.c (fold_ternary_loc): For A < 0 : : 0 + optimization, punt if sign_bit_p looked through any zero extension. + 2013-09-10 Jakub Jelinek PR rtl-optimization/58365 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 804a05f927a0..d83f084dd038 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -13849,14 +13849,29 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, && integer_zerop (op2) && (tem = sign_bit_p (TREE_OPERAND (arg0, 0), arg1))) { + /* sign_bit_p looks through both zero and sign extensions, + but for this optimization only sign extensions are + usable. */ + tree tem2 = TREE_OPERAND (arg0, 0); + while (tem != tem2) + { + if (TREE_CODE (tem2) != NOP_EXPR + || TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (tem2, 0)))) + { + tem = NULL_TREE; + break; + } + tem2 = TREE_OPERAND (tem2, 0); + } /* sign_bit_p only checks ARG1 bits within A's precision. If has wider type than A, bits outside of A's precision in need to be checked. If they are all 0, this optimization needs to be done in unsigned A's type, if they are all 1 in signed A's type, otherwise this can't be done. */ - if (TYPE_PRECISION (TREE_TYPE (tem)) - < TYPE_PRECISION (TREE_TYPE (arg1)) + if (tem + && TYPE_PRECISION (TREE_TYPE (tem)) + < TYPE_PRECISION (TREE_TYPE (arg1)) && TYPE_PRECISION (TREE_TYPE (tem)) < TYPE_PRECISION (type)) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 362317863b61..b28b8ad0dce9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,11 @@ 2014-05-07 Jakub Jelinek Backported from mainline + 2013-09-30 Jakub Jelinek + + PR middle-end/58564 + * gcc.c-torture/execute/pr58564.c: New test. + 2013-09-10 Jakub Jelinek PR rtl-optimization/58365 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr58564.c b/gcc/testsuite/gcc.c-torture/execute/pr58564.c new file mode 100644 index 000000000000..967ee95d4abc --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr58564.c @@ -0,0 +1,14 @@ +/* PR middle-end/58564 */ + +extern void abort (void); +int a, b; +short *c, **d = &c; + +int +main () +{ + b = (0, 0 > ((&c == d) & (1 && (a ^ 1)))) | 0U; + if (b != 0) + abort (); + return 0; +}