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]

RFC: PATCH: Add subreg_byte to REG_CANNOT_CHANGE_MODE_P


On Sat, Dec 14, 2013 at 08:32:25AM -0800, H.J. Lu wrote:
> On Wed, Dec 11, 2013 at 7:49 AM, Richard Sandiford
> <rdsandiford@googlemail.com> wrote:
> > "H.J. Lu" <hjl.tools@gmail.com> writes:
> >> On Wed, Dec 11, 2013 at 1:13 AM, Richard Sandiford
> >> <rdsandiford@googlemail.com> wrote:
> >>> Richard Henderson <rth@redhat.com> writes:
> >>>> On 12/10/2013 10:44 AM, Richard Sandiford wrote:
> >>>>> Sorry, I don't understand.  I never said it was invalid.  I said
> >>>>> (subreg:SF (reg:V4SF X) 1) was invalid if (reg:V4SF X) represents
> >>>>> a single register.  On a little-endian target, the offset cannot be
> >>>>> anything other than 0 in that case.
> >>>>>
> >>>>> So the CANNOT_CHANGE_MODE_CLASS code above seems to be checking for
> >>>>> something that is always invalid, regardless of the target.  That kind
> >>>>> of situation should be rejected by target-independent code instead.
> >>>>
> >>>> But, we want to disable the subreg before we know whether or not (reg:V4SF X)
> >>>> will be allocated to a single hard register.  That is something that we can't
> >>>> know in target-independent code before register allocation.
> >>>
> >>> I was thinking that if we've got a class, we've also got things like
> >>> CLASS_MAX_NREGS.  Maybe that doesn't cope with padding properly though.
> >>> But even in the padding cases an offset-based check in C_C_M_C could
> >>> be derived from other information.
> >>>
> >>> subreg_get_info handles padding with:
> >>>
> >>>       nregs_xmode = HARD_REGNO_NREGS_WITH_PADDING (xregno, xmode);
> >>>       if (GET_MODE_INNER (xmode) == VOIDmode)
> >>>         xmode_unit = xmode;
> >>>       else
> >>>         xmode_unit = GET_MODE_INNER (xmode);
> >>>       gcc_assert (HARD_REGNO_NREGS_HAS_PADDING (xregno, xmode_unit));
> >>>       gcc_assert (nregs_xmode
> >>>                   == (GET_MODE_NUNITS (xmode)
> >>>                       * HARD_REGNO_NREGS_WITH_PADDING (xregno, xmode_unit)));
> >>>       gcc_assert (hard_regno_nregs[xregno][xmode]
> >>>                   == (hard_regno_nregs[xregno][xmode_unit]
> >>>                       * GET_MODE_NUNITS (xmode)));
> >>>
> >>>       /* You can only ask for a SUBREG of a value with holes in the middle
> >>>          if you don't cross the holes.  (Such a SUBREG should be done by
> >>>          picking a different register class, or doing it in memory if
> >>>          necessary.)  An example of a value with holes is XCmode on 32-bit
> >>>          x86 with -m128bit-long-double; it's represented in 6 32-bit registers,
> >>>          3 for each part, but in memory it's two 128-bit parts.
> >>>          Padding is assumed to be at the end (not necessarily the 'high part')
> >>>          of each unit.  */
> >>>       if ((offset / GET_MODE_SIZE (xmode_unit) + 1
> >>>            < GET_MODE_NUNITS (xmode))
> >>>           && (offset / GET_MODE_SIZE (xmode_unit)
> >>>               != ((offset + GET_MODE_SIZE (ymode) - 1)
> >>>                   / GET_MODE_SIZE (xmode_unit))))
> >>>         {
> >>>           info->representable_p = false;
> >>>           rknown = true;
> >>>         }
> >>>
> >>> and I wouldn't really want to force targets to individually reproduce
> >>> that kind of logic at the class level.  If the worst comes to the worst
> >>> we could cache the difficult cases.
> >>>
> >>
> >> My case is x86 CANNOT_CHANGE_MODE_CLASS only needs
> >> to know if the subreg byte is zero or not.  It doesn't care about mode
> >> padding.  You are concerned about information passed to
> >> CANNOT_CHANGE_MODE_CLASS is too expensive for target
> >> to process.  It isn't the case for x86.
> >
> > No, I'm concerned that by going this route, we're forcing every target
> > (or at least every target with wider-than-word registers, which is most
> > of the common ones) to implement the same target-independent restriction.
> > This is not an x86-specific issue.
> >
> 
> It may not be x86 specific. However, the decision is made
> based on enum reg_class:
> 
> /* Return true if the registers in CLASS cannot represent the change from
>    modes FROM at offset SUBREG_BYTE to TO.  */
> 
> bool
> ix86_cannot_change_mode_class (enum machine_mode from,
>                                unsigned int subreg_byte,
>                                enum machine_mode to,
>                                enum reg_class regclass)
> {
>   if (from == to)
>     return false;
> 
>   /* x87 registers can't do subreg at all, as all values are reformatted
>      to extended precision.  */
>   if (MAYBE_FLOAT_CLASS_P (regclass))
>     return true;
> 
>   if (MAYBE_SSE_CLASS_P (regclass) || MAYBE_MMX_CLASS_P (regclass))
>     {
>       /* Vector registers do not support QI or HImode loads.  If we don't
>          disallow a change to these modes, reload will assume it's ok to
>          drop the subreg from (subreg:SI (reg:HI 100) 0).  This affects
>          the vec_dupv4hi pattern.  */
>       if (GET_MODE_SIZE (from) < 4)
>         return true;
> 
>       /* Vector registers do not support subreg with nonzero offsets, which
>          are otherwise valid for integer registers.  */
>       if (subreg_byte != 0 && GET_MODE_SIZE (to) < GET_MODE_SIZE (from))
>         return true;
>     }
> 
>   return false;
> }
> 
> We check subreg_byte only for SSE or MMX register classes.
> We could add a target-independent hook or add subreg_byte to
> CANNOT_CHANGE_MODE_CLASS like my patch does.
> 

Here is a patch.  It introduces a new macro, MAYBE_VECTOR_CLASS_P,
to check if a class of registers may be vector registers.  It adds
CANNOT_CHANGE_MODE_CLASS_P and replace usage of
CANNOT_CHANGE_MODE_CLASS with CANNOT_CHANGE_MODE_CLASS_P, which takes
subreg_byte and always returns true for vector class and non-zero
subreg_byte.  I use MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT indicate
unknown subreg_byte.  Tested on Linux/x86-64 without regressions
using -m32, -m64 and -mx32.  Any comments?

Thanks.


H.J.
---
2013-12-14   H.J. Lu  <hongjiu.lu@intel.com>

	* combine.c (subst): Pass subreg byte to REG_CANNOT_CHANGE_MODE_P.
	(simplify_set): Likewise.
	* emit-rtl.c (validate_subreg): Likewise.
	* recog.c (register_operand): Likewise.
	* rtlanal.c (simplify_subreg_regno): Likewise.
	* defaults.h (MAYBE_VECTOR_CLASS_P): New macro.
	* hard-reg-set.h (CANNOT_CHANGE_MODE_CLASS_P): New macro.
	(REG_CANNOT_CHANGE_MODE_P): Add SUBREG_BYTE and pass it to
	CANNOT_CHANGE_MODE_CLASS_P.
	* postreload.c (reload_cse_simplify_set): Pass subreg byte to
	CANNOT_CHANGE_MODE_CLASS_P.
	(reload_cse_simplify_operands): Likewise.
	* reload.c (push_reload): Likewise.
	* regcprop.c (mode_change_ok): Pass unknown subreg byte to
	REG_CANNOT_CHANGE_MODE_P.
	* reginfo.c (record_subregs_of_mode): Likewise.
	* reload1.c (choose_reload_regs): Pass subreg byte to
	REG_CANNOT_CHANGE_MODE_P.
	(inherit_piecemeal_p): Pass unknown subreg byte to
	REG_CANNOT_CHANGE_MODE_P.
	* config/i386/i386.c (ix86_cannot_change_mode_class): Don't
	check mode size.
	* config/i386/i386.h (MAYBE_VECTOR_CLASS_P): New macro.
	* doc/tm.texi.in: Document MAYBE_VECTOR_CLASS_P.
	* doc/tm.texi: Regenerated.

diff --git a/gcc/combine.c b/gcc/combine.c
index dea6c28..8e3b962 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -5084,6 +5084,7 @@ subst (rtx x, rtx from, rtx to, int in_dest, int in_cond, int unique_copy)
 		      && REGNO (to) < FIRST_PSEUDO_REGISTER
 		      && REG_CANNOT_CHANGE_MODE_P (REGNO (to),
 						   GET_MODE (to),
+						   SUBREG_BYTE (x),
 						   GET_MODE (x)))
 		    return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
 #endif
@@ -6450,6 +6451,7 @@ simplify_set (rtx x)
       && ! (REG_P (dest) && REGNO (dest) < FIRST_PSEUDO_REGISTER
 	    && REG_CANNOT_CHANGE_MODE_P (REGNO (dest),
 					 GET_MODE (SUBREG_REG (src)),
+					 SUBREG_BYTE (src),
 					 GET_MODE (src)))
 #endif
       && (REG_P (dest)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index ecf5e0b..8d71ffb 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -35057,13 +35057,6 @@ ix86_cannot_change_mode_class (enum machine_mode from, enum machine_mode to,
 	 the vec_dupv4hi pattern.  */
       if (GET_MODE_SIZE (from) < 4)
 	return true;
-
-      /* Vector registers do not support subreg with nonzero offsets, which
-	 are otherwise valid for integer registers.  Since we can't see
-	 whether we have a nonzero offset from here, prohibit all
-         nonparadoxical subregs changing size.  */
-      if (GET_MODE_SIZE (to) < GET_MODE_SIZE (from))
-	return true;
     }
 
   return false;
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 7efd1e0..d6156d7 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -1522,10 +1522,15 @@ enum reg_class
    ? mode_for_size (32, GET_MODE_CLASS (MODE), 0)		\
    : MODE)
 
-/* Return a class of registers that cannot change FROM mode to TO mode.  */
+/* Return true if the registers in CLASS cannot represent the change
+   from mode FROM to mode TO.  */
 
 #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
   ix86_cannot_change_mode_class (FROM, TO, CLASS)
+
+/* Return true if the register CLASS may be a vector class.  */
+#define MAYBE_VECTOR_CLASS_P(CLASS) \
+  (MAYBE_SSE_CLASS_P (CLASS) || MAYBE_MMX_CLASS_P (CLASS))
 
 /* Stack layout; function entry, exit and calling.  */
 
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 1d12aef..e7fbf27 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -1388,6 +1388,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define SWITCHABLE_TARGET 0
 #endif
 
+#ifndef MAYBE_VECTOR_CLASS_P
+#define MAYBE_VECTOR_CLASS_P(CLASS) false
+#endif
+
 #endif /* GCC_INSN_FLAGS_H  */
 
 #endif  /* ! GCC_DEFAULTS_H */
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 8abb3ef..94757c1 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -2898,6 +2898,20 @@ as below:
 @end smallexample
 @end defmac
 
+@defmac MAYBE_VECTOR_CLASS_P (@var{class})
+A C expression that returns @code{true} for a @var{class} of registers
+which may be vector registers.  Defaults to @code{false}.
+
+For the example, on x86 system, MMX and SSE registers are vector
+registers.  Therefore, @file{i386.h} defines @code{MAYBE_VECTOR_CLASS_P}
+as below:
+
+@smallexample
+#define MAYBE_VECTOR_CLASS_P(CLASS) \
+  (MAYBE_SSE_CLASS_P (CLASS) || MAYBE_MMX_CLASS_P (CLASS))
+@end smallexample
+@end defmac
+
 @deftypefn {Target Hook} bool TARGET_LRA_P (void)
 A target hook which returns true if we use LRA instead of reload pass.  It means that LRA was ported to the target.    The default version of this target hook returns always false.
 @end deftypefn
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index deedb41..6ca29f8 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -2539,6 +2539,20 @@ as below:
 @end smallexample
 @end defmac
 
+@defmac MAYBE_VECTOR_CLASS_P (@var{class})
+A C expression that returns @code{true} for a @var{class} of registers
+which may be vector registers.  Defaults to @code{false}.
+
+For the example, on x86 system, MMX and SSE registers are vector
+registers.  Therefore, @file{i386.h} defines @code{MAYBE_VECTOR_CLASS_P}
+as below:
+
+@smallexample
+#define MAYBE_VECTOR_CLASS_P(CLASS) \
+  (MAYBE_SSE_CLASS_P (CLASS) || MAYBE_MMX_CLASS_P (CLASS))
+@end smallexample
+@end defmac
+
 @hook TARGET_LRA_P
 
 @hook TARGET_REGISTER_PRIORITY
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index d7fa3a5..b8e3dfd 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -748,7 +748,7 @@ validate_subreg (enum machine_mode omode, enum machine_mode imode,
       if ((COMPLEX_MODE_P (imode) || VECTOR_MODE_P (imode))
 	  && GET_MODE_INNER (imode) == omode)
 	;
-      else if (REG_CANNOT_CHANGE_MODE_P (regno, imode, omode))
+      else if (REG_CANNOT_CHANGE_MODE_P (regno, imode, offset, omode))
 	return false;
 #endif
 
diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h
index ad987f9..d488a33 100644
--- a/gcc/hard-reg-set.h
+++ b/gcc/hard-reg-set.h
@@ -716,9 +716,17 @@ extern struct target_hard_regs *this_target_hard_regs;
 
 extern const char * reg_class_names[];
 
-/* Given a hard REGN a FROM mode and a TO mode, return nonzero if
-   REGN cannot change modes between the specified modes.  */
-#define REG_CANNOT_CHANGE_MODE_P(REGN, FROM, TO)                          \
-         CANNOT_CHANGE_MODE_CLASS (FROM, TO, REGNO_REG_CLASS (REGN))
+/* Return true if the registers in CLASS cannot represent the change
+   from mode FROM at offset SUBREG_BYTE to mode TO.  */
+#define CANNOT_CHANGE_MODE_CLASS_P(FROM, SUBREG_BYTE, TO, CLASS) \
+  ((MAYBE_VECTOR_CLASS_P (CLASS)				 \
+    && (SUBREG_BYTE) != 0					 \
+    && GET_MODE_SIZE (TO) < GET_MODE_SIZE (FROM))		 \
+   || CANNOT_CHANGE_MODE_CLASS (FROM, TO, CLASS))
+
+/* Given a hard REGN a FROM mode at SUBREG_BYTE and a TO mode, return
+   true if REGN cannot change modes between the specified modes.  */
+#define REG_CANNOT_CHANGE_MODE_P(REGN, FROM, SUBREG_BYTE, TO) \
+  CANNOT_CHANGE_MODE_CLASS_P (FROM, SUBREG_BYTE, TO, REGNO_REG_CLASS (REGN))
 
 #endif /* ! GCC_HARD_REG_SET_H */
diff --git a/gcc/postreload.c b/gcc/postreload.c
index 37bd9ff..a3629c7 100644
--- a/gcc/postreload.c
+++ b/gcc/postreload.c
@@ -348,9 +348,11 @@ reload_cse_simplify_set (rtx set, rtx insn)
 	  if (GET_MODE_BITSIZE (GET_MODE (SET_DEST (set))) < BITS_PER_WORD
 	      && extend_op != UNKNOWN
 #ifdef CANNOT_CHANGE_MODE_CLASS
-	      && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SET_DEST (set)),
-					    word_mode,
-					    REGNO_REG_CLASS (REGNO (SET_DEST (set))))
+	      && !CANNOT_CHANGE_MODE_CLASS_P (GET_MODE (SET_DEST (set)),
+					      (GET_CODE (SET_DEST (set)) == SUBREG
+					       ? SUBREG_BYTE (SET_DEST (set)) : 0),
+					      word_mode,
+					      REGNO_REG_CLASS (REGNO (SET_DEST (set))))
 #endif
 	      )
 	    {
@@ -458,9 +460,11 @@ reload_cse_simplify_operands (rtx insn, rtx testreg)
 	  /* If the register cannot change mode to word_mode, it follows that
 	     it cannot have been used in word_mode.  */
 	  else if (REG_P (SET_DEST (set))
-		   && CANNOT_CHANGE_MODE_CLASS (GET_MODE (SET_DEST (set)),
-						word_mode,
-						REGNO_REG_CLASS (REGNO (SET_DEST (set)))))
+		   && CANNOT_CHANGE_MODE_CLASS_P (GET_MODE (SET_DEST (set)),
+						  (GET_CODE (SET_DEST (set)) == SUBREG
+						   ? SUBREG_BYTE (SET_DEST (set)) : 0),
+						  word_mode,
+						  REGNO_REG_CLASS (REGNO (SET_DEST (set)))))
 	    ; /* Continue ordinary processing.  */
 #endif
 	  /* If this is a straight load, make the extension explicit.  */
diff --git a/gcc/recog.c b/gcc/recog.c
index dbd9a8a..e30d81c 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -1069,7 +1069,8 @@ register_operand (rtx op, enum machine_mode mode)
 #ifdef CANNOT_CHANGE_MODE_CLASS
       if (REG_P (sub)
 	  && REGNO (sub) < FIRST_PSEUDO_REGISTER
-	  && REG_CANNOT_CHANGE_MODE_P (REGNO (sub), GET_MODE (sub), mode)
+	  && REG_CANNOT_CHANGE_MODE_P (REGNO (sub), GET_MODE (sub),
+				       SUBREG_BYTE (op), mode)
 	  && GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_INT
 	  && GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_FLOAT
 	  /* LRA can generate some invalid SUBREGS just for matched
diff --git a/gcc/regcprop.c b/gcc/regcprop.c
index 3c9ef3d..2be5774 100644
--- a/gcc/regcprop.c
+++ b/gcc/regcprop.c
@@ -389,7 +389,9 @@ mode_change_ok (enum machine_mode orig_mode, enum machine_mode new_mode,
     return false;
 
 #ifdef CANNOT_CHANGE_MODE_CLASS
-  return !REG_CANNOT_CHANGE_MODE_P (regno, orig_mode, new_mode);
+  return !REG_CANNOT_CHANGE_MODE_P (regno, orig_mode,
+				    (MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT),
+				    new_mode);
 #endif
 
   return true;
diff --git a/gcc/reginfo.c b/gcc/reginfo.c
index 46288eb..1f81227 100644
--- a/gcc/reginfo.c
+++ b/gcc/reginfo.c
@@ -1221,8 +1221,9 @@ record_subregs_of_mode (rtx subreg, bitmap subregs_of_mode)
       for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
 	if (!bitmap_bit_p (invalid_mode_changes,
 			   regno * N_REG_CLASSES + rclass)
-	    && CANNOT_CHANGE_MODE_CLASS (PSEUDO_REGNO_MODE (regno),
-					 mode, (enum reg_class) rclass))
+	    && CANNOT_CHANGE_MODE_CLASS_P (PSEUDO_REGNO_MODE (regno),
+					   (MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT),
+					   mode, (enum reg_class) rclass))
 	  bitmap_set_bit (invalid_mode_changes,
 			  regno * N_REG_CLASSES + rclass);
     }
diff --git a/gcc/reload.c b/gcc/reload.c
index 96619f6..58a6143 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -1064,7 +1064,8 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
   if (in != 0 && GET_CODE (in) == SUBREG
       && (subreg_lowpart_p (in) || strict_low)
 #ifdef CANNOT_CHANGE_MODE_CLASS
-      && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (in)), inmode, rclass)
+      && !CANNOT_CHANGE_MODE_CLASS_P (GET_MODE (SUBREG_REG (in)),
+				      SUBREG_BYTE (in), inmode, rclass)
 #endif
       && contains_reg_of_mode[(int) rclass][(int) GET_MODE (SUBREG_REG (in))]
       && (CONSTANT_P (SUBREG_REG (in))
@@ -1113,7 +1114,8 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
 	  || (REG_P (SUBREG_REG (in))
 	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
 	      && REG_CANNOT_CHANGE_MODE_P
-	      (REGNO (SUBREG_REG (in)), GET_MODE (SUBREG_REG (in)), inmode))
+	      (REGNO (SUBREG_REG (in)), GET_MODE (SUBREG_REG (in)),
+	       SUBREG_BYTE (in), inmode))
 #endif
 	  ))
     {
@@ -1174,7 +1176,8 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
   if (out != 0 && GET_CODE (out) == SUBREG
       && (subreg_lowpart_p (out) || strict_low)
 #ifdef CANNOT_CHANGE_MODE_CLASS
-      && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (out)), outmode, rclass)
+      && !CANNOT_CHANGE_MODE_CLASS_P (GET_MODE (SUBREG_REG (out)),
+				      SUBREG_BYTE (out), outmode, rclass)
 #endif
       && contains_reg_of_mode[(int) rclass][(int) GET_MODE (SUBREG_REG (out))]
       && (CONSTANT_P (SUBREG_REG (out))
@@ -1209,6 +1212,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
 	      && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
 	      && REG_CANNOT_CHANGE_MODE_P (REGNO (SUBREG_REG (out)),
 					   GET_MODE (SUBREG_REG (out)),
+					   SUBREG_BYTE (out),
 					   outmode))
 #endif
 	  ))
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 47439ce..10d5a4e 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -6609,7 +6609,7 @@ choose_reload_regs (struct insn_chain *chain)
 		     mode MODE.  */
 		  && !REG_CANNOT_CHANGE_MODE_P (REGNO (reg_last_reload_reg[regno]),
 						GET_MODE (reg_last_reload_reg[regno]),
-						mode)
+						byte, mode)
 #endif
 		  )
 		{
@@ -8080,8 +8080,12 @@ inherit_piecemeal_p (int dest ATTRIBUTE_UNUSED,
 		     enum machine_mode mode ATTRIBUTE_UNUSED)
 {
 #ifdef CANNOT_CHANGE_MODE_CLASS
-  return (!REG_CANNOT_CHANGE_MODE_P (dest, mode, reg_raw_mode[dest])
-	  && !REG_CANNOT_CHANGE_MODE_P (src, mode, reg_raw_mode[src]));
+  return (!REG_CANNOT_CHANGE_MODE_P (dest, mode,
+				     (MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT),
+				     reg_raw_mode[dest])
+	  && !REG_CANNOT_CHANGE_MODE_P (src, mode,
+					(MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT),
+					reg_raw_mode[src]));
 #else
   return true;
 #endif
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 38f9e36..9687110 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -3533,7 +3533,7 @@ simplify_subreg_regno (unsigned int xregno, enum machine_mode xmode,
   /* Give the backend a chance to disallow the mode change.  */
   if (GET_MODE_CLASS (xmode) != MODE_COMPLEX_INT
       && GET_MODE_CLASS (xmode) != MODE_COMPLEX_FLOAT
-      && REG_CANNOT_CHANGE_MODE_P (xregno, xmode, ymode)
+      && REG_CANNOT_CHANGE_MODE_P (xregno, xmode, offset, ymode)
       /* We can use mode change in LRA for some transformations.  */
       && ! lra_in_progress)
     return -1;
-- 
1.8.3.1


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