From 4f5712bd2b23b68ba510f4ed99018df2a7c5fb93 Mon Sep 17 00:00:00 2001 From: glisse Date: Fri, 3 Aug 2012 12:21:14 +0000 Subject: gcc/ 2012-08-03 Marc Glisse PR tree-optimization/30318 * double-int.c (mul_double_wide_with_sign): New function. (mul_double_with_sign): Call the new function. * double-int.h (mul_double_wide_with_sign): Declare the new function. * tree-vrp.c (extract_range_from_binary_expr_1) [MULT_EXPR]: Handle integer types that wrap on overflow. (quad_int_cmp): New helper function. (quad_int_pair_sort): Likewise. gcc/testsuite/ 2012-08-03 Marc Glisse PR tree-optimization/30318 * gcc.dg/tree-ssa/vrp77.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@190125 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/double-int.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'gcc/double-int.c') diff --git a/gcc/double-int.c b/gcc/double-int.c index ae63ead903f..1204dc77aad 100644 --- a/gcc/double-int.c +++ b/gcc/double-int.c @@ -134,14 +134,29 @@ mul_double_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1, unsigned HOST_WIDE_INT l2, HOST_WIDE_INT h2, unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv, bool unsigned_p) +{ + unsigned HOST_WIDE_INT toplow; + HOST_WIDE_INT tophigh; + + return mul_double_wide_with_sign (l1, h1, l2, h2, + lv, hv, &toplow, &tophigh, + unsigned_p); +} + +int +mul_double_wide_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1, + unsigned HOST_WIDE_INT l2, HOST_WIDE_INT h2, + unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv, + unsigned HOST_WIDE_INT *lw, HOST_WIDE_INT *hw, + bool unsigned_p) { HOST_WIDE_INT arg1[4]; HOST_WIDE_INT arg2[4]; HOST_WIDE_INT prod[4 * 2]; unsigned HOST_WIDE_INT carry; int i, j, k; - unsigned HOST_WIDE_INT toplow, neglow; - HOST_WIDE_INT tophigh, neghigh; + unsigned HOST_WIDE_INT neglow; + HOST_WIDE_INT neghigh; encode (arg1, l1, h1); encode (arg2, l2, h2); @@ -165,25 +180,25 @@ mul_double_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1, } decode (prod, lv, hv); - decode (prod + 4, &toplow, &tophigh); + decode (prod + 4, lw, hw); /* Unsigned overflow is immediate. */ if (unsigned_p) - return (toplow | tophigh) != 0; + return (*lw | *hw) != 0; /* Check for signed overflow by calculating the signed representation of the top half of the result; it should agree with the low half's sign bit. */ if (h1 < 0) { neg_double (l2, h2, &neglow, &neghigh); - add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh); + add_double (neglow, neghigh, *lw, *hw, lw, hw); } if (h2 < 0) { neg_double (l1, h1, &neglow, &neghigh); - add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh); + add_double (neglow, neghigh, *lw, *hw, lw, hw); } - return (*hv < 0 ? ~(toplow & tophigh) : toplow | tophigh) != 0; + return (*hv < 0 ? ~(*lw & *hw) : *lw | *hw) != 0; } /* Shift the doubleword integer in L1, H1 right by COUNT places -- cgit v1.2.1