diff options
author | glisse <glisse@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-08-03 12:21:14 +0000 |
---|---|---|
committer | glisse <glisse@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-08-03 12:21:14 +0000 |
commit | 4f5712bd2b23b68ba510f4ed99018df2a7c5fb93 (patch) | |
tree | 567eda01e87e579ad9caa799953466f4a2dfb161 /gcc/double-int.c | |
parent | bfa091eeca8305aee66359c5333e854ad3f2ddc1 (diff) | |
download | gcc-4f5712bd2b23b68ba510f4ed99018df2a7c5fb93.tar.gz |
gcc/
2012-08-03 Marc Glisse <marc.glisse@inria.fr>
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 <marc.glisse@inria.fr>
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
Diffstat (limited to 'gcc/double-int.c')
-rw-r--r-- | gcc/double-int.c | 29 |
1 files changed, 22 insertions, 7 deletions
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 @@ -135,13 +135,28 @@ mul_double_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1, 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 |