Compare (length > la_max_inline_memcpy_size) and
(length <= align * LARCH_MAX_MOVE_OPS_STRAIGHT) is signed.

But loongarch_block_move_straight() -> XALLOCAVEC() -> alloca() allocate
space as unsigned value. It may result in segment fault if length less than 0.

gcc/ChangeLog:

        * config/loongarch/loongarch.cc (loongarch_block_move_loop):
        Change length, align to unsigned.
        (loongarch_expand_block_move): Ditto.
---
 gcc/config/loongarch/loongarch.cc | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index 6382db2f189..94b190dad3b 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -5978,8 +5978,8 @@ loongarch_adjust_block_mem (rtx mem, HOST_WIDE_INT 
length, rtx *loop_reg,
    the memory regions do not overlap.  */
 
 static void
-loongarch_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length,
-                          HOST_WIDE_INT align)
+loongarch_block_move_loop (rtx dest, rtx src, unsigned HOST_WIDE_INT length,
+                          unsigned HOST_WIDE_INT align)
 {
   rtx_code_label *label;
   rtx src_reg, dest_reg, final_src, test;
@@ -6035,11 +6035,11 @@ loongarch_expand_block_move (rtx dest, rtx src, rtx 
r_length, rtx r_align)
   if (!CONST_INT_P (r_length))
     return false;
 
-  HOST_WIDE_INT length = INTVAL (r_length);
+  unsigned HOST_WIDE_INT length = UINTVAL (r_length);
   if (length > la_max_inline_memcpy_size)
     return false;
 
-  HOST_WIDE_INT align = INTVAL (r_align);
+  unsigned HOST_WIDE_INT align = UINTVAL (r_align);
 
   if (!TARGET_STRICT_ALIGN || align > LARCH_MAX_MOVE_PER_INSN)
     align = LARCH_MAX_MOVE_PER_INSN;
-- 
2.34.1

Reply via email to