diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 95a314f..04832cf 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -5483,7 +5483,16 @@ must_be_base_p (rtx x)
 static bool
 must_be_index_p (rtx x)
 {
-  return GET_CODE (x) == MULT || GET_CODE (x) == ASHIFT;
+  rtx addr = x;
+  if (GET_CODE (addr) == SIGN_EXTRACT)
+    addr = *strip_address_mutations (&XEXP (addr, 0));
+
+  return (GET_CODE (x) == MULT
+          || GET_CODE (x) == ASHIFT
+          || GET_CODE (x) == ASHIFTRT
+          || GET_CODE (x) == LSHIFTRT
+          || GET_CODE (x) == ROTATE
+          || GET_CODE (x) == ROTATERT);
 }
 
 /* Set the segment part of address INFO to LOC, given that INNER is the
@@ -5505,6 +5514,9 @@ set_address_segment (struct address_info *info, rtx *loc, rtx *inner)
 static void
 set_address_base (struct address_info *info, rtx *loc, rtx *inner)
 {
+  if (GET_CODE (*inner) == SIGN_EXTRACT)
+    inner = strip_address_mutations (&XEXP (*inner, 0));
+
   if (GET_CODE (*inner) == LO_SUM)
     inner = strip_address_mutations (&XEXP (*inner, 0));
   gcc_checking_assert (REG_P (*inner)
@@ -5522,7 +5534,15 @@ set_address_base (struct address_info *info, rtx *loc, rtx *inner)
 static void
 set_address_index (struct address_info *info, rtx *loc, rtx *inner)
 {
-  if ((GET_CODE (*inner) == MULT || GET_CODE (*inner) == ASHIFT)
+  if (GET_CODE (*inner) == SIGN_EXTRACT)
+    inner = strip_address_mutations (&XEXP (*inner, 0));
+
+  if ((GET_CODE (*inner) == MULT
+       || GET_CODE (*inner) == ASHIFT
+       || GET_CODE (*inner) == ASHIFTRT
+       || GET_CODE (*inner) == LSHIFTRT
+       || GET_CODE (*inner) == ROTATE
+       || GET_CODE (*inner) == ROTATERT)
       && CONSTANT_P (XEXP (*inner, 1)))
     inner = strip_address_mutations (&XEXP (*inner, 0));
   gcc_checking_assert (REG_P (*inner)
