summaryrefslogtreecommitdiff
path: root/gcc/double-int.c
diff options
context:
space:
mode:
authorglisse <glisse@138bc75d-0d04-0410-961f-82ee72b054a4>2012-08-03 12:21:14 +0000
committerglisse <glisse@138bc75d-0d04-0410-961f-82ee72b054a4>2012-08-03 12:21:14 +0000
commit4f5712bd2b23b68ba510f4ed99018df2a7c5fb93 (patch)
tree567eda01e87e579ad9caa799953466f4a2dfb161 /gcc/double-int.c
parentbfa091eeca8305aee66359c5333e854ad3f2ddc1 (diff)
downloadgcc-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.c29
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