Hi!

REE breaks the following testcase on KNL, where we only accept
QImode/HImode in k0-k7 registers (SImode/DImode is only supported
with -mavx512bw).  We have
(set (reg:HI k0) (mem:HI ...))
...
(set (reg:DI rax) (zero_extend:DI (reg:HI k0)))
and we optimize it into:
(set (reg:DI rax) (zero_extend:DI (mem:HI ...)))
(set (reg:DI k0) (reg:DI rax))
The first insn is fine, but the latter is not really valid, kmovq
is only avx512bw, only kmovw is avx512f.

Fixed by consulting HARD_REGNO_MODE_OK in addition to comparing
HARD_REGNO_NREGS.

This change affects just
gcc.target/i386/{avx512{f,dq}-pr77476.c,avx512f-klogic-2.c,pr78132.c}
testcases, in all cases it is about k0 or k1 register and SImode or DImode.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2016-10-27  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/78132
        * ree.c (combine_reaching_defs): Give up if copy_needed and
        !HARD_REGNO_MODE_OK (REGNO (src_reg), dst_mode).

        * gcc.target/i386/pr78132.c: New test.

--- gcc/ree.c.jj        2016-10-21 11:36:33.000000000 +0200
+++ gcc/ree.c   2016-10-27 18:43:00.899215537 +0200
@@ -788,6 +788,11 @@ combine_reaching_defs (ext_cand *cand, c
       machine_mode dst_mode = GET_MODE (SET_DEST (PATTERN (cand->insn)));
       rtx src_reg = get_extended_src_reg (SET_SRC (PATTERN (cand->insn)));
 
+      /* Ensure we can use the src_reg in dst_mode (needed for
+        the (set (reg1) (reg2)) insn mentioned above).  */
+      if (!HARD_REGNO_MODE_OK (REGNO (src_reg), dst_mode))
+       return false;
+
       /* Ensure the number of hard registers of the copy match.  */
       if (HARD_REGNO_NREGS (REGNO (src_reg), dst_mode)
          != HARD_REGNO_NREGS (REGNO (src_reg), GET_MODE (src_reg)))
--- gcc/testsuite/gcc.target/i386/pr78132.c.jj  2016-10-27 18:48:25.944128889 
+0200
+++ gcc/testsuite/gcc.target/i386/pr78132.c     2016-10-27 18:48:53.538781368 
+0200
@@ -0,0 +1,20 @@
+/* PR rtl-optimization/78132 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -mavx512f -mno-avx512bw -mno-avx512dq -masm=att" } */
+/* { dg-final { scan-assembler-not "kmov\[dq]\t" } } */
+
+unsigned short c;
+char a, d, f, b;
+short e;
+long g;
+
+int
+main ()
+{
+  g = c;
+  f = c & e;
+  d = c & a | e;
+  if (a)
+    b = c;
+  return 0;
+}

        Jakub

Reply via email to