summaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c360
1 files changed, 143 insertions, 217 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 78b0d842cc0..49a0b442c8a 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -339,8 +339,8 @@ get_object_alignment_2 (tree exp, unsigned int *alignp,
if (TREE_CODE (addr) == BIT_AND_EXPR
&& TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST)
{
- align = (TREE_INT_CST_LOW (TREE_OPERAND (addr, 1))
- & -TREE_INT_CST_LOW (TREE_OPERAND (addr, 1)));
+ align = (tree_to_hwi (TREE_OPERAND (addr, 1))
+ & -tree_to_hwi (TREE_OPERAND (addr, 1)));
align *= BITS_PER_UNIT;
addr = TREE_OPERAND (addr, 0);
}
@@ -357,7 +357,7 @@ get_object_alignment_2 (tree exp, unsigned int *alignp,
{
unsigned HOST_WIDE_INT step = 1;
if (TMR_STEP (exp))
- step = TREE_INT_CST_LOW (TMR_STEP (exp));
+ step = tree_to_hwi (TMR_STEP (exp));
align = MIN (align, (step & -step) * BITS_PER_UNIT);
}
if (TMR_INDEX2 (exp))
@@ -379,7 +379,7 @@ get_object_alignment_2 (tree exp, unsigned int *alignp,
bitpos += ptr_bitpos;
if (TREE_CODE (exp) == MEM_REF
|| TREE_CODE (exp) == TARGET_MEM_REF)
- bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT;
+ bitpos += mem_ref_offset (exp).to_short_addr () * BITS_PER_UNIT;
}
}
else if (TREE_CODE (exp) == STRING_CST)
@@ -408,23 +408,23 @@ get_object_alignment_2 (tree exp, unsigned int *alignp,
}
else
next_offset = NULL;
- if (host_integerp (offset, 1))
+ if (tree_fits_uhwi_p (offset))
{
/* Any overflow in calculating offset_bits won't change
the alignment. */
unsigned offset_bits
- = ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT);
+ = ((unsigned) tree_to_uhwi (offset) * BITS_PER_UNIT);
if (offset_bits)
inner = MIN (inner, (offset_bits & -offset_bits));
}
else if (TREE_CODE (offset) == MULT_EXPR
- && host_integerp (TREE_OPERAND (offset, 1), 1))
+ && tree_fits_uhwi_p (TREE_OPERAND (offset, 1)))
{
/* Any overflow in calculating offset_factor won't change
the alignment. */
unsigned offset_factor
- = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
+ = ((unsigned) tree_to_uhwi (TREE_OPERAND (offset, 1))
* BITS_PER_UNIT);
if (offset_factor)
@@ -515,7 +515,7 @@ get_pointer_alignment_1 (tree exp, unsigned int *alignp,
else if (TREE_CODE (exp) == INTEGER_CST)
{
*alignp = BIGGEST_ALIGNMENT;
- *bitposp = ((TREE_INT_CST_LOW (exp) * BITS_PER_UNIT)
+ *bitposp = ((tree_to_hwi (exp) * BITS_PER_UNIT)
& (BIGGEST_ALIGNMENT - 1));
return true;
}
@@ -624,10 +624,10 @@ c_strlen (tree src, int only_value)
a null character if we can represent it as a single HOST_WIDE_INT. */
if (offset_node == 0)
offset = 0;
- else if (! host_integerp (offset_node, 0))
+ else if (!tree_fits_shwi_p (offset_node))
offset = -1;
else
- offset = tree_low_cst (offset_node, 0);
+ offset = tree_to_shwi (offset_node);
/* If the offset is known to be out of bounds, warn, and call strlen at
runtime. */
@@ -665,27 +665,31 @@ c_getstr (tree src)
if (offset_node == 0)
return TREE_STRING_POINTER (src);
- else if (!host_integerp (offset_node, 1)
+ else if (!tree_fits_uhwi_p (offset_node)
|| compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
return 0;
- return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
+ return TREE_STRING_POINTER (src) + tree_to_uhwi (offset_node);
}
-/* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
+/* Return a constant integer corresponding to target reading
GET_MODE_BITSIZE (MODE) bits from string constant STR. */
static rtx
c_readstr (const char *str, enum machine_mode mode)
{
- HOST_WIDE_INT c[2];
+ wide_int c;
HOST_WIDE_INT ch;
unsigned int i, j;
+ HOST_WIDE_INT tmp[MAX_BITSIZE_MODE_ANY_INT / HOST_BITS_PER_WIDE_INT];
+ unsigned int len = (GET_MODE_PRECISION (mode) + HOST_BITS_PER_WIDE_INT - 1)
+ / HOST_BITS_PER_WIDE_INT;
+
+ for (i = 0; i < len; i++)
+ tmp[i] = 0;
gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
- c[0] = 0;
- c[1] = 0;
ch = 1;
for (i = 0; i < GET_MODE_SIZE (mode); i++)
{
@@ -696,13 +700,14 @@ c_readstr (const char *str, enum machine_mode mode)
&& GET_MODE_SIZE (mode) >= UNITS_PER_WORD)
j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
j *= BITS_PER_UNIT;
- gcc_assert (j < HOST_BITS_PER_DOUBLE_INT);
if (ch)
ch = (unsigned char) str[i];
- c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
+ tmp[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
}
- return immed_double_const (c[0], c[1], mode);
+
+ c = wide_int::from_array (tmp, len, GET_MODE_PRECISION (mode));
+ return immed_wide_int_const (c, mode);
}
/* Cast a target constant CST to target CHAR and if that value fits into
@@ -718,7 +723,9 @@ target_char_cast (tree cst, char *p)
|| CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
return 1;
- val = TREE_INT_CST_LOW (cst);
+ /* Do not care if it fits or not right here. */
+ val = tree_to_hwi (cst);
+
if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
@@ -3179,7 +3186,7 @@ expand_builtin_mempcpy_args (tree dest, tree src, tree len,
return NULL_RTX;
/* If LEN is not constant, call the normal function. */
- if (! host_integerp (len, 1))
+ if (! tree_fits_uhwi_p (len))
return NULL_RTX;
len_rtx = expand_normal (len);
@@ -3414,7 +3421,7 @@ expand_builtin_strncpy (tree exp, rtx target)
tree slen = c_strlen (src, 1);
/* We must be passed a constant len and src parameter. */
- if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
+ if (!tree_fits_uhwi_p (len) || !slen || !tree_fits_uhwi_p (slen))
return NULL_RTX;
slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
@@ -3428,15 +3435,15 @@ expand_builtin_strncpy (tree exp, rtx target)
const char *p = c_getstr (src);
rtx dest_mem;
- if (!p || dest_align == 0 || !host_integerp (len, 1)
- || !can_store_by_pieces (tree_low_cst (len, 1),
+ if (!p || dest_align == 0 || !tree_fits_uhwi_p (len)
+ || !can_store_by_pieces (tree_to_uhwi (len),
builtin_strncpy_read_str,
CONST_CAST (char *, p),
dest_align, false))
return NULL_RTX;
dest_mem = get_memory_rtx (dest, len);
- store_by_pieces (dest_mem, tree_low_cst (len, 1),
+ store_by_pieces (dest_mem, tree_to_uhwi (len),
builtin_strncpy_read_str,
CONST_CAST (char *, p), dest_align, false, 0);
dest_mem = force_operand (XEXP (dest_mem, 0), target);
@@ -3569,13 +3576,13 @@ expand_builtin_memset_args (tree dest, tree val, tree len,
* the coefficients by pieces (in the required modes).
* We can't pass builtin_memset_gen_str as that emits RTL. */
c = 1;
- if (host_integerp (len, 1)
- && can_store_by_pieces (tree_low_cst (len, 1),
+ if (tree_fits_uhwi_p (len)
+ && can_store_by_pieces (tree_to_uhwi (len),
builtin_memset_read_str, &c, dest_align,
true))
{
val_rtx = force_reg (val_mode, val_rtx);
- store_by_pieces (dest_mem, tree_low_cst (len, 1),
+ store_by_pieces (dest_mem, tree_to_uhwi (len),
builtin_memset_gen_str, val_rtx, dest_align,
true, 0);
}
@@ -3594,11 +3601,11 @@ expand_builtin_memset_args (tree dest, tree val, tree len,
if (c)
{
- if (host_integerp (len, 1)
- && can_store_by_pieces (tree_low_cst (len, 1),
+ if (tree_fits_uhwi_p (len)
+ && can_store_by_pieces (tree_to_uhwi (len),
builtin_memset_read_str, &c, dest_align,
true))
- store_by_pieces (dest_mem, tree_low_cst (len, 1),
+ store_by_pieces (dest_mem, tree_to_uhwi (len),
builtin_memset_read_str, &c, dest_align, true, 0);
else if (!set_storage_via_setmem (dest_mem, len_rtx,
gen_int_mode (c, val_mode),
@@ -4503,7 +4510,7 @@ expand_builtin_frame_address (tree fndecl, tree exp)
if (call_expr_nargs (exp) == 0)
/* Warning about missing arg was already issued. */
return const0_rtx;
- else if (! host_integerp (CALL_EXPR_ARG (exp, 0), 1))
+ else if (! tree_fits_uhwi_p (CALL_EXPR_ARG (exp, 0)))
{
if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
error ("invalid argument to %<__builtin_frame_address%>");
@@ -4515,7 +4522,7 @@ expand_builtin_frame_address (tree fndecl, tree exp)
{
rtx tem
= expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
- tree_low_cst (CALL_EXPR_ARG (exp, 0), 1));
+ tree_to_uhwi (CALL_EXPR_ARG (exp, 0)));
/* Some ports cannot access arbitrary stack frames. */
if (tem == NULL)
@@ -4569,7 +4576,7 @@ expand_builtin_alloca (tree exp, bool cannot_accumulate)
/* Compute the alignment. */
align = (alloca_with_align
- ? TREE_INT_CST_LOW (CALL_EXPR_ARG (exp, 1))
+ ? tree_to_hwi (CALL_EXPR_ARG (exp, 1))
: BIGGEST_ALIGNMENT);
/* Allocate the desired space. */
@@ -5010,12 +5017,13 @@ expand_builtin_signbit (tree exp, rtx target)
if (bitpos < GET_MODE_BITSIZE (rmode))
{
- double_int mask = double_int_zero.set_bit (bitpos);
+ wide_int mask = wide_int::set_bit_in_zero (bitpos,
+ GET_MODE_PRECISION (rmode));
if (GET_MODE_SIZE (imode) > GET_MODE_SIZE (rmode))
temp = gen_lowpart (rmode, temp);
temp = expand_binop (rmode, and_optab, temp,
- immed_double_int_const (mask, rmode),
+ immed_wide_int_const (mask, rmode),
NULL_RTX, 1, OPTAB_LIB_WIDEN);
}
else
@@ -5401,7 +5409,7 @@ expand_builtin_atomic_compare_exchange (enum machine_mode mode, tree exp,
weak = CALL_EXPR_ARG (exp, 3);
is_weak = false;
- if (host_integerp (weak, 0) && tree_low_cst (weak, 0) != 0)
+ if (tree_fits_shwi_p (weak) && tree_to_shwi (weak) != 0)
is_weak = true;
oldval = expect;
@@ -8031,8 +8039,9 @@ fold_builtin_int_roundingfn (location_t loc, tree fndecl, tree arg)
{
tree itype = TREE_TYPE (TREE_TYPE (fndecl));
tree ftype = TREE_TYPE (arg);
- double_int val;
+ wide_int val;
REAL_VALUE_TYPE r;
+ bool fail = false;
switch (DECL_FUNCTION_CODE (fndecl))
{
@@ -8058,9 +8067,10 @@ fold_builtin_int_roundingfn (location_t loc, tree fndecl, tree arg)
gcc_unreachable ();
}
- real_to_integer2 ((HOST_WIDE_INT *)&val.low, &val.high, &r);
- if (double_int_fits_to_tree_p (itype, val))
- return double_int_to_tree (itype, val);
+ val = real_to_integer (&r, &fail,
+ TYPE_PRECISION (itype));
+ if (!fail)
+ return wide_int_to_tree (itype, val);
}
}
@@ -8093,102 +8103,40 @@ fold_builtin_bitop (tree fndecl, tree arg)
/* Optimize for constant argument. */
if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
{
- HOST_WIDE_INT hi, width, result;
- unsigned HOST_WIDE_INT lo;
- tree type;
-
- type = TREE_TYPE (arg);
- width = TYPE_PRECISION (type);
- lo = TREE_INT_CST_LOW (arg);
-
- /* Clear all the bits that are beyond the type's precision. */
- if (width > HOST_BITS_PER_WIDE_INT)
- {
- hi = TREE_INT_CST_HIGH (arg);
- if (width < HOST_BITS_PER_DOUBLE_INT)
- hi &= ~((unsigned HOST_WIDE_INT) (-1)
- << (width - HOST_BITS_PER_WIDE_INT));
- }
- else
- {
- hi = 0;
- if (width < HOST_BITS_PER_WIDE_INT)
- lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
- }
+ wide_int warg = arg;
+ wide_int result;
switch (DECL_FUNCTION_CODE (fndecl))
{
CASE_INT_FN (BUILT_IN_FFS):
- if (lo != 0)
- result = ffs_hwi (lo);
- else if (hi != 0)
- result = HOST_BITS_PER_WIDE_INT + ffs_hwi (hi);
- else
- result = 0;
+ result = warg.ffs ();
break;
CASE_INT_FN (BUILT_IN_CLZ):
- if (hi != 0)
- result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
- else if (lo != 0)
- result = width - floor_log2 (lo) - 1;
- else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
- result = width;
+ result = warg.clz ();
break;
CASE_INT_FN (BUILT_IN_CTZ):
- if (lo != 0)
- result = ctz_hwi (lo);
- else if (hi != 0)
- result = HOST_BITS_PER_WIDE_INT + ctz_hwi (hi);
- else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
- result = width;
+ result = warg.ctz ();
break;
CASE_INT_FN (BUILT_IN_CLRSB):
- if (width > 2 * HOST_BITS_PER_WIDE_INT)
- return NULL_TREE;
- if (width > HOST_BITS_PER_WIDE_INT
- && (hi & ((unsigned HOST_WIDE_INT) 1
- << (width - HOST_BITS_PER_WIDE_INT - 1))) != 0)
- {
- hi = ~hi & ~((unsigned HOST_WIDE_INT) (-1)
- << (width - HOST_BITS_PER_WIDE_INT - 1));
- lo = ~lo;
- }
- else if (width <= HOST_BITS_PER_WIDE_INT
- && (lo & ((unsigned HOST_WIDE_INT) 1 << (width - 1))) != 0)
- lo = ~lo & ~((unsigned HOST_WIDE_INT) (-1) << (width - 1));
- if (hi != 0)
- result = width - floor_log2 (hi) - 2 - HOST_BITS_PER_WIDE_INT;
- else if (lo != 0)
- result = width - floor_log2 (lo) - 2;
- else
- result = width - 1;
+ result = warg.clrsb ();
break;
CASE_INT_FN (BUILT_IN_POPCOUNT):
- result = 0;
- while (lo)
- result++, lo &= lo - 1;
- while (hi)
- result++, hi &= (unsigned HOST_WIDE_INT) hi - 1;
+ result = warg.popcount ();
break;
CASE_INT_FN (BUILT_IN_PARITY):
- result = 0;
- while (lo)
- result++, lo &= lo - 1;
- while (hi)
- result++, hi &= (unsigned HOST_WIDE_INT) hi - 1;
- result &= 1;
+ result = warg.parity ();
break;
default:
gcc_unreachable ();
}
- return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
+ return wide_int_to_tree (TREE_TYPE (TREE_TYPE (fndecl)), result);
}
return NULL_TREE;
@@ -8205,49 +8153,24 @@ fold_builtin_bswap (tree fndecl, tree arg)
/* Optimize constant value. */
if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
{
- HOST_WIDE_INT hi, width, r_hi = 0;
- unsigned HOST_WIDE_INT lo, r_lo = 0;
tree type = TREE_TYPE (TREE_TYPE (fndecl));
- width = TYPE_PRECISION (type);
- lo = TREE_INT_CST_LOW (arg);
- hi = TREE_INT_CST_HIGH (arg);
-
switch (DECL_FUNCTION_CODE (fndecl))
{
case BUILT_IN_BSWAP16:
case BUILT_IN_BSWAP32:
case BUILT_IN_BSWAP64:
{
- int s;
-
- for (s = 0; s < width; s += 8)
- {
- int d = width - s - 8;
- unsigned HOST_WIDE_INT byte;
-
- if (s < HOST_BITS_PER_WIDE_INT)
- byte = (lo >> s) & 0xff;
- else
- byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
-
- if (d < HOST_BITS_PER_WIDE_INT)
- r_lo |= byte << d;
- else
- r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
- }
+ signop sgn = TYPE_SIGN (type);
+ tree result =
+ wide_int_to_tree (type,
+ wide_int (arg)
+ .force_to_size (TYPE_PRECISION (type), sgn).bswap ());
+ return result;
}
-
- break;
-
default:
gcc_unreachable ();
}
-
- if (width < HOST_BITS_PER_WIDE_INT)
- return build_int_cst (type, r_lo);
- else
- return build_int_cst_wide (type, r_lo, r_hi);
}
return NULL_TREE;
@@ -8309,7 +8232,7 @@ fold_builtin_logarithm (location_t loc, tree fndecl, tree arg,
/* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
{
REAL_VALUE_TYPE dconst10;
- real_from_integer (&dconst10, VOIDmode, 10, 0, 0);
+ real_from_integer (&dconst10, VOIDmode, 10, SIGNED);
x = build_real (type, dconst10);
}
exponent = CALL_EXPR_ARG (arg, 0);
@@ -8462,7 +8385,7 @@ fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
/* Check for an integer exponent. */
n = real_to_integer (&c);
- real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
+ real_from_integer (&cint, VOIDmode, n, SIGNED);
if (real_identical (&c, &cint))
{
/* Attempt to evaluate pow at compile-time, unless this should
@@ -8560,9 +8483,9 @@ fold_builtin_powi (location_t loc, tree fndecl ATTRIBUTE_UNUSED,
if (real_onep (arg0))
return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
- if (host_integerp (arg1, 0))
+ if (tree_fits_shwi_p (arg1))
{
- HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
+ HOST_WIDE_INT c = tree_to_shwi (arg1);
/* Evaluate powi at compile-time. */
if (TREE_CODE (arg0) == REAL_CST
@@ -8659,7 +8582,7 @@ fold_builtin_memset (location_t loc, tree dest, tree c, tree len,
|| ! validate_arg (len, INTEGER_TYPE))
return NULL_TREE;
- if (! host_integerp (len, 1))
+ if (! tree_fits_uhwi_p (len))
return NULL_TREE;
/* If the LEN parameter is zero, return DEST. */
@@ -8689,7 +8612,7 @@ fold_builtin_memset (location_t loc, tree dest, tree c, tree len,
if (! var_decl_component_p (var))
return NULL_TREE;
- length = tree_low_cst (len, 1);
+ length = tree_to_uhwi (len);
if (GET_MODE_SIZE (TYPE_MODE (etype)) != length
|| get_pointer_alignment (dest) / BITS_PER_UNIT < length)
return NULL_TREE;
@@ -8704,7 +8627,7 @@ fold_builtin_memset (location_t loc, tree dest, tree c, tree len,
if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
return NULL_TREE;
- cval = TREE_INT_CST_LOW (c);
+ cval = tree_to_hwi (c);
cval &= 0xff;
cval |= cval << 8;
cval |= cval << 16;
@@ -8792,9 +8715,9 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src,
if (!dest_align || !src_align)
return NULL_TREE;
if (readonly_data_expr (src)
- || (host_integerp (len, 1)
+ || (tree_fits_uhwi_p (len)
&& (MIN (src_align, dest_align) / BITS_PER_UNIT
- >= (unsigned HOST_WIDE_INT) tree_low_cst (len, 1))))
+ >= (unsigned HOST_WIDE_INT) tree_to_uhwi (len))))
{
tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
if (!fn)
@@ -8817,8 +8740,8 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src,
destvar = TREE_OPERAND (dest, 0);
dest_base = get_ref_base_and_extent (destvar, &dest_offset,
&size, &maxsize);
- if (host_integerp (len, 1))
- maxsize = tree_low_cst (len, 1);
+ if (tree_fits_uhwi_p (len))
+ maxsize = tree_to_uhwi (len);
else
maxsize = -1;
src_offset /= BITS_PER_UNIT;
@@ -8834,20 +8757,19 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src,
else if (TREE_CODE (src_base) == MEM_REF
&& TREE_CODE (dest_base) == MEM_REF)
{
- double_int off;
+ addr_wide_int off;
if (! operand_equal_p (TREE_OPERAND (src_base, 0),
TREE_OPERAND (dest_base, 0), 0))
return NULL_TREE;
- off = mem_ref_offset (src_base) +
- double_int::from_shwi (src_offset);
- if (!off.fits_shwi ())
+ off = mem_ref_offset (src_base) + src_offset;
+ if (!off.fits_shwi_p ())
return NULL_TREE;
- src_offset = off.low;
- off = mem_ref_offset (dest_base) +
- double_int::from_shwi (dest_offset);
- if (!off.fits_shwi ())
+ src_offset = off.to_shwi ();
+
+ off = mem_ref_offset (dest_base) + dest_offset;
+ if (!off.fits_shwi_p ())
return NULL_TREE;
- dest_offset = off.low;
+ dest_offset = off.to_shwi ();
if (ranges_overlap_p (src_offset, maxsize,
dest_offset, maxsize))
return NULL_TREE;
@@ -8884,7 +8806,7 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src,
return NULL_TREE;
}
- if (!host_integerp (len, 0))
+ if (!tree_fits_shwi_p (len))
return NULL_TREE;
/* FIXME:
This logic lose for arguments like (type *)malloc (sizeof (type)),
@@ -9172,7 +9094,7 @@ fold_builtin_memchr (location_t loc, tree arg1, tree arg2, tree len, tree type)
const char *p1;
if (TREE_CODE (arg2) != INTEGER_CST
- || !host_integerp (len, 1))
+ || !tree_fits_uhwi_p (len))
return NULL_TREE;
p1 = c_getstr (arg1);
@@ -9185,7 +9107,7 @@ fold_builtin_memchr (location_t loc, tree arg1, tree arg2, tree len, tree type)
if (target_char_cast (arg2, &c))
return NULL_TREE;
- r = (const char *) memchr (p1, c, tree_low_cst (len, 1));
+ r = (const char *) memchr (p1, c, tree_to_uhwi (len));
if (r == NULL)
return build_int_cst (TREE_TYPE (arg1), 0);
@@ -9224,11 +9146,11 @@ fold_builtin_memcmp (location_t loc, tree arg1, tree arg2, tree len)
/* If all arguments are constant, and the value of len is not greater
than the lengths of arg1 and arg2, evaluate at compile-time. */
- if (host_integerp (len, 1) && p1 && p2
+ if (tree_fits_uhwi_p (len) && p1 && p2
&& compare_tree_int (len, strlen (p1) + 1) <= 0
&& compare_tree_int (len, strlen (p2) + 1) <= 0)
{
- const int r = memcmp (p1, p2, tree_low_cst (len, 1));
+ const int r = memcmp (p1, p2, tree_to_uhwi (len));
if (r > 0)
return integer_one_node;
@@ -9240,7 +9162,7 @@ fold_builtin_memcmp (location_t loc, tree arg1, tree arg2, tree len)
/* If len parameter is one, return an expression corresponding to
(*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
- if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
+ if (tree_fits_uhwi_p (len) && tree_to_uhwi (len) == 1)
{
tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
tree cst_uchar_ptr_node
@@ -9352,9 +9274,9 @@ fold_builtin_strncmp (location_t loc, tree arg1, tree arg2, tree len)
p1 = c_getstr (arg1);
p2 = c_getstr (arg2);
- if (host_integerp (len, 1) && p1 && p2)
+ if (tree_fits_uhwi_p (len) && p1 && p2)
{
- const int i = strncmp (p1, p2, tree_low_cst (len, 1));
+ const int i = strncmp (p1, p2, tree_to_uhwi (len));
if (i > 0)
return integer_one_node;
else if (i < 0)
@@ -9400,7 +9322,7 @@ fold_builtin_strncmp (location_t loc, tree arg1, tree arg2, tree len)
/* If len parameter is one, return an expression corresponding to
(*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
- if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
+ if (tree_fits_uhwi_p (len) && tree_to_uhwi (len) == 1)
{
tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
tree cst_uchar_ptr_node
@@ -9858,7 +9780,7 @@ fold_builtin_load_exponent (location_t loc, tree arg0, tree arg1,
/* If both arguments are constant, then try to evaluate it. */
if ((ldexp || REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2)
&& TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
- && host_integerp (arg1, 0))
+ && tree_fits_shwi_p (arg1))
{
/* Bound the maximum adjustment to twice the range of the
mode's valid exponents. Use abs to ensure the range is
@@ -9868,7 +9790,7 @@ fold_builtin_load_exponent (location_t loc, tree arg0, tree arg1,
- REAL_MODE_FORMAT (TYPE_MODE (type))->emin);
/* Get the user-requested adjustment. */
- const HOST_WIDE_INT req_exp_adj = tree_low_cst (arg1, 0);
+ const HOST_WIDE_INT req_exp_adj = tree_to_shwi (arg1);
/* The requested adjustment must be inside this range. This
is a preliminary cap to avoid things like overflow, we
@@ -12338,7 +12260,7 @@ fold_builtin_snprintf (location_t loc, tree dest, tree destsize, tree fmt,
if (orig && !validate_arg (orig, POINTER_TYPE))
return NULL_TREE;
- if (!host_integerp (destsize, 1))
+ if (!tree_fits_uhwi_p (destsize))
return NULL_TREE;
/* Check whether the format is a literal string constant. */
@@ -12352,7 +12274,7 @@ fold_builtin_snprintf (location_t loc, tree dest, tree destsize, tree fmt,
if (!init_target_chars ())
return NULL_TREE;
- destlen = tree_low_cst (destsize, 1);
+ destlen = tree_to_uhwi (destsize);
/* If the format doesn't contain % args or %%, use strcpy. */
if (strchr (fmt_str, target_percent) == NULL)
@@ -12397,10 +12319,10 @@ fold_builtin_snprintf (location_t loc, tree dest, tree destsize, tree fmt,
return NULL_TREE;
retval = c_strlen (orig, 1);
- if (!retval || !host_integerp (retval, 1))
+ if (!retval || !tree_fits_uhwi_p (retval))
return NULL_TREE;
- origlen = tree_low_cst (retval, 1);
+ origlen = tree_to_uhwi (retval);
/* We could expand this as
memcpy (str1, str2, cst - 1); str1[cst - 1] = '\0';
or to
@@ -12462,7 +12384,7 @@ expand_builtin_object_size (tree exp)
return const0_rtx;
}
- object_size_type = tree_low_cst (ost, 0);
+ object_size_type = tree_to_shwi (ost);
return object_size_type < 2 ? constm1_rtx : const0_rtx;
}
@@ -12491,10 +12413,10 @@ expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
len = CALL_EXPR_ARG (exp, 2);
size = CALL_EXPR_ARG (exp, 3);
- if (! host_integerp (size, 1))
+ if (! tree_fits_uhwi_p (size))
return NULL_RTX;
- if (host_integerp (len, 1) || integer_all_onesp (size))
+ if (tree_fits_uhwi_p (len) || integer_all_onesp (size))
{
tree fn;
@@ -12625,22 +12547,22 @@ maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
if (!len || !size)
return;
- if (! host_integerp (size, 1) || integer_all_onesp (size))
+ if (! tree_fits_uhwi_p (size) || integer_all_onesp (size))
return;
if (is_strlen)
{
len = c_strlen (len, 1);
- if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
+ if (! len || ! tree_fits_uhwi_p (len) || tree_int_cst_lt (len, size))
return;
}
else if (fcode == BUILT_IN_STRNCAT_CHK)
{
tree src = CALL_EXPR_ARG (exp, 1);
- if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
+ if (! src || ! tree_fits_uhwi_p (len) || tree_int_cst_lt (len, size))
return;
src = c_strlen (src, 1);
- if (! src || ! host_integerp (src, 1))
+ if (! src || ! tree_fits_uhwi_p (src))
{
warning_at (loc, 0, "%Kcall to %D might overflow destination buffer",
exp, get_callee_fndecl (exp));
@@ -12649,7 +12571,7 @@ maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
else if (tree_int_cst_lt (src, size))
return;
}
- else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
+ else if (! tree_fits_uhwi_p (len) || ! tree_int_cst_lt (size, len))
return;
warning_at (loc, 0, "%Kcall to %D will always overflow destination buffer",
@@ -12673,7 +12595,7 @@ maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
size = CALL_EXPR_ARG (exp, 2);
fmt = CALL_EXPR_ARG (exp, 3);
- if (! host_integerp (size, 1) || integer_all_onesp (size))
+ if (! tree_fits_uhwi_p (size) || integer_all_onesp (size))
return;
/* Check whether the format is a literal string constant. */
@@ -12701,7 +12623,7 @@ maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
return;
len = c_strlen (arg, 1);
- if (!len || ! host_integerp (len, 1))
+ if (!len || ! tree_fits_uhwi_p (len))
return;
}
else
@@ -12744,6 +12666,7 @@ fold_builtin_object_size (tree ptr, tree ost)
{
unsigned HOST_WIDE_INT bytes;
int object_size_type;
+ int precision = TYPE_PRECISION (TREE_TYPE (ptr));
if (!validate_arg (ptr, POINTER_TYPE)
|| !validate_arg (ost, INTEGER_TYPE))
@@ -12756,7 +12679,7 @@ fold_builtin_object_size (tree ptr, tree ost)
|| compare_tree_int (ost, 3) > 0)
return NULL_TREE;
- object_size_type = tree_low_cst (ost, 0);
+ object_size_type = tree_to_shwi (ost);
/* __builtin_object_size doesn't evaluate side-effects in its arguments;
if there are any side-effects, it returns (size_t) -1 for types 0 and 1
@@ -12766,21 +12689,24 @@ fold_builtin_object_size (tree ptr, tree ost)
if (TREE_CODE (ptr) == ADDR_EXPR)
{
- bytes = compute_builtin_object_size (ptr, object_size_type);
- if (double_int_fits_to_tree_p (size_type_node,
- double_int::from_uhwi (bytes)))
- return build_int_cstu (size_type_node, bytes);
+
+ wide_int wbytes
+ = wide_int::from_uhwi (compute_builtin_object_size (ptr, object_size_type),
+ precision);
+ if (wbytes.fits_to_tree_p (size_type_node))
+ return wide_int_to_tree (size_type_node, wbytes);
}
else if (TREE_CODE (ptr) == SSA_NAME)
{
/* If object size is not known yet, delay folding until
later. Maybe subsequent passes will help determining
it. */
+ wide_int wbytes;
bytes = compute_builtin_object_size (ptr, object_size_type);
+ wbytes = wide_int::from_uhwi (bytes, precision);
if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2 ? -1 : 0)
- && double_int_fits_to_tree_p (size_type_node,
- double_int::from_uhwi (bytes)))
- return build_int_cstu (size_type_node, bytes);
+ && wbytes.fits_to_tree_p (size_type_node))
+ return wide_int_to_tree (size_type_node, wbytes);
}
return NULL_TREE;
@@ -12822,17 +12748,17 @@ fold_builtin_memory_chk (location_t loc, tree fndecl,
}
}
- if (! host_integerp (size, 1))
+ if (! tree_fits_uhwi_p (size))
return NULL_TREE;
if (! integer_all_onesp (size))
{
- if (! host_integerp (len, 1))
+ if (! tree_fits_uhwi_p (len))
{
/* If LEN is not constant, try MAXLEN too.
For MAXLEN only allow optimizing into non-_ocs function
if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
- if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
+ if (maxlen == NULL_TREE || ! tree_fits_uhwi_p (maxlen))
{
if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
{
@@ -12904,18 +12830,18 @@ fold_builtin_stxcpy_chk (location_t loc, tree fndecl, tree dest,
if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest);
- if (! host_integerp (size, 1))
+ if (! tree_fits_uhwi_p (size))
return NULL_TREE;
if (! integer_all_onesp (size))
{
len = c_strlen (src, 1);
- if (! len || ! host_integerp (len, 1))
+ if (! len || ! tree_fits_uhwi_p (len))
{
/* If LEN is not constant, try MAXLEN too.
For MAXLEN only allow optimizing into non-_ocs function
if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
- if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
+ if (maxlen == NULL_TREE || ! tree_fits_uhwi_p (maxlen))
{
if (fcode == BUILT_IN_STPCPY_CHK)
{
@@ -12991,17 +12917,17 @@ fold_builtin_stxncpy_chk (location_t loc, tree dest, tree src,
return build_call_expr_loc (loc, fn, 4, dest, src, len, size);
}
- if (! host_integerp (size, 1))
+ if (! tree_fits_uhwi_p (size))
return NULL_TREE;
if (! integer_all_onesp (size))
{
- if (! host_integerp (len, 1))
+ if (! tree_fits_uhwi_p (len))
{
/* If LEN is not constant, try MAXLEN too.
For MAXLEN only allow optimizing into non-_ocs function
if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
- if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
+ if (maxlen == NULL_TREE || ! tree_fits_uhwi_p (maxlen))
return NULL_TREE;
}
else
@@ -13040,7 +12966,7 @@ fold_builtin_strcat_chk (location_t loc, tree fndecl, tree dest,
if (p && *p == '\0')
return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
- if (! host_integerp (size, 1) || ! integer_all_onesp (size))
+ if (! tree_fits_uhwi_p (size) || ! integer_all_onesp (size))
return NULL_TREE;
/* If __builtin_strcat_chk is used, assume strcat is available. */
@@ -13074,15 +13000,15 @@ fold_builtin_strncat_chk (location_t loc, tree fndecl,
else if (integer_zerop (len))
return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
- if (! host_integerp (size, 1))
+ if (! tree_fits_uhwi_p (size))
return NULL_TREE;
if (! integer_all_onesp (size))
{
tree src_len = c_strlen (src, 1);
if (src_len
- && host_integerp (src_len, 1)
- && host_integerp (len, 1)
+ && tree_fits_uhwi_p (src_len)
+ && tree_fits_uhwi_p (len)
&& ! tree_int_cst_lt (len, src_len))
{
/* If LEN >= strlen (SRC), optimize into __strcat_chk. */
@@ -13131,7 +13057,7 @@ fold_builtin_sprintf_chk_1 (location_t loc, int nargs, tree *args,
if (!validate_arg (fmt, POINTER_TYPE))
return NULL_TREE;
- if (! host_integerp (size, 1))
+ if (! tree_fits_uhwi_p (size))
return NULL_TREE;
len = NULL_TREE;
@@ -13162,7 +13088,7 @@ fold_builtin_sprintf_chk_1 (location_t loc, int nargs, tree *args,
if (validate_arg (arg, POINTER_TYPE))
{
len = c_strlen (arg, 1);
- if (! len || ! host_integerp (len, 1))
+ if (! len || ! tree_fits_uhwi_p (len))
len = NULL_TREE;
}
}
@@ -13239,17 +13165,17 @@ fold_builtin_snprintf_chk_1 (location_t loc, int nargs, tree *args,
if (!validate_arg (fmt, POINTER_TYPE))
return NULL_TREE;
- if (! host_integerp (size, 1))
+ if (! tree_fits_uhwi_p (size))
return NULL_TREE;
if (! integer_all_onesp (size))
{
- if (! host_integerp (len, 1))
+ if (! tree_fits_uhwi_p (len))
{
/* If LEN is not constant, try MAXLEN too.
For MAXLEN only allow optimizing into non-_ocs function
if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
- if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
+ if (maxlen == NULL_TREE || ! tree_fits_uhwi_p (maxlen))
return NULL_TREE;
}
else
@@ -13894,10 +13820,10 @@ do_mpfr_bessel_n (tree arg1, tree arg2, tree type,
/* To proceed, MPFR must exactly represent the target floating point
format, which only happens when the target base equals two. */
if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
- && host_integerp (arg1, 0)
+ && tree_fits_shwi_p (arg1)
&& TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
{
- const HOST_WIDE_INT n = tree_low_cst(arg1, 0);
+ const HOST_WIDE_INT n = tree_to_shwi (arg1);
const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg2);
if (n == (long)n