From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2153) id B9CCB385800E; Mon, 6 Sep 2021 08:09:17 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B9CCB385800E MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jakub Jelinek To: gcc-cvs@gcc.gnu.org Subject: [gcc r12-3365] match.pd: Fix up __builtin_*_overflow arg demotion [PR102207] X-Act-Checkin: gcc X-Git-Author: Jakub Jelinek X-Git-Refname: refs/heads/master X-Git-Oldrev: 564efbf40077c25623cdd6ce2f911c56b5b08f6c X-Git-Newrev: 8a4602c2e0f81895415ba7ee23bf81dc795d1103 Message-Id: <20210906080917.B9CCB385800E@sourceware.org> Date: Mon, 6 Sep 2021 08:09:17 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Sep 2021 08:09:17 -0000 https://gcc.gnu.org/g:8a4602c2e0f81895415ba7ee23bf81dc795d1103 commit r12-3365-g8a4602c2e0f81895415ba7ee23bf81dc795d1103 Author: Jakub Jelinek Date: Mon Sep 6 10:08:16 2021 +0200 match.pd: Fix up __builtin_*_overflow arg demotion [PR102207] My earlier patch to demote arguments of __builtin_*_overflow unfortunately caused a wrong-code regression. The builtins operate on infinite precision arguments, outer_prec > inner_prec signed -> signed, unsigned -> unsigned promotions there are just repeating the sign or 0s and can be demoted, similarly unsigned -> signed which also is repeating 0s, but as the testcase shows, signed -> unsigned promotions need to be preserved (unless we'd know the inner arguments can't be negative), because for negative numbers such promotion sets the outer_prec -> inner_prec bits to 1 bit the bits above that to 0 in the infinite precision. So, the following patch avoids the demotions for the signed -> unsigned promotions. 2021-09-06 Jakub Jelinek PR tree-optimization/102207 * match.pd: Don't demote operands of IFN_{ADD,SUB,MUL}_OVERFLOW if they were promoted from signed to wider unsigned type. * gcc.dg/pr102207.c: New test. Diff: --- gcc/match.pd | 6 ++++-- gcc/testsuite/gcc.dg/pr102207.c | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/gcc/match.pd b/gcc/match.pd index cc7809dfe0f..008f7758c96 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -5608,13 +5608,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (ovf (convert@2 @0) @1) (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && INTEGRAL_TYPE_P (TREE_TYPE (@2)) - && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE (@0))) + && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE (@0)) + && (!TYPE_UNSIGNED (TREE_TYPE (@2)) || TYPE_UNSIGNED (TREE_TYPE (@0)))) (ovf @0 @1))) (simplify (ovf @1 (convert@2 @0)) (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && INTEGRAL_TYPE_P (TREE_TYPE (@2)) - && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE (@0))) + && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE (@0)) + && (!TYPE_UNSIGNED (TREE_TYPE (@2)) || TYPE_UNSIGNED (TREE_TYPE (@0)))) (ovf @1 @0)))) /* Simplification of math builtins. These rules must all be optimizations diff --git a/gcc/testsuite/gcc.dg/pr102207.c b/gcc/testsuite/gcc.dg/pr102207.c new file mode 100644 index 00000000000..08540d0c180 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr102207.c @@ -0,0 +1,24 @@ +/* PR tree-optimization/102207 */ +/* { dg-do run { target int128 } } */ +/* { dg-options "-O2" } */ + +typedef unsigned __int128 u128; + +u128 +foo (unsigned short a) +{ + u128 g; + __builtin_sub_overflow ((unsigned long long) -a, 1, &g); + return g; +} + +int +main () +{ + if (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ != 64 + || __SIZEOF_SHORT__ * __CHAR_BIT__ != 16) + return 0; + if (foo (1) != 0xfffffffffffffffeULL) + __builtin_abort (); + return 0; +}