Hi All,

Previously GCC's no-op detection could would consider something a no-op even 
when the
mode change is not directly possible.  This caused subregs that shouldn't be 
removed
to be treated as a no-op and deleted.

Regtested on armeb-none-eabi and no regressions.
Bootstrapped on arm-none-linux-gnueabihf and no issues.

Ok for trunk? and for backport to GCC 8?

Thanks,
Tamar

gcc/
2018-06-19  Tamar Christina  <tamar.christ...@arm.com>

        PR target/84711
        * rtlanal.c (set_noop_p): Constrain on mode change,
        include hard-reg-set.h

-- 
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index ac3662de3ce0c9fcb58a042138f461c538fc1522..7af516378b38e043849cc2e1326a43837856ae4d 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "recog.h"
 #include "addresses.h"
 #include "rtl-iter.h"
+#include "hard-reg-set.h"
 
 /* Forward declarations */
 static void set_of_1 (rtx, const_rtx, void *);
@@ -1620,8 +1621,9 @@ set_noop_p (const_rtx set)
 	if (INTVAL (XVECEXP (par, 0, i)) != c0 + i)
 	  return 0;
       return
-	simplify_subreg_regno (REGNO (src0), GET_MODE (src0),
-			       offset, GET_MODE (dst)) == (int) REGNO (dst);
+	REG_CAN_CHANGE_MODE_P (REGNO (dst), GET_MODE (src0), GET_MODE (dst))
+	&& simplify_subreg_regno (REGNO (src0), GET_MODE (src0),
+				  offset, GET_MODE (dst)) == (int) REGNO (dst);
     }
 
   return (REG_P (src) && REG_P (dst)

Reply via email to