public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: <apinski@marvell.com>
To: <gcc-patches@gcc.gnu.org>
Cc: Andrew Pinski <apinski@marvell.com>
Subject: [PATCH 08/10] [RISCV] Fix PR 106586: riscv32 vs ZBS
Date: Thu, 18 Aug 2022 15:03:51 -0700	[thread overview]
Message-ID: <1660860233-11175-9-git-send-email-apinski@marvell.com> (raw)
In-Reply-To: <1660860233-11175-1-git-send-email-apinski@marvell.com>

From: Andrew Pinski <apinski@marvell.com>

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.
---
 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 @@ (define_special_predicate "gpr_save_operation"
 ;; 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.  */
 
-- 
2.27.0


  parent reply	other threads:[~2022-08-18 22:04 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-18 22:03 [PATCH 00/10] [RISCV] Fix/improve the RISCV backend apinski
2022-08-18 22:03 ` [PATCH 01/10] [RISCV] Move iterators from riscv.md to iterators.md apinski
2022-08-18 22:03 ` [PATCH 02/10] [RISCV] Move iterators from bitmanip.md " apinski
2022-08-18 22:03 ` [PATCH 03/10] [RISCV] Move iterators from sync.md " apinski
2022-08-18 22:03 ` [PATCH 04/10] [RISCV] Add the list of operand modifiers to riscv.md too apinski
2022-08-18 22:03 ` [PATCH 05/10] [RISCV] Add %~ to print w if TARGET_64BIT and use it apinski
2022-08-18 22:03 ` [PATCH 06/10] [RISCV] Use constraints/predicates instead of checking const_int directly for shNadd patterns apinski
2022-08-22  8:47   ` Kito Cheng
2022-08-18 22:03 ` [PATCH 07/10] [RISCV] Use a constraint for bset<mode>_mask and bset<mode>_1_mask apinski
2022-08-18 22:03 ` apinski [this message]
2022-08-18 22:03 ` [PATCH 09/10] [RISCV] Add constraints for not_single_bit_mask_operand/single_bit_mask_operand apinski
2022-08-18 22:03 ` [PATCH 10/10] [RISCV] Fix PR 106632 and PR 106588 a few constraints in bitmanip.md apinski
2022-08-22  9:09   ` Kito Cheng
2022-08-22 20:44   ` Palmer Dabbelt
2022-08-22 20:44 ` [PATCH 00/10] [RISCV] Fix/improve the RISCV backend Palmer Dabbelt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1660860233-11175-9-git-send-email-apinski@marvell.com \
    --to=apinski@marvell.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).