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]

Re: simplify_shift_const() breaks sign extraction of wider sign-extension




  In message <or1yunl9w5.fsf@guarana.lsd.ic.unicamp.br>you write:
  > --=-=-=
  > 
  > When combine attempts to combine:
  > 
  > (set (reg:DI B) (sign_extend:DI (reg:HI A)))
  > (set (reg:SI C) (lshiftrt:SI (subreg:SI (reg:DI B))
  >                              (const_int 31)))
  > 
  > It eventually asks simplify_shift_const() to simplify the LSHIFTRT.
  > It ends up transforming varop in:
  > 
  > (ashiftrt:DI (ashift:DI (subreg:DI (reg:HI A) 0) (const_int 48))
  >              (const_int 48))
  > 
  > And it discards the ashiftrt because the enclosing lshiftrt is
  > extracting just the sign bit.  However, it shouldn't do this if the
  > mode of varop is wider than that of the result, because then the
  > enclosed operation may not have the appropriate sign bit.  In this
  > case, the whole thing would be optimized to zero, because the left
  > shift would leave all the lower 32-bits as zero (because reg C would
  > eventually be truncated to HImode).
  > 
  > This patch fixes this problem.  Ok to install?
  > 
  > 
  > --=-=-=
  > Content-Type: text/x-patch
  > Content-Disposition: inline; filename=combine-sign-extract.patch
  > 
  > Index: gcc/ChangeLog
  > from  Alexandre Oliva  <aoliva@redhat.com>
  > 
  > 	* combine.c (simplify_shift_const): Even if we're sign-extracting,
  > 	don't discard an ASHIFTRT if we're shifting in a wider mode.
This is OK if you add a comment to the code indicating why this transformation
is not valid when RESULT_MODE is smaller than VAROP.

jeff


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