Commit e5b2900e by Kyrylo Tkachov

[combine] Don't transform sign and zero extends inside mults

2015-11-13  Segher Boessenkool  <segher@kernel.crashing.org>
            Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

        * combine.c (subst): Don't substitute or simplify when
        handling register-wise widening multiply.
        (force_to_mode): Likewise.

        * gcc.target/aarch64/umaddl_combine_1.c: New test.

From-SVN: r230326
parent dd3c1b14
2015-11-13 Segher Boessenkool <segher@kernel.crashing.org>
Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* combine.c (subst): Don't substitute or simplify when
handling register-wise widening multiply.
(force_to_mode): Likewise.
2015-11-13 Richard Sandiford <richard.sandiford@arm.com> 2015-11-13 Richard Sandiford <richard.sandiford@arm.com>
PR tree-optimization/68264 PR tree-optimization/68264
...@@ -5284,6 +5284,22 @@ subst (rtx x, rtx from, rtx to, int in_dest, int in_cond, int unique_copy) ...@@ -5284,6 +5284,22 @@ subst (rtx x, rtx from, rtx to, int in_dest, int in_cond, int unique_copy)
|| GET_CODE (SET_DEST (x)) == PC)) || GET_CODE (SET_DEST (x)) == PC))
fmt = "ie"; fmt = "ie";
/* Substituting into the operands of a widening MULT is not likely
to create RTL matching a machine insn. */
if (code == MULT
&& (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
|| GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)
&& (GET_CODE (XEXP (x, 1)) == ZERO_EXTEND
|| GET_CODE (XEXP (x, 1)) == SIGN_EXTEND)
&& REG_P (XEXP (XEXP (x, 0), 0))
&& REG_P (XEXP (XEXP (x, 1), 0)))
{
if (from == to)
return x;
else
return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
}
/* Get the mode of operand 0 in case X is now a SIGN_EXTEND of a /* Get the mode of operand 0 in case X is now a SIGN_EXTEND of a
constant. */ constant. */
if (fmt[0] == 'e') if (fmt[0] == 'e')
...@@ -8455,6 +8471,17 @@ force_to_mode (rtx x, machine_mode mode, unsigned HOST_WIDE_INT mask, ...@@ -8455,6 +8471,17 @@ force_to_mode (rtx x, machine_mode mode, unsigned HOST_WIDE_INT mask,
/* ... fall through ... */ /* ... fall through ... */
case MULT: case MULT:
/* Substituting into the operands of a widening MULT is not likely to
create RTL matching a machine insn. */
if (code == MULT
&& (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
|| GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)
&& (GET_CODE (XEXP (x, 1)) == ZERO_EXTEND
|| GET_CODE (XEXP (x, 1)) == SIGN_EXTEND)
&& REG_P (XEXP (XEXP (x, 0), 0))
&& REG_P (XEXP (XEXP (x, 1), 0)))
return gen_lowpart_or_truncate (mode, x);
/* For PLUS, MINUS and MULT, we need any bits less significant than the /* For PLUS, MINUS and MULT, we need any bits less significant than the
most significant bit in MASK since carries from those bits will most significant bit in MASK since carries from those bits will
affect the bits we are interested in. */ affect the bits we are interested in. */
......
2015-11-13 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* gcc.target/aarch64/umaddl_combine_1.c: New test.
2015-11-13 Richard Sandiford <richard.sandiford@arm.com> 2015-11-13 Richard Sandiford <richard.sandiford@arm.com>
PR tree-optimization/68264 PR tree-optimization/68264
......
/* { dg-do compile } */
/* { dg-options "-O2 -mcpu=cortex-a53" } */
enum reg_class
{
NO_REGS,
AD_REGS,
ALL_REGS, LIM_REG_CLASSES
};
extern enum reg_class
reg_class_subclasses[((int) LIM_REG_CLASSES)][((int) LIM_REG_CLASSES)];
void
init_reg_sets_1 (unsigned int i)
{
unsigned int j;
{
for (j = i + 1; j < ((int) LIM_REG_CLASSES); j++)
{
enum reg_class *p;
p = &reg_class_subclasses[j][0];
while (*p != LIM_REG_CLASSES)
p++;
}
}
}
/* { dg-final { scan-assembler-not "umull\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment