arm: fix some issues in mve_vector_mem_operand
authorRichard Earnshaw <rearnsha@arm.com>
Wed, 11 May 2022 10:40:42 +0000 (11:40 +0100)
committerRichard Earnshaw <rearnsha@arm.com>
Fri, 13 May 2022 10:24:11 +0000 (11:24 +0100)
There are a couple of issues with the mve_vector_mem_operand function.
Firstly, SP is permitted as a register provided there is no write-back
operation.  Secondly, there were some cases where 'strict' was not
being applied when checking which registers had been used.

gcc/ChangeLog:

* config/arm/arm.cc (mve_vector_mem_operand): Allow SP_REGNUM
when there is no write-back.  Fix use when strict is true.

gcc/config/arm/arm.cc

index 69a18c2..2afe044 100644 (file)
@@ -13527,7 +13527,7 @@ mve_vector_mem_operand (machine_mode mode, rtx op, bool strict)
       int reg_no = REGNO (op);
       return (((mode == E_V8QImode || mode == E_V4QImode || mode == E_V4HImode)
               ? reg_no <= LAST_LO_REGNUM
-              :(reg_no < LAST_ARM_REGNUM && reg_no != SP_REGNUM))
+              : reg_no < LAST_ARM_REGNUM)
              || (!strict && reg_no >= FIRST_PSEUDO_REGISTER));
     }
   code = GET_CODE (op);
@@ -13536,10 +13536,10 @@ mve_vector_mem_operand (machine_mode mode, rtx op, bool strict)
       || code == PRE_INC || code == POST_DEC)
     {
       reg_no = REGNO (XEXP (op, 0));
-      return ((mode == E_V8QImode || mode == E_V4QImode || mode == E_V4HImode)
-             ? reg_no <= LAST_LO_REGNUM
-             :(reg_no < LAST_ARM_REGNUM && reg_no != SP_REGNUM))
-       || reg_no >= FIRST_PSEUDO_REGISTER;
+      return (((mode == E_V8QImode || mode == E_V4QImode || mode == E_V4HImode)
+              ? reg_no <= LAST_LO_REGNUM
+              :(reg_no < LAST_ARM_REGNUM && reg_no != SP_REGNUM))
+             || (!strict && reg_no >= FIRST_PSEUDO_REGISTER));
     }
   else if (((code == POST_MODIFY || code == PRE_MODIFY)
            && GET_CODE (XEXP (op, 1)) == PLUS
@@ -13580,10 +13580,11 @@ mve_vector_mem_operand (machine_mode mode, rtx op, bool strict)
          default:
            return FALSE;
        }
-      return reg_no >= FIRST_PSEUDO_REGISTER
-       || (MVE_STN_LDW_MODE (mode)
-           ? reg_no <= LAST_LO_REGNUM
-           : (reg_no < LAST_ARM_REGNUM && reg_no != SP_REGNUM));
+      return ((!strict && reg_no >= FIRST_PSEUDO_REGISTER)
+             || (MVE_STN_LDW_MODE (mode)
+                 ? reg_no <= LAST_LO_REGNUM
+                 : (reg_no < LAST_ARM_REGNUM
+                    && (code == PLUS || reg_no != SP_REGNUM))));
     }
   return FALSE;
 }