Hi all,

This patch has been sitting in my SH-LRA conversion stash for a while.  I
can't reproduce the associated issues without the patch anymore on the
latest master version (or haven't tried hard enough).  There have been
several changes and fixes to LRA since the patch was written, so I'm not
sure if these changes are still needed at all?  I'd like to avoid adding
more clutter to the backend if possible.

In essence, what this patch does is rejecting invalid hard-regs for memory
address registers when using LRA.  It seems the behavior of reload and LRA
used to differ in that regard.

Any feedback highly appreciated.  Thanks a lot!

Best regards,
Oleg Endo
From 30b4dea643e7e063f0cc3eb3235ba16dacb1b55e Mon Sep 17 00:00:00 2001
From: Oleg Endo <[email protected]>
Date: Sun, 29 Sep 2024 21:33:29 +0900
Subject: [PATCH] SH: Tighten memory predicates and constraints

In particular, reject invalid hard-regs for memory address registers when using
LRA.  Unfortunately we need to distingquish between old reload and LRA behaviors
for the transitional period.  LRA seems to require stricter predicates and
constraints.

gcc/ChangeLog:

	PR target/55212
	* config/sh/predicates.md (simple_mem_operand):
	Use 'satisfies_constraint_Sra'.
	(post_inc_mem, pre_dec_mem): Use 'satisfies_constraint_Rab'.
	* config/sh/constraints.md (Rab, Rai, Sgb): New constraints.
	(Sua, Sdd, Snd, Ssd, Sbv, Sra, Ara, Add): Use Rab and Rai constraints.
	* config/sh/sync.md (atomic_mem_operand_0, atomic_mem_operand_1): Reject
	GBR addresses when hard-llcs atomic mode is enabled.
---
 gcc/config/sh/constraints.md | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++---------------
 gcc/config/sh/predicates.md  |  7 +++----
 gcc/config/sh/sync.md        |  8 ++++++--
 3 files changed, 59 insertions(+), 21 deletions(-)

diff --git a/gcc/config/sh/constraints.md b/gcc/config/sh/constraints.md
index 51569cd..7b476dc 100644
--- a/gcc/config/sh/constraints.md
+++ b/gcc/config/sh/constraints.md
@@ -44,10 +44,12 @@
 ;; G: Floating point 0
 ;; H: Floating point 1
 ;; Q: pc relative load operand
 ;; Rxx: reserved for exotic register classes.
+;;  Rab: address base register
+;;  Rai: address index register
 ;; Sxx: extra memory constraints
-;;  Sua: unaligned memory address
+;;  Sua: simple or post-inc address (for unaligned load)
 ;;  Sbv: QImode address without displacement
 ;;  Sbw: QImode address with 12 bit displacement
 ;;  Snd: address without displacement
 ;;  Sdd: address with displacement
@@ -259,66 +261,99 @@
 	    (match_test "~ival == 32")
 	    (match_test "~ival == 64")
 	    (match_test "~ival == 128"))))
 
+;; FIXME: LRA and reload behavior differs in memory constraint handling.
+;;        For LRA memory address constraints need to narrow the register type
+;;        restrictions.  It seems  the address RTX validation is done slightly
+;;        differently.  Remove the non-LRA paths eventually.
+(define_constraint "Rab"
+  "@internal address base register constraint"
+  (ior (and (match_test "sh_lra_p ()")
+	    (match_test "MAYBE_BASE_REGISTER_RTX_P (op, false)"))
+       (and (match_test "!sh_lra_p ()")
+	    (match_code "reg"))))
+
+(define_constraint "Rai"
+  "@internal address index register constraint"
+  (ior (and (match_test "sh_lra_p ()")
+	    (match_test "MAYBE_INDEX_REGISTER_RTX_P (op, false)"))
+       (and (match_test "!sh_lra_p ()")
+	    (match_code "reg"))))
+
 (define_memory_constraint "Sua"
-  "@internal"
-  (and (match_test "memory_operand (op, GET_MODE (op))")
-       (match_test "GET_CODE (XEXP (op, 0)) != PLUS")))
+  "A memory reference that allows simple register or post-inc addressing."
+  (and (match_code "mem")
+       (ior (match_test "satisfies_constraint_Rab (XEXP (op, 0))")
+	    (and (match_code "post_inc" "0")
+	    (match_test "satisfies_constraint_Rab (XEXP (XEXP (op, 0), 0))")))))
 
 (define_memory_constraint "Sdd"
   "A memory reference that uses displacement addressing."
   (and (match_code "mem")
        (match_code "plus" "0")
-       (match_code "reg" "00")
+       (match_test "satisfies_constraint_Rab (XEXP (XEXP (op, 0), 0))")
        (match_code "const_int" "01")))
 
 (define_memory_constraint "Snd"
   "A memory reference that excludes displacement addressing."
   (and (match_code "mem")
        (match_test "! satisfies_constraint_Sdd (op)")))
 
 (define_memory_constraint "Sid"
   "A memory reference that uses index addressing."
   (and (match_code "mem")
        (match_code "plus" "0")
-       (match_code "reg" "00")
-       (match_code "reg" "01")))
+       (ior (and (match_test "satisfies_constraint_Rab (XEXP (XEXP (op, 0), 0))")
+		 (match_test "satisfies_constraint_Rai (XEXP (XEXP (op, 0), 1))"))
+	    (and (match_test "satisfies_constraint_Rab (XEXP (XEXP (op, 0), 1))")
+		 (match_test "satisfies_constraint_Rai (XEXP (XEXP (op, 0), 0))")))))
 
 (define_memory_constraint "Ssd"
   "A memory reference that excludes index and displacement addressing."
-  (and (match_code "mem")
-       (match_test "! satisfies_constraint_Sid (op)")
-       (match_test "! satisfies_constraint_Sdd (op)")))
+  (ior (and (match_code "mem")
+	    (match_test "! sh_lra_p ()")
+	    (match_test "! satisfies_constraint_Sid (op)")
+	    (match_test "! satisfies_constraint_Sdd (op)"))
+       (and (match_code "mem")
+	    (match_test "sh_lra_p ()")
+	    (ior (match_test "satisfies_constraint_Rab (XEXP (op, 0))")
+		 (and (ior (match_code "pre_dec" "0") (match_code "post_inc" "0"))
+		 (match_test "satisfies_constraint_Rab (XEXP (XEXP (op, 0), 0))"))))))
 
 (define_memory_constraint "Sbv"
   "A memory reference, as used in SH2A bclr.b, bset.b, etc."
-  (and (match_test "MEM_P (op) && GET_MODE (op) == QImode")
-       (match_test "REG_P (XEXP (op, 0))")))
+  (and (match_code "mem")
+       (match_test "GET_MODE (op) == QImode")
+       (match_test "satisfies_constraint_Rab (XEXP (op, 0))")))
 
 (define_memory_constraint "Sbw"
   "A memory reference, as used in SH2A bclr.b, bset.b, etc."
   (and (match_test "satisfies_constraint_Sdd (op)")
        (match_test "GET_MODE (op) == QImode")
        (match_test "satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1))")))
 
 (define_memory_constraint "Sra"
   "A memory reference that uses simple register addressing."
   (and (match_code "mem")
-       (match_code "reg" "0")))
+       (match_test "satisfies_constraint_Rab (XEXP (op, 0))")))
+
+(define_memory_constraint "Sgb"
+  "A memory renference that uses GBR addressing."
+  (match_test "gbr_address_mem (op, GET_MODE (op))"))
 
 (define_memory_constraint "Ara"
   "A memory reference that uses simple register addressing suitable for
    gusa atomic operations."
   (and (match_code "mem")
-       (match_code "reg" "0")
+       (match_test "satisfies_constraint_Rab (XEXP (op, 0))")
        (match_test "REGNO (XEXP (op, 0)) != SP_REG")))
 
 (define_memory_constraint "Add"
   "A memory reference that uses displacement addressing suitable for
    gusa atomic operations."
   (and (match_code "mem")
        (match_test "GET_MODE (op) == SImode")
        (match_code "plus" "0")
-       (match_code "reg" "00")
+       (match_test "satisfies_constraint_Rab (XEXP (XEXP (op, 0), 0))")
        (match_code "const_int" "01")
        (match_test "REGNO (XEXP (XEXP (op, 0), 0)) != SP_REG")))
diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md
index f705108..6964833 100644
--- a/gcc/config/sh/predicates.md
+++ b/gcc/config/sh/predicates.md
@@ -207,10 +207,9 @@
 
 ;; Returns 1 if OP is a simple register address.
 (define_predicate "simple_mem_operand"
   (and (match_code "mem")
-       (match_code "reg" "0")
-       (match_test "arith_reg_operand (XEXP (op, 0), SImode)")))
+       (match_test "satisfies_constraint_Sra (op)")))
 
 ;; Returns 1 if OP is a valid displacement address.
 (define_predicate "displacement_mem_operand"
   (and (match_code "mem")
@@ -238,15 +237,15 @@
 ;; Returns true if OP is a post-increment addressing mode memory reference.
 (define_predicate "post_inc_mem"
   (and (match_code "mem")
        (match_code "post_inc" "0")
-       (match_code "reg" "00")))
+       (match_test "satisfies_constraint_Rab (XEXP (XEXP (op, 0), 0))")))
 
 ;; Returns true if OP is a pre-decrement addressing mode memory reference.
 (define_predicate "pre_dec_mem"
   (and (match_code "mem")
        (match_code "pre_dec" "0")
-       (match_code "reg" "00")))
+       (match_test "satisfies_constraint_Rab (XEXP (XEXP (op, 0), 0))")))
 
 ;; Returns 1 if the operand can be used in an SH2A movu.{b|w} insn.
 (define_predicate "zero_extend_movu_operand"
   (and (ior (match_operand 0 "displacement_mem_operand")
diff --git a/gcc/config/sh/sync.md b/gcc/config/sh/sync.md
index b0b412b..6025b77 100644
--- a/gcc/config/sh/sync.md
+++ b/gcc/config/sh/sync.md
@@ -216,9 +216,11 @@
        (ior (match_operand 0 "simple_mem_operand")
 	    (and (match_test "mode == SImode")
 		 (and (match_test "!TARGET_ATOMIC_HARD_LLCS")
 		      (match_test "!TARGET_SH4A || TARGET_ATOMIC_STRICT"))
-		 (match_operand 0 "short_displacement_mem_operand")))))
+		 (match_operand 0 "short_displacement_mem_operand")))
+       (ior (match_test "!TARGET_ATOMIC_HARD_LLCS")
+	    (not (match_operand 0 "gbr_address_mem")))))
 
 (define_expand "atomic_compare_and_swap<mode>"
   [(match_operand:SI 0 "arith_reg_dest")		;; bool success output
    (match_operand:QIHISI 1 "arith_reg_dest")		;; oldval output
@@ -714,9 +716,11 @@
 				    || TARGET_ATOMIC_SOFT_IMASK)
 				   && TARGET_SH4A && !TARGET_ATOMIC_STRICT
 				   && mode != SImode"))
 		 (ior (match_operand 0 "short_displacement_mem_operand")
-		      (match_operand 0 "gbr_address_mem"))))))
+		      (match_operand 0 "gbr_address_mem"))))
+       (ior (match_test "!TARGET_ATOMIC_HARD_LLCS")
+            (not (match_operand 0 "gbr_address_mem")))))
 
 (define_expand "atomic_fetch_<fetchop_name><mode>"
   [(set (match_operand:QIHISI 0 "arith_reg_dest")
 	(match_operand:QIHISI 1 "atomic_mem_operand_1"))
--
libgit2 1.9.1

Reply via email to