[gcc r11-7720] PR target/99314: Fix integer signedness issue for cpymem pattern expansion.

Kito Cheng kito@gcc.gnu.org
Thu Mar 18 16:13:18 GMT 2021


https://gcc.gnu.org/g:d9f0ade001533c9544bf2153b6baa8844ec0bee4

commit r11-7720-gd9f0ade001533c9544bf2153b6baa8844ec0bee4
Author: Sinan Lin <sinan@isrc.iscas.ac.cn>
Date:   Thu Mar 4 18:02:39 2021 +0800

    PR target/99314: Fix integer signedness issue for cpymem pattern expansion.
    
    Third operand of cpymem pattern is unsigned HOST_WIDE_INT, however we
    are interpret that as signed HOST_WIDE_INT, that not a problem in
    most case, but when the value is large than signed HOST_WIDE_INT, it
    might screw up since we have using that value to calculate the buffer
    size.
    
    2021-03-05  Sinan Lin  <sinan@isrc.iscas.ac.cn>
                Kito Cheng  <kito.cheng@sifive.com>
    
    gcc/ChangeLog:
    
            * config/riscv/riscv.c (riscv_block_move_straight): Change type
            to unsigned HOST_WIDE_INT for parameter and local variable with
            HOST_WIDE_INT type.
            (riscv_adjust_block_mem): Ditto.
            (riscv_block_move_loop): Ditto.
            (riscv_expand_block_move): Ditto.

Diff:
---
 gcc/config/riscv/riscv.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index fffd0814eee..96fc0c0a4a0 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -3146,9 +3146,9 @@ riscv_legitimize_call_address (rtx addr)
    Assume that the areas do not overlap.  */
 
 static void
-riscv_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length)
+riscv_block_move_straight (rtx dest, rtx src, unsigned HOST_WIDE_INT length)
 {
-  HOST_WIDE_INT offset, delta;
+  unsigned HOST_WIDE_INT offset, delta;
   unsigned HOST_WIDE_INT bits;
   int i;
   enum machine_mode mode;
@@ -3194,8 +3194,8 @@ riscv_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length)
    register.  Store them in *LOOP_REG and *LOOP_MEM respectively.  */
 
 static void
-riscv_adjust_block_mem (rtx mem, HOST_WIDE_INT length,
-		       rtx *loop_reg, rtx *loop_mem)
+riscv_adjust_block_mem (rtx mem, unsigned HOST_WIDE_INT length,
+			rtx *loop_reg, rtx *loop_mem)
 {
   *loop_reg = copy_addr_to_reg (XEXP (mem, 0));
 
@@ -3210,11 +3210,11 @@ riscv_adjust_block_mem (rtx mem, HOST_WIDE_INT length,
    the memory regions do not overlap.  */
 
 static void
-riscv_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length,
-		      HOST_WIDE_INT bytes_per_iter)
+riscv_block_move_loop (rtx dest, rtx src, unsigned HOST_WIDE_INT length,
+		       unsigned HOST_WIDE_INT bytes_per_iter)
 {
   rtx label, src_reg, dest_reg, final_src, test;
-  HOST_WIDE_INT leftover;
+  unsigned HOST_WIDE_INT leftover;
 
   leftover = length % bytes_per_iter;
   length -= leftover;
@@ -3259,18 +3259,19 @@ riscv_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length,
 bool
 riscv_expand_block_move (rtx dest, rtx src, rtx length)
 {
+  unsigned HOST_WIDE_INT hwi_length = UINTVAL (length);
   if (CONST_INT_P (length))
     {
-      HOST_WIDE_INT factor, align;
+      unsigned HOST_WIDE_INT factor, align;
 
       align = MIN (MIN (MEM_ALIGN (src), MEM_ALIGN (dest)), BITS_PER_WORD);
       factor = BITS_PER_WORD / align;
 
       if (optimize_function_for_size_p (cfun)
-	  && INTVAL (length) * factor * UNITS_PER_WORD > MOVE_RATIO (false))
+	  && hwi_length * factor * UNITS_PER_WORD > MOVE_RATIO (false))
 	return false;
 
-      if (INTVAL (length) <= RISCV_MAX_MOVE_BYTES_STRAIGHT / factor)
+      if (hwi_length <= (RISCV_MAX_MOVE_BYTES_STRAIGHT / factor))
 	{
 	  riscv_block_move_straight (dest, src, INTVAL (length));
 	  return true;
@@ -3280,7 +3281,8 @@ riscv_expand_block_move (rtx dest, rtx src, rtx length)
 	  unsigned min_iter_words
 	    = RISCV_MAX_MOVE_BYTES_PER_LOOP_ITER / UNITS_PER_WORD;
 	  unsigned iter_words = min_iter_words;
-	  HOST_WIDE_INT bytes = INTVAL (length), words = bytes / UNITS_PER_WORD;
+	  unsigned HOST_WIDE_INT bytes = hwi_length;
+	  unsigned HOST_WIDE_INT words = bytes / UNITS_PER_WORD;
 
 	  /* Lengthen the loop body if it shortens the tail.  */
 	  for (unsigned i = min_iter_words; i < min_iter_words * 2 - 1; i++)


More information about the Gcc-cvs mailing list