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