From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1314) id 2B3D2385357A; Wed, 24 Aug 2022 19:20:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2B3D2385357A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1661368839; bh=oDDHfGzT+Rm0LHjD1ExjLuVPwxrdejGFmTnMPIT0btg=; h=From:To:Subject:Date:From; b=a1MhgkztmZNE5aRjCF/nmyn/y+zGIPmae2BhgJruiqlwlxDd6GSyoWIbQ1xd57kI4 QouXq8XJcGXvVduT9mt2ydfufVQa39JJ1bONJHGZQIHEax7/imWbwnvaKM0WNP7JTm 9fbVDfxBUVj2BigBSkAHNgK2V7lBy4pnImlg6S1o= 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 r13-2188] [RISCV] Fix PR 106586: riscv32 vs ZBS X-Act-Checkin: gcc X-Git-Author: Andrew Pinski X-Git-Refname: refs/heads/trunk X-Git-Oldrev: 95989ab39bbedd34e6f508de3109cb5c17db433e X-Git-Newrev: 2c721ea9473ad7615bb47b66509097bd254bb839 Message-Id: <20220824192039.2B3D2385357A@sourceware.org> Date: Wed, 24 Aug 2022 19:20:39 +0000 (GMT) List-Id: https://gcc.gnu.org/g:2c721ea9473ad7615bb47b66509097bd254bb839 commit r13-2188-g2c721ea9473ad7615bb47b66509097bd254bb839 Author: Andrew Pinski Date: Mon Aug 15 22:25:13 2022 +0000 [RISCV] Fix PR 106586: riscv32 vs ZBS The problem here is two fold. With RISCV32, 32bit const_int are always signed extended to 64bit in HWI. So that means for SINGLE_BIT_MASK_OPERAND, it should mask off the upper bits to see it is a single bit for !TARGET_64BIT. Plus there are a few locations which forget to call trunc_int_for_mode when generating a SImode constant so they are not sign extended correctly for HWI. The predicates single_bit_mask_operand and not_single_bit_mask_operand need get the same handling as SINGLE_BIT_MASK_OPERAND so just use SINGLE_BIT_MASK_OPERAND. OK? Built and tested on riscv32-linux-gnu and riscv64-linux-gnu with --with-arch=rvNimafdc_zba_zbb_zbc_zbs where N is replaced with 32 or 64. Thanks, Andrew Pinski gcc/ChangeLog: PR target/106586 * config/riscv/predicates.md (single_bit_mask_operand): Use SINGLE_BIT_MASK_OPERAND instead of directly calling pow2p_hwi. (not_single_bit_mask_operand): Likewise. * config/riscv/riscv.cc (riscv_build_integer_1): Don't special case 1<<31 for 32bits as it is already handled. Call trunc_int_for_mode on the upper part after the subtraction. (riscv_move_integer): Call trunc_int_for_mode before generating the integer just make sure the constant has been sign extended corectly. (riscv_emit_int_compare): Call trunc_int_for_mode after doing the addition for the new rhs. * config/riscv/riscv.h (SINGLE_BIT_MASK_OPERAND): If !TARGET64BIT, then mask off the upper 32bits of the HWI as it will be sign extended. Diff: --- gcc/config/riscv/predicates.md | 4 ++-- gcc/config/riscv/riscv.cc | 12 +++++++++--- gcc/config/riscv/riscv.h | 4 +++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index 2af7f661d6f..862e72b0983 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -226,11 +226,11 @@ ;; Predicates for the ZBS extension. (define_predicate "single_bit_mask_operand" (and (match_code "const_int") - (match_test "pow2p_hwi (INTVAL (op))"))) + (match_test "SINGLE_BIT_MASK_OPERAND (UINTVAL (op))"))) (define_predicate "not_single_bit_mask_operand" (and (match_code "const_int") - (match_test "pow2p_hwi (~INTVAL (op))"))) + (match_test "SINGLE_BIT_MASK_OPERAND (~UINTVAL (op))"))) (define_predicate "const31_operand" (and (match_code "const_int") diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 22d0f6d604c..026c69ce40d 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -432,7 +432,7 @@ riscv_build_integer_1 (struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS], sign-extended (negative) representation (-1 << 31) for the value, if we want to build (1 << 31) in SImode. This will then expand to an LUI instruction. */ - if (mode == SImode && value == (HOST_WIDE_INT_1U << 31)) + if (TARGET_64BIT && mode == SImode && value == (HOST_WIDE_INT_1U << 31)) codes[0].value = (HOST_WIDE_INT_M1U << 31); return 1; @@ -445,7 +445,11 @@ riscv_build_integer_1 (struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS], && (mode != HImode || value - low_part <= ((1 << (GET_MODE_BITSIZE (HImode) - 1)) - 1))) { - alt_cost = 1 + riscv_build_integer_1 (alt_codes, value - low_part, mode); + HOST_WIDE_INT upper_part = value - low_part; + if (mode != VOIDmode) + upper_part = trunc_int_for_mode (value - low_part, mode); + + alt_cost = 1 + riscv_build_integer_1 (alt_codes, upper_part, mode); if (alt_cost < cost) { alt_codes[alt_cost-1].code = PLUS; @@ -1550,6 +1554,7 @@ riscv_move_integer (rtx temp, rtx dest, HOST_WIDE_INT value, x = riscv_split_integer (value, mode); else { + codes[0].value = trunc_int_for_mode (codes[0].value, mode); /* Apply each binary operation to X. */ x = GEN_INT (codes[0].value); @@ -1559,7 +1564,7 @@ riscv_move_integer (rtx temp, rtx dest, HOST_WIDE_INT value, x = riscv_emit_set (temp, x); else x = force_reg (mode, x); - + codes[i].value = trunc_int_for_mode (codes[i].value, mode); x = gen_rtx_fmt_ee (codes[i].code, mode, x, GEN_INT (codes[i].value)); } } @@ -2651,6 +2656,7 @@ riscv_emit_int_compare (enum rtx_code *code, rtx *op0, rtx *op1) continue; new_rhs = rhs + (increment ? 1 : -1); + new_rhs = trunc_int_for_mode (new_rhs, GET_MODE (*op0)); if (riscv_integer_cost (new_rhs) < riscv_integer_cost (rhs) && (rhs < 0) == (new_rhs < 0)) { diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 4b07c5487c6..5394776eb50 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -535,7 +535,9 @@ enum reg_class /* If this is a single bit mask, then we can load it with bseti. Special handling of SImode 0x80000000 on RV64 is done in riscv_build_integer_1. */ #define SINGLE_BIT_MASK_OPERAND(VALUE) \ - (pow2p_hwi (VALUE)) + (pow2p_hwi (TARGET_64BIT \ + ? (VALUE) \ + : ((VALUE) & ((HOST_WIDE_INT_1U << 32)-1)))) /* Stack layout; function entry, exit and calling. */