diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc
index 13ca8f674b0c..2f1d83fbbc7f 100644
--- a/gcc/config/riscv/thead.cc
+++ b/gcc/config/riscv/thead.cc
@@ -609,31 +609,70 @@ th_memidx_classify_address_index (struct riscv_address_info *info, rtx x,
   if (GET_CODE (x) != PLUS)
     return false;
 
-  rtx reg = XEXP (x, 0);
+  rtx op0 = XEXP (x, 0);
+  rtx op1 = XEXP (x, 1);
   enum riscv_address_type type;
-  rtx offset = XEXP (x, 1);
   int shift;
+  rtx reg = op0;
+  rtx offset = op1;
 
   if (!riscv_valid_base_register_p (reg, mode, strict_p))
-    return false;
+    {
+      reg = op1;
+      offset = op0;
+      if (!riscv_valid_base_register_p (reg, mode, strict_p))
+	return false;
+    }
 
   /* (reg:X) */
-  if (REG_P (offset)
+  if ((REG_P (offset) || SUBREG_P (offset))
       && GET_MODE (offset) == Xmode)
     {
       type = ADDRESS_REG_REG;
       shift = 0;
       offset = offset;
     }
-  /* (zero_extend:DI (reg:SI)) */
-  else if (GET_CODE (offset) == ZERO_EXTEND
+  /* (any_extend:DI (reg:SI)) */
+  else if (TARGET_64BIT
+	   && (GET_CODE (offset) == SIGN_EXTEND
+	       || GET_CODE (offset) == ZERO_EXTEND)
 	   && GET_MODE (offset) == DImode
 	   && GET_MODE (XEXP (offset, 0)) == SImode)
     {
-      type = ADDRESS_REG_UREG;
+      type = (GET_CODE (offset) == SIGN_EXTEND)
+	     ? ADDRESS_REG_REG : ADDRESS_REG_UREG;
       shift = 0;
       offset = XEXP (offset, 0);
     }
+  /* (mult:X (reg:X) (const_int scale)) */
+  else if (GET_CODE (offset) == MULT
+	   && GET_MODE (offset) == Xmode
+	   && REG_P (XEXP (offset, 0))
+	   && GET_MODE (XEXP (offset, 0)) == Xmode
+	   && CONST_INT_P (XEXP (offset, 1))
+	   && pow2p_hwi (INTVAL (XEXP (offset, 1)))
+	   && IN_RANGE (exact_log2 (INTVAL (XEXP (offset, 1))), 1, 3))
+    {
+      type = ADDRESS_REG_REG;
+      shift = exact_log2 (INTVAL (XEXP (offset, 1)));
+      offset = XEXP (offset, 0);
+    }
+  /* (mult:DI (any_extend:DI (reg:SI)) (const_int scale)) */
+  else if (TARGET_64BIT
+	   && GET_CODE (offset) == MULT
+	   && GET_MODE (offset) == DImode
+	   && (GET_CODE (XEXP (offset, 0)) == SIGN_EXTEND
+	       || GET_CODE (XEXP (offset, 0)) == ZERO_EXTEND)
+	   && GET_MODE (XEXP (offset, 0)) == DImode
+	   && REG_P (XEXP (XEXP (offset, 0), 0))
+	   && GET_MODE (XEXP (XEXP (offset, 0), 0)) == SImode
+	   && CONST_INT_P (XEXP (offset, 1)))
+    {
+      type = (GET_CODE (XEXP (offset, 0)) == SIGN_EXTEND)
+	     ? ADDRESS_REG_REG : ADDRESS_REG_UREG;
+      shift = exact_log2 (INTVAL (XEXP (x, 1)));
+      offset = XEXP (XEXP (x, 0), 0);
+    }
   /* (ashift:X (reg:X) (const_int shift)) */
   else if (GET_CODE (offset) == ASHIFT
 	   && GET_MODE (offset) == Xmode
@@ -646,23 +685,46 @@ th_memidx_classify_address_index (struct riscv_address_info *info, rtx x,
       shift = INTVAL (XEXP (offset, 1));
       offset = XEXP (offset, 0);
     }
-  /* (ashift:DI (zero_extend:DI (reg:SI)) (const_int shift)) */
-  else if (GET_CODE (offset) == ASHIFT
+  /* (ashift:DI (any_extend:DI (reg:SI)) (const_int shift)) */
+  else if (TARGET_64BIT
+	   && GET_CODE (offset) == ASHIFT
 	   && GET_MODE (offset) == DImode
-	   && GET_CODE (XEXP (offset, 0)) == ZERO_EXTEND
+	   && (GET_CODE (XEXP (offset, 0)) == SIGN_EXTEND
+	       || GET_CODE (XEXP (offset, 0)) == ZERO_EXTEND)
 	   && GET_MODE (XEXP (offset, 0)) == DImode
 	   && GET_MODE (XEXP (XEXP (offset, 0), 0)) == SImode
 	   && CONST_INT_P (XEXP (offset, 1))
 	   && IN_RANGE(INTVAL (XEXP (offset, 1)), 0, 3))
     {
-      type = ADDRESS_REG_UREG;
+      type = (GET_CODE (XEXP (offset, 0)) == SIGN_EXTEND)
+	     ? ADDRESS_REG_REG : ADDRESS_REG_UREG;
       shift = INTVAL (XEXP (offset, 1));
       offset = XEXP (XEXP (offset, 0), 0);
     }
+  /* (and:X (mult:X (reg:X) (const_int scale)) (const_int mask)) */
+  else if (TARGET_64BIT
+	   && GET_CODE (offset) == AND
+	   && GET_MODE (offset) == DImode
+	   && GET_CODE (XEXP (offset, 0)) == MULT
+	   && GET_MODE (XEXP (offset, 0)) == DImode
+	   && REG_P (XEXP (XEXP (offset, 0), 0))
+	   && GET_MODE (XEXP (XEXP (offset, 0), 0)) == DImode
+	   && CONST_INT_P (XEXP (XEXP (offset, 0), 1))
+	   && pow2p_hwi (INTVAL (XEXP (XEXP (offset, 0), 1)))
+	   && IN_RANGE (exact_log2 (INTVAL (XEXP (XEXP (offset, 0), 1))), 1, 3)
+	   && CONST_INT_P (XEXP (offset, 1))
+	   && INTVAL (XEXP (offset, 1))
+	      >> exact_log2 (INTVAL (XEXP (XEXP (offset, 0), 1))) == 0xffffffff)
+    {
+      type = ADDRESS_REG_UREG;
+      shift = exact_log2 (INTVAL (XEXP (XEXP (offset, 0), 1)));
+      offset = XEXP (XEXP (offset, 0), 0);
+    }
   else
     return false;
 
-  if (!strict_p && GET_CODE (offset) == SUBREG)
+  if (!strict_p && SUBREG_P (offset)
+      && GET_MODE (SUBREG_REG (offset)) == SImode)
     offset = SUBREG_REG (offset);
 
   if (!REG_P (offset)
@@ -774,7 +836,7 @@ th_fmemidx_output_index (rtx dest, rtx src, machine_mode mode, bool load)
   rtx x = th_get_move_mem_addr (dest, src, load);
 
   /* Validate x.  */
-  if (!th_memidx_classify_address_index (&info, x, mode, false))
+  if (!th_memidx_classify_address_index (&info, x, mode, reload_completed))
     return NULL;
 
   int index = exact_log2 (GET_MODE_SIZE (mode).to_constant ()) - 2;
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index 93becb2843bd..2a3af76b55c2 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -456,26 +456,6 @@ (define_insn "*th_mempair_load_zero_extendsidi2"
 
 ;; XTheadMemIdx
 
-;; Help reload to add a displacement for the base register.
-;; In the case `zext(*(uN*)(base+(zext(rN)<<1)))` LRA splits
-;; off two new instructions: a) `new_base = base + disp`, and
-;; b) `index = zext(rN)<<1`.  The index calculation has no
-;; corresponding instruction pattern and needs this insn_and_split
-;; to recover.
-
-(define_insn_and_split "*th_memidx_operand"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-     (ashift:DI
-       (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
-       (match_operand 2 "const_int_operand" "n")))]
-  "TARGET_64BIT && TARGET_XTHEADMEMIDX && lra_in_progress"
-  "#"
-  ""
-  [(set (match_dup 0) (zero_extend:DI (match_dup 1)))
-   (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
-  ""
-  [(set_attr "type" "bitmanip")])
-
 (define_insn "*th_memidx_zero_extendqi<SUPERQI:mode>2"
   [(set (match_operand:SUPERQI 0 "register_operand" "=r,r,r,r,r,r")
 	(zero_extend:SUPERQI
@@ -654,401 +634,4 @@ (define_insn "*th_memidx_bb_extendqi<SUPERQI:mode>2"
   [(set_attr "move_type" "shift_shift,load,load,load,load,load")
    (set_attr "mode" "<SUPERQI:MODE>")])
 
-;; All modes that are supported by XTheadMemIdx
-(define_mode_iterator TH_M_ANYI [(QI "TARGET_XTHEADMEMIDX")
-                                 (HI "TARGET_XTHEADMEMIDX")
-                                 (SI "TARGET_XTHEADMEMIDX")
-                                 (DI "TARGET_64BIT && TARGET_XTHEADMEMIDX")])
-
-;; All modes that are supported by XTheadFMemIdx
-(define_mode_iterator TH_M_ANYF [(SF "TARGET_HARD_FLOAT && TARGET_XTHEADFMEMIDX")
-                                 (DF "TARGET_DOUBLE_FLOAT && TARGET_XTHEADFMEMIDX")])
-
-;; All non-extension modes that are supported by XTheadMemIdx
-(define_mode_iterator TH_M_NOEXTI [(SI "!TARGET_64BIT && TARGET_XTHEADMEMIDX")
-                                   (DI "TARGET_64BIT && TARGET_XTHEADMEMIDX")])
-
-;; All non-extension modes that are supported by XTheadFMemIdx
-(define_mode_iterator TH_M_NOEXTF [(SF "TARGET_HARD_FLOAT && TARGET_XTHEADFMEMIDX")
-                                   (DF "TARGET_DOUBLE_FLOAT && TARGET_XTHEADFMEMIDX")])
-
-;; XTheadMemIdx optimizations
-;; All optimizations attempt to improve the operand utilization of
-;; XTheadMemIdx instructions, where one sign or zero extended
-;; register-index-operand can be shifted left by a 2-bit immediate.
-;;
-;; The basic idea is the following optimization:
-;; (set (reg 0) (op (reg 1) (imm 2)))
-;; (set (reg 3) (mem (plus (reg 0) (reg 4)))
-;; ==>
-;; (set (reg 3) (mem (plus (reg 4) (op2 (reg 1) (imm 2))))
-;; This optimization only valid if (reg 0) has no further uses.
-;;
-;; The three-instruction case is as follows:
-;; (set (reg 0) (op1 (reg 1) (imm 2)))
-;; (set (reg 3) (op2 (reg 0) (imm 4)))
-;; (set (reg 5) (mem (plus (reg 3) (reg 6)))
-;; ==>
-;; (set (reg 5) (mem (plus (reg 6) (op2 (reg 1) (imm 2/4)))))
-;; This optimization is only valid if (reg 0) and (reg 3) have no further uses.
-;;
-;; The optimization cases are:
-;; I) fold 2-bit ashift of register offset into mem-plus RTX
-;; US) fold 32-bit zero-extended (shift) offset into mem-plus
-;; UZ) fold 32-bit zero-extended (zext) offset into mem-plus
-;;
-;; The first optimization case is targeting the th.lr<MODE> instructions.
-;; The other optimization cases are targeting the th.lur<MODE> instructions
-;; and have to consider two forms of zero-extensions:
-;; - ashift-32 + lshiftrt-{29..32} if there are no zero-extension instructions.
-;;   Left-shift amounts of 29..31 indicate a left-shifted zero-extended value.
-;; - zero-extend32 if there are zero-extension instructions (XTheadBb or Zbb).
-;;
-;; We always have three peephole passes per optimization case:
-;; a) no-extended (X) word-load
-;; b) any-extend (SUBX) word-load
-;; c) store
-;;
-;; Note, that SHIFTs will be converted to MULTs during combine.
-
-(define_insn_and_split "*th_memidx_I_a"
-  [(set (match_operand:TH_M_NOEXTI 0 "register_operand" "=r")
-        (mem:TH_M_NOEXTI (plus:X
-          (mult:X (match_operand:X 1 "register_operand" "r")
-                  (match_operand:QI 2 "immediate_operand" "i"))
-          (match_operand:X 3 "register_operand" "r"))))]
-  "TARGET_XTHEADMEMIDX
-   && CONST_INT_P (operands[2])
-   && pow2p_hwi (INTVAL (operands[2]))
-   && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)"
-  "#"
-  "&& 1"
-  [(set (match_dup 0)
-        (mem:TH_M_NOEXTI (plus:X
-          (match_dup 3)
-          (ashift:X (match_dup 1) (match_dup 2)))))]
-  { operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
-  }
-)
-
-(define_insn_and_split "*th_memidx_I_b"
-  [(set (match_operand:X 0 "register_operand" "=r")
-        (any_extend:X (mem:SUBX (plus:X
-          (mult:X (match_operand:X 1 "register_operand" "r")
-                  (match_operand:QI 2 "immediate_operand" "i"))
-          (match_operand:X 3 "register_operand" "r")))))]
-  "TARGET_XTHEADMEMIDX
-   && CONST_INT_P (operands[2])
-   && pow2p_hwi (INTVAL (operands[2]))
-   && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)"
-  "#"
-  "&& 1"
-  [(set (match_dup 0)
-        (any_extend:X (mem:SUBX (plus:X
-          (match_dup 3)
-          (ashift:X (match_dup 1) (match_dup 2))))))]
-  { operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
-  }
-)
-
-(define_insn_and_split "*th_memidx_I_c"
-  [(set (mem:TH_M_ANYI (plus:X
-          (mult:X (match_operand:X 1 "register_operand" "r")
-                  (match_operand:QI 2 "immediate_operand" "i"))
-          (match_operand:X 3 "register_operand" "r")))
-        (match_operand:TH_M_ANYI 0 "register_operand" "r"))]
-  "TARGET_XTHEADMEMIDX
-   && CONST_INT_P (operands[2])
-   && pow2p_hwi (INTVAL (operands[2]))
-   && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)"
-  "#"
-  "&& 1"
-  [(set (mem:TH_M_ANYI (plus:X
-          (match_dup 3)
-          (ashift:X (match_dup 1) (match_dup 2))))
-        (match_dup 0))]
-  { operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
-  }
-)
-
-(define_insn_and_split "*th_memidx_US_a"
-  [(set (match_operand:TH_M_NOEXTI 0 "register_operand" "=r")
-        (mem:TH_M_NOEXTI (plus:DI
-          (and:DI
-            (mult:DI (match_operand:DI 1 "register_operand" "r")
-                     (match_operand:QI 2 "immediate_operand" "i"))
-            (match_operand:DI 3 "immediate_operand" "i"))
-          (match_operand:DI 4 "register_operand" "r"))))]
-  "TARGET_64BIT && TARGET_XTHEADMEMIDX
-   && CONST_INT_P (operands[2])
-   && pow2p_hwi (INTVAL (operands[2]))
-   && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)
-   && CONST_INT_P (operands[3])
-   && (INTVAL (operands[3]) >> exact_log2 (INTVAL (operands[2]))) == 0xffffffff"
-  "#"
-  "&& 1"
-  [(set (match_dup 0)
-        (mem:TH_M_NOEXTI (plus:DI
-          (match_dup 4)
-          (ashift:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))))]
-  { operands[1] = gen_lowpart (SImode, operands[1]);
-    operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
-  }
-)
-
-(define_insn_and_split "*th_memidx_US_b"
-  [(set (match_operand:X 0 "register_operand" "=r")
-        (any_extend:X (mem:SUBX (plus:DI
-          (and:DI
-            (mult:DI (match_operand:DI 1 "register_operand" "r")
-                     (match_operand:QI 2 "immediate_operand" "i"))
-            (match_operand:DI 3 "immediate_operand" "i"))
-          (match_operand:DI 4 "register_operand" "r")))))]
-  "TARGET_64BIT && TARGET_XTHEADMEMIDX
-   && CONST_INT_P (operands[2])
-   && pow2p_hwi (INTVAL (operands[2]))
-   && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)
-   && CONST_INT_P (operands[3])
-   && (INTVAL (operands[3]) >> exact_log2 (INTVAL (operands[2]))) == 0xffffffff"
-  "#"
-  "&& 1"
-  [(set (match_dup 0)
-        (any_extend:X (mem:SUBX (plus:DI
-          (match_dup 4)
-          (ashift:DI (zero_extend:DI (match_dup 1)) (match_dup 2))))))]
-  { operands[1] = gen_lowpart (SImode, operands[1]);
-    operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
-  }
-)
-
-(define_insn_and_split "*th_memidx_US_c"
-  [(set (mem:TH_M_ANYI (plus:DI
-          (and:DI
-            (mult:DI (match_operand:DI 1 "register_operand" "r")
-                     (match_operand:QI 2 "immediate_operand" "i"))
-            (match_operand:DI 3 "immediate_operand" "i"))
-          (match_operand:DI 4 "register_operand" "r")))
-        (match_operand:TH_M_ANYI 0 "register_operand" "r"))]
-  "TARGET_64BIT && TARGET_XTHEADMEMIDX
-   && CONST_INT_P (operands[2])
-   && pow2p_hwi (INTVAL (operands[2]))
-   && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)
-   && CONST_INT_P (operands[3])
-   && (INTVAL (operands[3]) >> exact_log2 (INTVAL (operands[2]))) == 0xffffffff"
-  "#"
-  "&& 1"
-  [(set (mem:TH_M_ANYI (plus:DI
-          (match_dup 4)
-          (ashift:DI (zero_extend:DI (match_dup 1)) (match_dup 2))))
-        (match_dup 0))]
-  { operands[1] = gen_lowpart (SImode, operands[1]);
-    operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
-  }
-)
-
-(define_insn_and_split "*th_memidx_UZ_a"
-  [(set (match_operand:TH_M_NOEXTI 0 "register_operand" "=r")
-        (mem:TH_M_NOEXTI (plus:DI
-          (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
-          (match_operand:DI 2 "register_operand" "r"))))]
-  "TARGET_64BIT && TARGET_XTHEADMEMIDX"
-  "#"
-  "&& 1"
-  [(set (match_dup 0)
-        (mem:TH_M_NOEXTI (plus:DI
-          (match_dup 2)
-          (zero_extend:DI (match_dup 1)))))]
-)
-
-(define_insn_and_split "*th_memidx_UZ_b"
-  [(set (match_operand:X 0 "register_operand" "=r")
-        (any_extend:X (mem:SUBX (plus:DI
-          (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
-          (match_operand:DI 2 "register_operand" "r")))))]
-  "TARGET_64BIT && TARGET_XTHEADMEMIDX"
-  "#"
-  "&& 1"
-  [(set (match_dup 0)
-        (any_extend:X (mem:SUBX (plus:DI
-          (match_dup 2)
-          (zero_extend:DI (match_dup 1))))))]
-)
-
-(define_insn_and_split "*th_memidx_UZ_c"
-  [(set (mem:TH_M_ANYI (plus:DI
-          (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
-          (match_operand:DI 2 "register_operand" "r")))
-        (match_operand:TH_M_ANYI 0 "register_operand" "r"))]
-  "TARGET_64BIT && TARGET_XTHEADMEMIDX"
-  "#"
-  "&& 1"
-  [(set (mem:TH_M_ANYI (plus:DI
-          (match_dup 2)
-          (zero_extend:DI (match_dup 1))))
-        (match_dup 0))]
-)
-
-;; XTheadFMemIdx
-;; Note, that we might get GP registers in FP-mode (reg:DF a2)
-;; which cannot be handled by the XTheadFMemIdx instructions.
-;; This might even happen after register allocation.
-;; We could implement splitters that undo the combiner results
-;; if "after_reload && !HARDFP_REG_P (operands[0])", but this
-;; raises even more questions (e.g. split into what?).
-;; So let's solve this by simply requiring XTheadMemIdx
-;; which provides the necessary instructions to cover this case.
-
-(define_insn "*th_fmemidx_movsf_hardfloat"
-  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,th_m_mir,f,th_m_miu")
-	(match_operand:SF 1 "move_operand"         " th_m_mir,f,th_m_miu,f"))]
-  "TARGET_HARD_FLOAT && TARGET_XTHEADFMEMIDX && TARGET_XTHEADMEMIDX
-   && (register_operand (operands[0], SFmode)
-       || reg_or_0_operand (operands[1], SFmode))"
-  { return riscv_output_move (operands[0], operands[1]); }
-  [(set_attr "move_type" "fpload,fpstore,fpload,fpstore")
-   (set_attr "mode" "SF")])
-
-(define_insn "*th_fmemidx_movdf_hardfloat_rv64"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,th_m_mir,f,th_m_miu")
-	(match_operand:DF 1 "move_operand"         " th_m_mir,f,th_m_miu,f"))]
-  "TARGET_64BIT && TARGET_DOUBLE_FLOAT && TARGET_XTHEADFMEMIDX
-   && TARGET_XTHEADMEMIDX
-   && (register_operand (operands[0], DFmode)
-       || reg_or_0_operand (operands[1], DFmode))"
-  { return riscv_output_move (operands[0], operands[1]); }
-  [(set_attr "move_type" "fpload,fpstore,fpload,fpstore")
-   (set_attr "mode" "DF")])
-
-;; XTheadFMemIdx optimizations
-;; Similar like XTheadMemIdx optimizations, but less cases.
-
-(define_insn_and_split "*th_fmemidx_I_a"
-  [(set (match_operand:TH_M_NOEXTF 0 "register_operand" "=f")
-        (mem:TH_M_NOEXTF (plus:X
-          (mult:X (match_operand:X 1 "register_operand" "r")
-                  (match_operand:QI 2 "immediate_operand" "i"))
-          (match_operand:X 3 "register_operand" "r"))))]
-  "TARGET_XTHEADMEMIDX && TARGET_XTHEADFMEMIDX
-   && CONST_INT_P (operands[2])
-   && pow2p_hwi (INTVAL (operands[2]))
-   && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)"
-  "#"
-  "&& reload_completed"
-  [(set (match_dup 0)
-        (mem:TH_M_NOEXTF (plus:X
-          (match_dup 3)
-          (ashift:X (match_dup 1) (match_dup 2)))))]
-  { operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
-  }
-  [(set_attr "move_type" "fpload")
-   (set_attr "mode" "<UNITMODE>")
-   (set_attr "type" "fmove")
-   (set (attr "length") (const_int 16))])
-
-(define_insn_and_split "*th_fmemidx_I_c"
-  [(set (mem:TH_M_ANYF (plus:X
-          (mult:X (match_operand:X 1 "register_operand" "r")
-                  (match_operand:QI 2 "immediate_operand" "i"))
-          (match_operand:X 3 "register_operand" "r")))
-        (match_operand:TH_M_ANYF 0 "register_operand" "f"))]
-  "TARGET_XTHEADMEMIDX && TARGET_XTHEADFMEMIDX
-   && CONST_INT_P (operands[2])
-   && pow2p_hwi (INTVAL (operands[2]))
-   && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)"
-  "#"
-  "&& 1"
-  [(set (mem:TH_M_ANYF (plus:X
-          (match_dup 3)
-          (ashift:X (match_dup 1) (match_dup 2))))
-        (match_dup 0))]
-  { operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
-  }
-)
-
-(define_insn_and_split "*th_fmemidx_US_a"
-  [(set (match_operand:TH_M_NOEXTF 0 "register_operand" "=f")
-        (mem:TH_M_NOEXTF (plus:DI
-          (and:DI
-            (mult:DI (match_operand:DI 1 "register_operand" "r")
-                     (match_operand:QI 2 "immediate_operand" "i"))
-            (match_operand:DI 3 "immediate_operand" "i"))
-          (match_operand:DI 4 "register_operand" "r"))))]
-  "TARGET_64BIT && TARGET_XTHEADMEMIDX && TARGET_XTHEADFMEMIDX
-   && CONST_INT_P (operands[2])
-   && pow2p_hwi (INTVAL (operands[2]))
-   && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)
-   && CONST_INT_P (operands[3])
-   && (INTVAL (operands[3]) >> exact_log2 (INTVAL (operands[2]))) == 0xffffffff"
-  "#"
-  "&& reload_completed"
-  [(set (match_dup 0)
-        (mem:TH_M_NOEXTF (plus:DI
-          (match_dup 4)
-          (ashift:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))))]
-  { operands[1] = gen_lowpart (SImode, operands[1]);
-    operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
-  }
-  [(set_attr "move_type" "fpload")
-   (set_attr "mode" "<UNITMODE>")
-   (set_attr "type" "fmove")
-   (set (attr "length") (const_int 16))])
-
-(define_insn_and_split "*th_fmemidx_US_c"
-  [(set (mem:TH_M_ANYF (plus:DI
-          (and:DI
-            (mult:DI (match_operand:DI 1 "register_operand" "r")
-                     (match_operand:QI 2 "immediate_operand" "i"))
-            (match_operand:DI 3 "immediate_operand" "i"))
-          (match_operand:DI 4 "register_operand" "r")))
-        (match_operand:TH_M_ANYF 0 "register_operand" "f"))]
-  "TARGET_64BIT && TARGET_XTHEADMEMIDX && TARGET_XTHEADFMEMIDX
-   && CONST_INT_P (operands[2])
-   && pow2p_hwi (INTVAL (operands[2]))
-   && IN_RANGE (exact_log2 (INTVAL (operands[2])), 1, 3)
-   && CONST_INT_P (operands[3])
-   && (INTVAL (operands[3]) >> exact_log2 (INTVAL (operands[2]))) == 0xffffffff"
-  "#"
-  "&& 1"
-  [(set (mem:TH_M_ANYF (plus:DI
-          (match_dup 4)
-          (ashift:DI (zero_extend:DI (match_dup 1)) (match_dup 2))))
-        (match_dup 0))]
-  { operands[1] = gen_lowpart (SImode, operands[1]);
-    operands[2] = GEN_INT (exact_log2 (INTVAL (operands [2])));
-  }
-)
-
-(define_insn_and_split "*th_fmemidx_UZ_a"
-  [(set (match_operand:TH_M_NOEXTF 0 "register_operand" "=f")
-        (mem:TH_M_NOEXTF (plus:DI
-          (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
-          (match_operand:DI 2 "register_operand" "r"))))]
-  "TARGET_64BIT && TARGET_XTHEADMEMIDX && TARGET_XTHEADFMEMIDX
-   && (!HARD_REGISTER_NUM_P (REGNO (operands[0])) || HARDFP_REG_P (REGNO (operands[0])))"
-  "#"
-  "&& reload_completed"
-  [(set (match_dup 0)
-        (mem:TH_M_NOEXTF (plus:DI
-          (match_dup 2)
-          (zero_extend:DI (match_dup 1)))))]
-  ""
-  [(set_attr "move_type" "fpload")
-   (set_attr "mode" "<UNITMODE>")
-   (set_attr "type" "fmove")
-   (set (attr "length") (const_int 16))])
-
-(define_insn_and_split "*th_fmemidx_UZ_c"
-  [(set (mem:TH_M_ANYF (plus:DI
-          (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
-          (match_operand:DI 2 "register_operand" "r")))
-        (match_operand:TH_M_ANYF 0 "register_operand" "f"))]
-  "TARGET_64BIT && TARGET_XTHEADMEMIDX && TARGET_XTHEADFMEMIDX"
-  "#"
-  "&& 1"
-  [(set (mem:TH_M_ANYF (plus:DI
-          (match_dup 2)
-          (zero_extend:DI (match_dup 1))))
-        (match_dup 0))]
-)
-
 (include "thead-peephole.md")
diff --git a/gcc/testsuite/gcc.target/riscv/pr116131.c b/gcc/testsuite/gcc.target/riscv/pr116131.c
new file mode 100644
index 000000000000..4d644c37cde7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr116131.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-flto" "-O0" "-Og" "-Os" "-Oz" } } */
+/* { dg-options "-march=rv64gc_xtheadmemidx" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_xtheadmemidx" { target { rv32 } } } */
+
+volatile long long a;
+int b;
+int c[1];
+
+void d()
+{
+  c[a] = b;
+}
+
+/* { dg-final { scan-assembler "th.srw\t" } } */
