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 COMMITTED: Fix for PR 42099


PR 42099 is about a bug in the handling of division by a constant in a
mode larger than HOST_WIDE_INT.  When the constant fits in
HOST_WIDE_INT, and appears to look like the minimum integer value, gcc
does an invalid shift.  On x86, this leads gcc to conclude that the
value is in fact the minimum integer value.  The fix is simple.

The comment says "This case is not handled correctly below" but that
comment is irrelevant when working in a mode which is larger than
HOST_WIDE_INT.  The rest of the code handles the case correctly.

Bootstrapped on i686-pc-linux-gnu.  Committed to mainline.

Ian


gcc/:

2009-12-29  Ian Lance Taylor  <iant@google.com>

	PR middle-end/42099
	* expmed.c (expand_divmod): Don't shift HOST_WIDE_INT value more
	than HOST_BITS_PER_WIDE_INT.

gcc/testsuite/:

2009-12-29  Ian Lance Taylor  <iant@google.com>

	PR middle-end/42099
	* gcc.c-torture/execute/20091229-1.c: New test.


Index: expmed.c
===================================================================
--- expmed.c	(revision 155510)
+++ expmed.c	(working copy)
@@ -4194,7 +4194,8 @@ expand_divmod (int rem_flag, enum tree_c
 		else if (d == -1)
 		  quotient = expand_unop (compute_mode, neg_optab, op0,
 					  tquotient, 0);
-		else if (abs_d == (unsigned HOST_WIDE_INT) 1 << (size - 1))
+		else if (HOST_BITS_PER_WIDE_INT >= size
+			 && abs_d == (unsigned HOST_WIDE_INT) 1 << (size - 1))
 		  {
 		    /* This case is not handled correctly below.  */
 		    quotient = emit_store_flag (tquotient, EQ, op0, op1,
Index: testsuite/gcc.c-torture/execute/20091229-1.c
===================================================================
--- testsuite/gcc.c-torture/execute/20091229-1.c	(revision 0)
+++ testsuite/gcc.c-torture/execute/20091229-1.c	(revision 0)
@@ -0,0 +1,2 @@
+long long foo(long long v) { return v / -0x080000000LL; }
+void main() { if (foo(0x080000000LL) != -1) abort(); exit (0); }

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