[combine] Don't transform sign and zero extends inside mults
authorKyrylo Tkachov <ktkachov@gcc.gnu.org>
Fri, 13 Nov 2015 15:12:26 +0000 (15:12 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Fri, 13 Nov 2015 15:12:26 +0000 (15:12 +0000)
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

gcc/ChangeLog
gcc/combine.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/umaddl_combine_1.c [new file with mode: 0644]

index 18d0fdb23530fa5102c7488c5f6421d63120f444..4d6165ecda5def635da54102dea8faaea35f489c 100644 (file)
@@ -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
index c3db2e0adf697b9fd74ef7980dff711e0711ca7d..2a66fd5c8bdf6dbccc407ab3290ee8723bb71448 100644 (file)
@@ -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.  */
index a29b65181a860f5fc2c7ace4c8a44247b777b0af..10a2c808d1988a40c6e47fa32922d3e5d5696f4c 100644 (file)
@@ -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 (file)
index 0000000..430277f
--- /dev/null
@@ -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\]+" } } */