force_to_mode exits partway through for modes that aren't scalar
integers. This patch splits the remainder of the function out
into a subroutine, force_int_to_mode, so that the modes from that
point on can have type scalar_int_mode.
The patch also makes sure that xmode is kept up-to-date with x
and uses xmode instead of GET_MODE (x) throughout.
2017-07-13 Richard Sandiford
Alan Hayward
David Sherwood
gcc/
* combine.c (force_int_to_mode): New function, split out from...
(force_to_mode): ...here. Keep xmode up-to-date and use it
instead of GET_MODE (x).
Index: gcc/combine.c
===
--- gcc/combine.c 2017-07-13 09:18:42.160519154 +0100
+++ gcc/combine.c 2017-07-13 09:18:42.622481204 +0100
@@ -449,6 +449,8 @@ static rtx extract_left_shift (rtx, int)
static int get_pos_from_mask (unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT *);
static rtx canon_reg_for_combine (rtx, rtx);
+static rtx force_int_to_mode (rtx, scalar_int_mode, scalar_int_mode,
+ scalar_int_mode, unsigned HOST_WIDE_INT, int);
static rtx force_to_mode (rtx, machine_mode,
unsigned HOST_WIDE_INT, int);
static rtx if_then_else_cond (rtx, rtx *, rtx *);
@@ -8517,8 +8519,7 @@ force_to_mode (rtx x, machine_mode mode,
enum rtx_code code = GET_CODE (x);
int next_select = just_select || code == XOR || code == NOT || code == NEG;
machine_mode op_mode;
- unsigned HOST_WIDE_INT fuller_mask, nonzero;
- rtx op0, op1, temp;
+ unsigned HOST_WIDE_INT nonzero;
/* If this is a CALL or ASM_OPERANDS, don't do anything. Some of the
code below will do the wrong thing since the mode of such an
@@ -8546,15 +8547,6 @@ force_to_mode (rtx x, machine_mode mode,
if (op_mode)
mask &= GET_MODE_MASK (op_mode);
- /* When we have an arithmetic operation, or a shift whose count we
- do not know, we need to assume that all bits up to the highest-order
- bit in MASK will be needed. This is how we form such a mask. */
- if (mask & (HOST_WIDE_INT_1U << (HOST_BITS_PER_WIDE_INT - 1)))
-fuller_mask = HOST_WIDE_INT_M1U;
- else
-fuller_mask = ((HOST_WIDE_INT_1U << (floor_log2 (mask) + 1))
- - 1);
-
/* Determine what bits of X are guaranteed to be (non)zero. */
nonzero = nonzero_bits (x, mode);
@@ -8592,9 +8584,42 @@ force_to_mode (rtx x, machine_mode mode,
& ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x)))
return force_to_mode (SUBREG_REG (x), mode, mask, next_select);
- /* The arithmetic simplifications here only work for scalar integer modes.
*/
- if (!SCALAR_INT_MODE_P (mode) || !SCALAR_INT_MODE_P (GET_MODE (x)))
-return gen_lowpart_or_truncate (mode, x);
+ scalar_int_mode int_mode, xmode;
+ if (is_a (mode, &int_mode)
+ && is_a (GET_MODE (x), &xmode))
+/* OP_MODE is either MODE or XMODE, so it must be a scalar
+ integer too. */
+return force_int_to_mode (x, int_mode, xmode,
+ as_a (op_mode),
+ mask, just_select);
+
+ return gen_lowpart_or_truncate (mode, x);
+}
+
+/* Subroutine of force_to_mode that handles cases in which both X and
+ the result are scalar integers. MODE is the mode of the result,
+ XMODE is the mode of X, and OP_MODE says which of MODE or XMODE
+ is preferred for simplified versions of X. The other arguments
+ are as for force_to_mode. */
+
+static rtx
+force_int_to_mode (rtx x, scalar_int_mode mode, scalar_int_mode xmode,
+ scalar_int_mode op_mode, unsigned HOST_WIDE_INT mask,
+ int just_select)
+{
+ enum rtx_code code = GET_CODE (x);
+ int next_select = just_select || code == XOR || code == NOT || code == NEG;
+ unsigned HOST_WIDE_INT fuller_mask;
+ rtx op0, op1, temp;
+
+ /* When we have an arithmetic operation, or a shift whose count we
+ do not know, we need to assume that all bits up to the highest-order
+ bit in MASK will be needed. This is how we form such a mask. */
+ if (mask & (HOST_WIDE_INT_1U << (HOST_BITS_PER_WIDE_INT - 1)))
+fuller_mask = HOST_WIDE_INT_M1U;
+ else
+fuller_mask = ((HOST_WIDE_INT_1U << (floor_log2 (mask) + 1))
+ - 1);
switch (code)
{
@@ -8625,14 +8650,14 @@ force_to_mode (rtx x, machine_mode mode,
{
x = simplify_and_const_int (x, op_mode, XEXP (x, 0),
mask & INTVAL (XEXP (x, 1)));
+ xmode = op_mode;
/* If X is still an AND, see if it is an AND with a mask that
is just some low-order bits. If so, and it is MASK, we don't
need it. */
if (GET_CODE (x) == AND && CONST_INT_P (XEXP (x, 1))
- && ((INTVAL (XEXP (x, 1)) & GET_MODE_MASK (GET_MODE (x)))
- == mask))
+ && (INTVAL (XEXP (x, 1)) & G