aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-08-30 11:19:39 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-08-30 11:19:39 +0000
commitdb61b7f923b769142156eab047c94b04bb7adaae (patch)
tree522f1a6eed83a6d3571b7d5746f0fbeb9c488141
parentb397965cae46d88d4c274fb2ecdde9a4714a4e6a (diff)
downloadgcc-db61b7f923b769142156eab047c94b04bb7adaae.zip
gcc-db61b7f923b769142156eab047c94b04bb7adaae.tar.gz
gcc-db61b7f923b769142156eab047c94b04bb7adaae.tar.bz2
[66/77] Use scalar_mode for constant integers
This patch treats the mode associated with an integer constant as a scalar_mode. We can't use the more natural-sounding scalar_int_mode because we also use (const_int 0) for bounds-checking modes. (It might be worth adding a bounds-specific code instead, but that's for another day.) This exposes a latent bug in simplify_immed_subreg, which for vectors of CONST_WIDE_INTs would pass the vector mode rather than the element mode to rtx_mode_t. I think the: /* We can get a 0 for an error mark. */ || GET_MODE_CLASS (mode) == MODE_VECTOR_INT || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT in immed_double_const is dead. trunc_int_mode (via gen_int_mode) would go on to ICE if the mode fitted in a HWI, and surely plenty of other code would be confused to see a const_int be interpreted as a vector. We should instead be using CONST0_RTX (mode) if we need a safe constant for a particular mode. We didn't try to make these functions take scalar_mode arguments because in many cases that would be too invasive at this stage. Maybe it would become feasible in future. Also, the long-term direction should probably be to add modes to constant integers rather than have then as VOIDmode odd-ones-out. That would remove the need for rtx_mode_t and thus remove the question whether they should use scalar_int_mode, scalar_mode or machine_mode. The patch also uses scalar_mode for the CONST_DOUBLE handling in loc_descriptor. In that case the mode can legitimately be either floating-point or integral. 2017-08-30 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> gcc/ * emit-rtl.c (immed_double_const): Use is_a <scalar_mode> instead of separate mode class checks. Do not allow vector modes here. (immed_wide_int_const): Use as_a <scalar_mode>. * explow.c (trunc_int_for_mode): Likewise. * rtl.h (wi::int_traits<rtx_mode_t>::get_precision): Likewise. (wi::shwi): Likewise. (wi::min_value): Likewise. (wi::max_value): Likewise. * dwarf2out.c (loc_descriptor): Likewise. * simplify-rtx.c (simplify_immed_subreg): Fix rtx_mode_t argument for CONST_WIDE_INT. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r251517
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/dwarf2out.c7
-rw-r--r--gcc/emit-rtl.c19
-rw-r--r--gcc/explow.c6
-rw-r--r--gcc/rtl.h9
-rw-r--r--gcc/simplify-rtx.c2
6 files changed, 35 insertions, 24 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f67f411..ed48b55 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -2,6 +2,22 @@
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
+ * emit-rtl.c (immed_double_const): Use is_a <scalar_mode> instead
+ of separate mode class checks. Do not allow vector modes here.
+ (immed_wide_int_const): Use as_a <scalar_mode>.
+ * explow.c (trunc_int_for_mode): Likewise.
+ * rtl.h (wi::int_traits<rtx_mode_t>::get_precision): Likewise.
+ (wi::shwi): Likewise.
+ (wi::min_value): Likewise.
+ (wi::max_value): Likewise.
+ * dwarf2out.c (loc_descriptor): Likewise.
+ * simplify-rtx.c (simplify_immed_subreg): Fix rtx_mode_t argument
+ for CONST_WIDE_INT.
+
+2017-08-30 Richard Sandiford <richard.sandiford@linaro.org>
+ Alan Hayward <alan.hayward@arm.com>
+ David Sherwood <david.sherwood@arm.com>
+
* tree.h (SCALAR_TYPE_MODE): New macro.
* expr.c (expand_expr_addr_expr_1): Use it.
(expand_expr_real_2): Likewise.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index f857a27..42da36c 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -15863,10 +15863,11 @@ loc_descriptor (rtx rtl, machine_mode mode,
or a floating-point constant. A CONST_DOUBLE is used whenever
the constant requires more than one word in order to be
adequately represented. We output CONST_DOUBLEs as blocks. */
+ scalar_mode smode = as_a <scalar_mode> (mode);
loc_result = new_loc_descr (DW_OP_implicit_value,
- GET_MODE_SIZE (mode), 0);
+ GET_MODE_SIZE (smode), 0);
#if TARGET_SUPPORTS_WIDE_INT == 0
- if (!SCALAR_FLOAT_MODE_P (mode))
+ if (!SCALAR_FLOAT_MODE_P (smode))
{
loc_result->dw_loc_oprnd2.val_class = dw_val_class_const_double;
loc_result->dw_loc_oprnd2.v.val_double
@@ -15875,7 +15876,7 @@ loc_descriptor (rtx rtl, machine_mode mode,
else
#endif
{
- unsigned int length = GET_MODE_SIZE (mode);
+ unsigned int length = GET_MODE_SIZE (smode);
unsigned char *array = ggc_vec_alloc<unsigned char> (length);
insert_float (rtl, array);
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index f0c09ff..15c25ec 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -599,7 +599,8 @@ rtx
immed_wide_int_const (const wide_int_ref &v, machine_mode mode)
{
unsigned int len = v.get_len ();
- unsigned int prec = GET_MODE_PRECISION (mode);
+ /* Not scalar_int_mode because we also allow pointer bound modes. */
+ unsigned int prec = GET_MODE_PRECISION (as_a <scalar_mode> (mode));
/* Allow truncation but not extension since we do not know if the
number is signed or unsigned. */
@@ -659,18 +660,10 @@ immed_double_const (HOST_WIDE_INT i0, HOST_WIDE_INT i1, machine_mode mode)
(i.e., i1 consists only from copies of the sign bit, and sign
of i0 and i1 are the same), then we return a CONST_INT for i0.
3) Otherwise, we create a CONST_DOUBLE for i0 and i1. */
- if (mode != VOIDmode)
- {
- gcc_assert (GET_MODE_CLASS (mode) == MODE_INT
- || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT
- /* We can get a 0 for an error mark. */
- || GET_MODE_CLASS (mode) == MODE_VECTOR_INT
- || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
- || GET_MODE_CLASS (mode) == MODE_POINTER_BOUNDS);
-
- if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
- return gen_int_mode (i0, mode);
- }
+ scalar_mode smode;
+ if (is_a <scalar_mode> (mode, &smode)
+ && GET_MODE_BITSIZE (smode) <= HOST_BITS_PER_WIDE_INT)
+ return gen_int_mode (i0, mode);
/* If this integer fits in one word, return a CONST_INT. */
if ((i1 == 0 && i0 >= 0) || (i1 == ~0 && i0 < 0))
diff --git a/gcc/explow.c b/gcc/explow.c
index 5079629..ee20969 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -49,14 +49,16 @@ static rtx break_out_memory_refs (rtx);
HOST_WIDE_INT
trunc_int_for_mode (HOST_WIDE_INT c, machine_mode mode)
{
- int width = GET_MODE_PRECISION (mode);
+ /* Not scalar_int_mode because we also allow pointer bound modes. */
+ scalar_mode smode = as_a <scalar_mode> (mode);
+ int width = GET_MODE_PRECISION (smode);
/* You want to truncate to a _what_? */
gcc_assert (SCALAR_INT_MODE_P (mode)
|| POINTER_BOUNDS_MODE_P (mode));
/* Canonicalize BImode to 0 and STORE_FLAG_VALUE. */
- if (mode == BImode)
+ if (smode == BImode)
return c & 1 ? STORE_FLAG_VALUE : 0;
/* Sign-extend for the requested mode. */
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 7363bd6..b8ba49f 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2120,8 +2120,7 @@ namespace wi
inline unsigned int
wi::int_traits <rtx_mode_t>::get_precision (const rtx_mode_t &x)
{
- gcc_checking_assert (x.second != BLKmode && x.second != VOIDmode);
- return GET_MODE_PRECISION (x.second);
+ return GET_MODE_PRECISION (as_a <scalar_mode> (x.second));
}
inline wi::storage_ref
@@ -2166,7 +2165,7 @@ namespace wi
inline wi::hwi_with_prec
wi::shwi (HOST_WIDE_INT val, machine_mode mode)
{
- return shwi (val, GET_MODE_PRECISION (mode));
+ return shwi (val, GET_MODE_PRECISION (as_a <scalar_mode> (mode)));
}
/* Produce the smallest number that is represented in MODE. The precision
@@ -2174,7 +2173,7 @@ wi::shwi (HOST_WIDE_INT val, machine_mode mode)
inline wide_int
wi::min_value (machine_mode mode, signop sgn)
{
- return min_value (GET_MODE_PRECISION (mode), sgn);
+ return min_value (GET_MODE_PRECISION (as_a <scalar_mode> (mode)), sgn);
}
/* Produce the largest number that is represented in MODE. The precision
@@ -2182,7 +2181,7 @@ wi::min_value (machine_mode mode, signop sgn)
inline wide_int
wi::max_value (machine_mode mode, signop sgn)
{
- return max_value (GET_MODE_PRECISION (mode), sgn);
+ return max_value (GET_MODE_PRECISION (as_a <scalar_mode> (mode)), sgn);
}
extern void init_rtlanal (void);
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 109c019..60ea9a1 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -5794,7 +5794,7 @@ simplify_immed_subreg (machine_mode outermode, rtx op,
case CONST_WIDE_INT:
{
- rtx_mode_t val = rtx_mode_t (el, innermode);
+ rtx_mode_t val = rtx_mode_t (el, GET_MODE_INNER (innermode));
unsigned char extend = wi::sign_mask (val);
int prec = wi::get_precision (val);