public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-2188] [RISCV] Fix PR 106586: riscv32 vs ZBS
@ 2022-08-24 19:20 Andrew Pinski
0 siblings, 0 replies; only message in thread
From: Andrew Pinski @ 2022-08-24 19:20 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:2c721ea9473ad7615bb47b66509097bd254bb839
commit r13-2188-g2c721ea9473ad7615bb47b66509097bd254bb839
Author: Andrew Pinski <apinski@marvell.com>
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. */
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-08-24 19:20 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-24 19:20 [gcc r13-2188] [RISCV] Fix PR 106586: riscv32 vs ZBS Andrew Pinski
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).