From: Kyrylo Tkachov Date: Fri, 13 Nov 2015 15:12:26 +0000 (+0000) Subject: [combine] Don't transform sign and zero extends inside mults X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e5b2900e37366b5da63c85c2005e33158817bd60;p=gcc.git [combine] Don't transform sign and zero extends inside mults 2015-11-13 Segher Boessenkool Kyrylo Tkachov * 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 18d0fdb2353..4d6165ecda5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-11-13 Segher Boessenkool + Kyrylo Tkachov + + * combine.c (subst): Don't substitute or simplify when + handling register-wise widening multiply. + (force_to_mode): Likewise. + 2015-11-13 Richard Sandiford PR tree-optimization/68264 diff --git a/gcc/combine.c b/gcc/combine.c index c3db2e0adf6..2a66fd5c8bd 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a29b65181a8..10a2c808d19 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-11-13 Kyrylo Tkachov + + * gcc.target/aarch64/umaddl_combine_1.c: New test. + 2015-11-13 Richard Sandiford PR tree-optimization/68264 diff --git a/gcc/testsuite/gcc.target/aarch64/umaddl_combine_1.c b/gcc/testsuite/gcc.target/aarch64/umaddl_combine_1.c new file mode 100644 index 00000000000..430277f1187 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/umaddl_combine_1.c @@ -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\]+" } } */