mirror of git://gcc.gnu.org/git/gcc.git
[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
This commit is contained in:
parent
dd3c1b14af
commit
e5b2900e37
|
|
@ -1,3 +1,10 @@
|
|||
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>
|
||||
|
||||
PR tree-optimization/68264
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
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
|
||||
constant. */
|
||||
if (fmt[0] == 'e')
|
||||
|
|
@ -8455,6 +8471,17 @@ force_to_mode (rtx x, machine_mode mode, unsigned HOST_WIDE_INT mask,
|
|||
/* ... fall through ... */
|
||||
|
||||
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
|
||||
most significant bit in MASK since carries from those bits will
|
||||
affect the bits we are interested in. */
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
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>
|
||||
|
||||
PR tree-optimization/68264
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
/* { 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 = ®_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\]+" } } */
|
||||
Loading…
Reference in New Issue