This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[AARCH64][PATCH] Fix legitimate address checking for TImode and TFmode


This patch fixes the behaviour of legitimate address checking for TImode and TFmode values.

The current implementation does not correctly distinguish between the address modes available for ldp/stp X,X versus ldr/str Q.

/Marcus

ChangeLog:

	* config/aarch64/aarch64.c
	(aarch64_regno_ok_for_index_p): Handle NULL reg_renumber.
	(aarch64_regno_ok_for_base_p): Likewise.
	(offset_7bit_signed_scaled_p): New.
	(offset_9bit_signed_unscaled_p): New.
	(offset_12bit_unsigned_scaled_p): New.
	(aarch64_classify_address): Replace pair_p with allow_reg_index_p.
	Conservative test for valid TImode and TFmode addresses.  Use
	offset_7bit_signed_scaled_p offset_9bit_signed_unscaled_p and
	offset_12bit_unsigned_scaled_p.  Remove explicit TImode and TFmode
	tests.
	* config/aarch64/aarch64.md (movti_aarch64): Replace 'm' with 'Ump'.
	(movtf_aarch64): Replace 'm' with 'Ump', replace 'Utf' with 'm'.
	* config/aarch64/constraints.md (Utf): Remove.
	(Ump) Pass strict.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 34d04755900a75376c0afe5b9b4b8b3cd1ac84e2..b985d63c4fd591c7ae17d519a7b858c0264edec7 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -2441,6 +2441,10 @@ aarch64_regno_ok_for_index_p (int regno,
     {
       if (!strict_p)
 	return true;
+
+      if (!reg_renumber)
+	return false;
+
       regno = reg_renumber[regno];
     }
   return GP_REGNUM_P (regno);
@@ -2456,6 +2460,10 @@ aarch64_regno_ok_for_base_p (int regno,
     {
       if (!strict_p)
 	return true;
+
+      if (!reg_renumber)
+	return false;
+
       regno = reg_renumber[regno];
     }
 
@@ -2639,6 +2647,29 @@ aarch64_classify_index (struct aarch64_a
   return false;
 }
 
+static inline bool
+offset_7bit_signed_scaled_p (enum machine_mode mode, HOST_WIDE_INT offset)
+{
+  return (offset >= -64 * GET_MODE_SIZE (mode)
+	  && offset < 64 * GET_MODE_SIZE (mode)
+	  && offset % GET_MODE_SIZE (mode) == 0);
+}
+
+static inline bool
+offset_9bit_signed_unscaled_p (enum machine_mode mode ATTRIBUTE_UNUSED,
+			       HOST_WIDE_INT offset)
+{
+  return offset >= -256 && offset < 256;
+}
+
+static inline bool
+offset_12bit_unsigned_scaled_p (enum machine_mode mode, HOST_WIDE_INT offset)
+{
+  return (offset >= 0
+	  && offset < 4096 * GET_MODE_SIZE (mode)
+	  && offset % GET_MODE_SIZE (mode) == 0);
+}
+
 /* Return true if X is a valid address for machine mode MODE.  If it is,
    fill in INFO appropriately.  STRICT_P is true if REG_OK_STRICT is in
    effect.  OUTER_CODE is PARALLEL for a load/store pair.  */
@@ -2650,7 +2681,8 @@ aarch64_classify_address (struct aarch64
 {
   enum rtx_code code = GET_CODE (x);
   rtx op0, op1;
-  bool pair_p = (outer_code == PARALLEL || mode == TImode);
+  bool allow_reg_index_p =
+    outer_code != PARALLEL && GET_MODE_SIZE(mode) != 16;
 
   /* Don't support anything other than POST_INC or REG addressing for
      AdvSIMD.  */
@@ -2679,25 +2711,27 @@ aarch64_classify_address (struct aarch64
 	  info->type = ADDRESS_REG_IMM;
 	  info->base = op0;
 	  info->offset = op1;
+
+	  /* TImode and TFmode values are allowed in both pairs of X
+	     registers and individual Q registers.  The available
+	     address modes are:
+	     X,X: 7-bit signed scaled offset
+	     Q:   9-bit signed offset
+	     We conservatively require an offset representable in either mode.
+	   */
+	  if (mode == TImode || mode == TFmode)
+	    return (offset_7bit_signed_scaled_p (mode, offset)
+		    && offset_9bit_signed_unscaled_p (mode, offset));
+
 	  if (outer_code == PARALLEL)
-	    /* load/store pair: 7-bit signed, scaled offset.  */
 	    return ((GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8)
-		    && offset >= -64 * GET_MODE_SIZE (mode)
-		    && offset < 64 * GET_MODE_SIZE (mode)
-		    && offset % GET_MODE_SIZE (mode) == 0);
-	  else if (mode == TImode)
-	    /* load/store pair of dwords: 7-bit signed, scaled offset.  */
-	    return offset >= -512 && offset < 512 && offset % 8 == 0;
+		    && offset_7bit_signed_scaled_p (mode, offset));
 	  else
-	    /* load/store single: 9-bit signed, unscaled offset.  */
-	    /* load/store single: 12-bit unsigned, scaled offset.  */
-	    return ((offset >= -256 && offset < 256)
-		    || (offset >= 0
-			&& offset < 4096 * GET_MODE_SIZE (mode)
-			&& offset % GET_MODE_SIZE (mode) == 0));
+	    return (offset_9bit_signed_unscaled_p (mode, offset)
+		    || offset_12bit_unsigned_scaled_p (mode, offset));
 	}
 
-      if (!pair_p)
+      if (allow_reg_index_p)
 	{
 	  /* Look for base + (scaled/extended) index register.  */
 	  if (aarch64_base_register_rtx_p (op0, strict_p)
@@ -2737,18 +2771,23 @@ aarch64_classify_address (struct aarch64
 	  HOST_WIDE_INT offset;
 	  info->offset = XEXP (XEXP (x, 1), 1);
 	  offset = INTVAL (info->offset);
+
+	  /* TImode and TFmode values are allowed in both pairs of X
+	     registers and individual Q registers.  The available
+	     address modes are:
+	     X,X: 7-bit signed scaled offset
+	     Q:   9-bit signed offset
+	     We conservatively require an offset representable in either mode.
+	   */
+	  if (mode == TImode || mode == TFmode)
+	    return (offset_7bit_signed_scaled_p (mode, offset)
+		    && offset_9bit_signed_unscaled_p (mode, offset));
+
 	  if (outer_code == PARALLEL)
-	    /* load/store pair: 7-bit signed, scaled offset.  */
 	    return ((GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8)
-		    && offset >= -64 * GET_MODE_SIZE (mode)
-		    && offset < 64 * GET_MODE_SIZE (mode)
-		    && offset % GET_MODE_SIZE (mode) == 0);
-	  else if (mode == TImode)
-	    /* load/store pair of dwords: 7-bit signed, scaled offset.  */
-	    return offset >= -512 && offset < 512 && offset % 8 == 0;
+		    && offset_7bit_signed_scaled_p (mode, offset));
 	  else
-	    /* load/store single: 9-bit signed, unscaled offset.  */
-	    return offset >= -256 && offset < 256;
+	    return offset_9bit_signed_unscaled_p (mode, offset);
 	}
       return false;
 
@@ -2759,10 +2798,10 @@ aarch64_classify_address (struct aarch64
       info->type = ADDRESS_SYMBOLIC;
       if (outer_code != PARALLEL
 	  && (GET_MODE_SIZE (mode) == 4
-	      || GET_MODE_SIZE (mode) == 8
-	      || mode == TFmode))
+	      || GET_MODE_SIZE (mode) == 8))
 	{
 	  rtx sym, addend;
+
 	  split_const (x, &sym, &addend);
 	  return (GET_CODE (sym) == LABEL_REF
 		  || (GET_CODE (sym) == SYMBOL_REF
@@ -2774,7 +2813,7 @@ aarch64_classify_address (struct aarch64
       info->type = ADDRESS_LO_SUM;
       info->base = XEXP (x, 0);
       info->offset = XEXP (x, 1);
-      if (!pair_p
+      if (allow_reg_index_p
 	  && aarch64_base_register_rtx_p (info->base, strict_p))
 	{
 	  rtx sym, offs;
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 456fab743ca301e596d147322266bbb10ed85507..3ce99941ecb4b0c89e02979c14df10c7080c1ff7 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -987,8 +987,10 @@ (define_expand "movti"
 )
 
 (define_insn "*movti_aarch64"
-  [(set (match_operand:TI 0 "nonimmediate_operand"  "=r, *w,r,*w,r,m,m,*w, m")
-	(match_operand:TI 1 "aarch64_movti_operand" " rn,r,*w,*w,m,r,Z, m,*w"))]
+  [(set (match_operand:TI 0
+	 "nonimmediate_operand"  "=r, *w,r ,*w,r  ,Ump,Ump,*w,m")
+	(match_operand:TI 1
+	 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r  ,Z  , m,*w"))]
   "(register_operand (operands[0], TImode)
     || aarch64_reg_or_zero (operands[1], TImode))"
   "@
@@ -1002,7 +1004,7 @@ (define_insn "*movti_aarch64"
    ldr\\t%q0, %1
    str\\t%q1, %0"
   [(set_attr "v8type" "move2,fmovi2f,fmovf2i,*, \
-	               load2,store2,store2,fpsimd_load,fpsimd_store")
+		       load2,store2,store2,fpsimd_load,fpsimd_store")
    (set_attr "simd_type" "*,*,*,simd_move,*,*,*,*,*")
    (set_attr "mode" "DI,DI,DI,TI,DI,DI,DI,TI,TI")
    (set_attr "length" "8,8,8,4,4,4,4,4,4")
@@ -1091,8 +1093,10 @@ (define_expand "movtf"
 )
 
 (define_insn "*movtf_aarch64"
-  [(set (match_operand:TF 0 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Utf")
-	(match_operand:TF 1 "general_operand"      " w,?r,?r,w ,Y,Y ,m,w,Utf,?rY"))]
+  [(set (match_operand:TF 0
+	 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
+	(match_operand:TF 1
+	 "general_operand"      " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
   "TARGET_FLOAT && (register_operand (operands[0], TFmode)
     || register_operand (operands[1], TFmode))"
   "@
diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md
index 47d638400c546051ba1a3db67231f07cf120870f..91eba09f02cc5f61cac18649b55f6f469b418eea 100644
--- a/gcc/config/aarch64/constraints.md
+++ b/gcc/config/aarch64/constraints.md
@@ -121,14 +121,7 @@ (define_memory_constraint "Ump"
   A memory address suitable for a load/store pair operation."
   (and (match_code "mem")
        (match_test "aarch64_legitimate_address_p (GET_MODE (op), XEXP (op, 0),
-						  PARALLEL, 0)")))
-
-(define_memory_constraint "Utf"
-  "@internal
-  A memory address suitable for a load/store pair operation."
-  (and (match_code "mem")
-       (match_test "aarch64_legitimate_address_p (TImode, XEXP (op, 0),
-						  UNKNOWN, 0)")))
+						  PARALLEL, 1)")))
 
 (define_constraint "Dn"
   "@internal

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]