aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKyrylo Tkachov <ktkachov@gcc.gnu.org>2015-11-13 15:12:26 +0000
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>2015-11-13 15:12:26 +0000
commite5b2900e37366b5da63c85c2005e33158817bd60 (patch)
tree293f945582a8472048901e812fed95ac9e080b60 /gcc
parentdd3c1b14afa954856789c4cb955dec474d799edd (diff)
downloadgcc-e5b2900e37366b5da63c85c2005e33158817bd60.zip
gcc-e5b2900e37366b5da63c85c2005e33158817bd60.tar.gz
gcc-e5b2900e37366b5da63c85c2005e33158817bd60.tar.bz2
[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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/combine.c27
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/umaddl_combine_1.c29
4 files changed, 67 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 18d0fdb..4d6165e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/combine.c b/gcc/combine.c
index c3db2e0..2a66fd5 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 a29b651..10a2c80 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
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 0000000..430277f
--- /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 = &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\]+" } } */