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]

[PATCH, RFT s390x] Bug in truncation simplifcation


I found this bug while working on my previous patch.

If MODE is the mode of the truncation and OP is the operand then in
order to see whether the bits outside of MODE have the same value as
the new sign bit, the number of leading bits we need to check is:

  GET_MODE_BITSIZE (GET_MODE (OP)) - GET_MODE_BITSIZE (MODE) + 1

Instead the code checks GET_MODE_BITSIZE (mode) + 1 bits which happens
to work if the new mode is half the size of the original mode.

Unfortunately, I couldn't sufficiently exercise the new code.  I
bootstrapped and tested on i686-pc-linux-gnu.  However on x86,
TRUNCATEs only occur before an LSHIFTRT and a MULT where this
transformation is disabled specifically.  I tried testing with a
h8300-elf toolchain but the build fails in newlib.  Finally, I built
an s390x-ibm-linux-gnu cc1 and compared the assembly output for
gcc.c-torture/exercise and for GCC preprocessed files.  There is no
change in the output before and after the patch and the code does
trigger a few times.

I am not sure if it is necessary but if yes can someone with access to
s390x-ibm-linux-gnu please test this patch.

Thanks,
Adam

	* simplify-rtx.c (simplify_unary_operation_1) <TRUNCATE>: When
	trying to remove TRUNCATE check if all bits outside the new mode
	are identical to the sign bit.

Index: simplify-rtx.c
===================================================================
--- simplify-rtx.c	(revision 111573)
+++ simplify-rtx.c	(working copy)
@@ -640,7 +640,8 @@ simplify_unary_operation_1 (enum rtx_cod
       if ((TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
 				 GET_MODE_BITSIZE (GET_MODE (op)))
 	   ? (num_sign_bit_copies (op, GET_MODE (op))
-	      >= (unsigned int) (GET_MODE_BITSIZE (mode) + 1))
+	      > (unsigned int) (GET_MODE_BITSIZE (GET_MODE (op))
+				- GET_MODE_BITSIZE (mode)))
 	   : truncated_to_mode (mode, op))
 	  && ! (GET_CODE (op) == LSHIFTRT
 		&& GET_CODE (XEXP (op, 0)) == MULT))


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