From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1314) id 6004D3858D3C; Fri, 2 Jun 2023 19:30:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6004D3858D3C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1685734237; bh=O4owiCwYCxU4pSjwJbSeeiz8oeVlX0v6NvYniw9AIzs=; h=From:To:Subject:Date:From; b=agQbOfM1+YUu52zsrAK11aFqDWpAm6mE1Av+rPLrdN1zeELR08/3tqAYnD7dksg7U NhXW4+j7L2VwE3hPh5H9iSBMcwZzIjIvO4odGEoU5cHjunjx4HThssyZeQkVvYBX8s iWaZcEhNedmNNZUDBftHxECXMwxQ2I0pU34Po5IA= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Andrew Pinski To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-1507] Fix PR 110042: ifcvt regression due to paradoxical subregs X-Act-Checkin: gcc X-Git-Author: Andrew Pinski X-Git-Refname: refs/heads/trunk X-Git-Oldrev: 84d080a29a780973bef47171ba708ae2f7b4ee47 X-Git-Newrev: df0853d72d38247aed577a4511450c91794f2f06 Message-Id: <20230602193037.6004D3858D3C@sourceware.org> Date: Fri, 2 Jun 2023 19:30:37 +0000 (GMT) List-Id: https://gcc.gnu.org/g:df0853d72d38247aed577a4511450c91794f2f06 commit r14-1507-gdf0853d72d38247aed577a4511450c91794f2f06 Author: Andrew Pinski Date: Tue May 30 15:54:32 2023 -0700 Fix PR 110042: ifcvt regression due to paradoxical subregs After r14-1014-gc5df248509b489364c573e8, GCC started to emit directly a zero_extract for `(t1&0x8)!=0`. This introduced a small regression where ifcvt would not do the ifconversion as there is now a paradoxical subreg in the dest which was being rejected. Since paradoxical subreg set the whole register, we can treat it as the same as a reg in the two places. OK? Bootstrapped and tested on x86_64-linux-gnu and aarch64-linux-gnu. gcc/ChangeLog: PR rtl-optimization/110042 * ifcvt.cc (bbs_ok_for_cmove_arith): Allow paradoxical subregs. (bb_valid_for_noce_process_p): Strip the subreg for the SET_DEST. gcc/testsuite/ChangeLog: PR rtl-optimization/110042 * gcc.target/aarch64/csel_bfx_2.c: New test. Diff: --- gcc/ifcvt.cc | 14 +++++++++----- gcc/testsuite/gcc.target/aarch64/csel_bfx_2.c | 27 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc index 868eda93251..0b180b4568f 100644 --- a/gcc/ifcvt.cc +++ b/gcc/ifcvt.cc @@ -2022,7 +2022,7 @@ bbs_ok_for_cmove_arith (basic_block bb_a, basic_block bb_b, rtx to_rename) } /* Make sure this is a REG and not some instance - of ZERO_EXTRACT or SUBREG or other dangerous stuff. + of ZERO_EXTRACT or non-paradoxical SUBREG or other dangerous stuff. If we have a memory destination then we have a pair of simple basic blocks performing an operation of the form [addr] = c ? a : b. bb_valid_for_noce_process_p will have ensured that these are @@ -2030,7 +2030,8 @@ bbs_ok_for_cmove_arith (basic_block bb_a, basic_block bb_b, rtx to_rename) to be renamed. Assert that the callers set this up properly. */ if (MEM_P (SET_DEST (sset_b))) gcc_assert (rtx_equal_p (SET_DEST (sset_b), to_rename)); - else if (!REG_P (SET_DEST (sset_b))) + else if (!REG_P (SET_DEST (sset_b)) + && !paradoxical_subreg_p (SET_DEST (sset_b))) { BITMAP_FREE (bba_sets); return false; @@ -3136,14 +3137,17 @@ bb_valid_for_noce_process_p (basic_block test_bb, rtx cond, rtx sset = single_set (insn); gcc_assert (sset); + rtx dest = SET_DEST (sset); + if (SUBREG_P (dest)) + dest = SUBREG_REG (dest); if (contains_mem_rtx_p (SET_SRC (sset)) - || !REG_P (SET_DEST (sset)) - || reg_overlap_mentioned_p (SET_DEST (sset), cond)) + || !REG_P (dest) + || reg_overlap_mentioned_p (dest, cond)) goto free_bitmap_and_fail; potential_cost += pattern_cost (sset, speed_p); - bitmap_set_bit (test_bb_temps, REGNO (SET_DEST (sset))); + bitmap_set_bit (test_bb_temps, REGNO (dest)); } } diff --git a/gcc/testsuite/gcc.target/aarch64/csel_bfx_2.c b/gcc/testsuite/gcc.target/aarch64/csel_bfx_2.c new file mode 100644 index 00000000000..c3b8a6f45cc --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/csel_bfx_2.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +unsigned +f1(int t, int t1) +{ + int tt = 0; + if(t) + tt = (t1&0x8)!=0; + return tt; +} +struct f +{ + unsigned t:3; + unsigned t1:4; +}; +unsigned +f2(int t, struct f y) +{ + int tt = 0; + if(t) + tt = y.t1; + return tt; +} +/* Both f1 and f2 should produce a csel and not a cbz on the argument. */ +/* { dg-final { scan-assembler-times "csel\t" 2 } } */ +/* { dg-final { scan-assembler-times "ubfx\t" 2 } } */ +/* { dg-final { scan-assembler-not "cbz\t" } } */