From de008ec4d69a5f7e9b75b25dc9e1fa937d65ff80 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 30 Mar 2017 15:29:28 +0200 Subject: [PATCH] re PR target/80206 (ICE in extract_insn, at recog.c:2327) PR target/80206 * config/i386/sse.md (_vextract_mask): Use register as dest whenever it is a MEM not rtx_equal_p to the corresponding dup operand, and when forcing into reg move the reg into the memory afterwards. (_vextract_mask): Likewise. Use instead of for the force_reg mode. (avx512vl_vextractf128): Use register as dest either always when a MEM, or when it is a MEM not rtx_equal_p to the corresponding dup operand, or even not when it is a CONST_VECTOR depending on the mode and lo vs. hi. (avx512dq_vextract64x2_1_maskm): Remove extraneous parens. (avx512f_vextract32x4_1_maskm): Likewise. (avx512dq_vextract64x2_1): Likewise. Require that operands[2] is even. (avx512f_vextract32x4_1): Remove extraneous parens. Require that operands[2] is a multiple of 4. (vec_extract_lo_): Don't bother testing if operands[0] is a MEM if , the predicates/constraints disallow memory then. * gcc.target/i386/pr80206.c: New test. From-SVN: r246588 --- gcc/ChangeLog | 27 +++++++++ gcc/config/i386/sse.md | 73 ++++++++++++++++--------- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.target/i386/pr80206.c | 14 +++++ 4 files changed, 93 insertions(+), 26 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr80206.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3333bfd1468..99256af1cff 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,30 @@ +2017-03-30 Jakub Jelinek + + PR target/80206 + * config/i386/sse.md + (_vextract_mask): Use + register as dest whenever it is a MEM not rtx_equal_p to the + corresponding dup operand, and when forcing into reg move the + reg into the memory afterwards. + (_vextract_mask): + Likewise. Use instead of + for the force_reg mode. + (avx512vl_vextractf128): Use register as dest either + always when a MEM, or when it is a MEM not rtx_equal_p to the + corresponding dup operand, or even not when it is a CONST_VECTOR + depending on the mode and lo vs. hi. + (avx512dq_vextract64x2_1_maskm): Remove extraneous + parens. + (avx512f_vextract32x4_1_maskm): Likewise. + (avx512dq_vextract64x2_1): + Likewise. Require that operands[2] is even. + (avx512f_vextract32x4_1): + Remove extraneous parens. Require that operands[2] is a multiple + of 4. + (vec_extract_lo_): Don't bother testing if + operands[0] is a MEM if , the predicates/constraints + disallow memory then. + 2017-03-30 Richard Biener PR tree-optimization/77498 diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 5cca4f1d4fd..0ea06c5aa53 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -7135,19 +7135,22 @@ { int mask; mask = INTVAL (operands[2]); + rtx dest = operands[0]; - if (MEM_P (operands[0]) && GET_CODE (operands[3]) == CONST_VECTOR) - operands[0] = force_reg (mode, operands[0]); + if (MEM_P (operands[0]) && !rtx_equal_p (operands[0], operands[3])) + dest = gen_reg_rtx (mode); if (mode == V16SImode || mode == V16SFmode) - emit_insn (gen_avx512f_vextract32x4_1_mask (operands[0], + emit_insn (gen_avx512f_vextract32x4_1_mask (dest, operands[1], GEN_INT (mask * 4), GEN_INT (mask * 4 + 1), GEN_INT (mask * 4 + 2), GEN_INT (mask * 4 + 3), operands[3], operands[4])); else - emit_insn (gen_avx512dq_vextract64x2_1_mask (operands[0], + emit_insn (gen_avx512dq_vextract64x2_1_mask (dest, operands[1], GEN_INT (mask * 2), GEN_INT (mask * 2 + 1), operands[3], operands[4])); + if (dest != operands[0]) + emit_move_insn (operands[0], dest); DONE; }) @@ -7161,8 +7164,8 @@ (match_operand: 4 "memory_operand" "0") (match_operand:QI 5 "register_operand" "Yk")))] "TARGET_AVX512DQ - && (INTVAL (operands[2]) % 2 == 0) - && (INTVAL (operands[2]) == INTVAL (operands[3]) - 1) + && INTVAL (operands[2]) % 2 == 0 + && INTVAL (operands[2]) == INTVAL (operands[3]) - 1 && rtx_equal_p (operands[4], operands[0])" { operands[2] = GEN_INT ((INTVAL (operands[2])) >> 1); @@ -7187,13 +7190,13 @@ (match_operand: 6 "memory_operand" "0") (match_operand:QI 7 "register_operand" "Yk")))] "TARGET_AVX512F - && ((INTVAL (operands[2]) % 4 == 0) - && INTVAL (operands[2]) == (INTVAL (operands[3]) - 1) - && INTVAL (operands[3]) == (INTVAL (operands[4]) - 1) - && INTVAL (operands[4]) == (INTVAL (operands[5]) - 1)) + && INTVAL (operands[2]) % 4 == 0 + && INTVAL (operands[2]) == INTVAL (operands[3]) - 1 + && INTVAL (operands[3]) == INTVAL (operands[4]) - 1 + && INTVAL (operands[4]) == INTVAL (operands[5]) - 1 && rtx_equal_p (operands[6], operands[0])" { - operands[2] = GEN_INT ((INTVAL (operands[2])) >> 2); + operands[2] = GEN_INT (INTVAL (operands[2]) >> 2); return "vextract32x4\t{%2, %1, %0%{%7%}|%0%{%7%}, %1, %2}"; } [(set_attr "type" "sselog") @@ -7209,9 +7212,11 @@ (match_operand:V8FI 1 "register_operand" "v") (parallel [(match_operand 2 "const_0_to_7_operand") (match_operand 3 "const_0_to_7_operand")])))] - "TARGET_AVX512DQ && (INTVAL (operands[2]) == INTVAL (operands[3]) - 1)" + "TARGET_AVX512DQ + && INTVAL (operands[2]) % 2 == 0 + && INTVAL (operands[2]) == INTVAL (operands[3]) - 1" { - operands[2] = GEN_INT ((INTVAL (operands[2])) >> 1); + operands[2] = GEN_INT (INTVAL (operands[2]) >> 1); return "vextract64x2\t{%2, %1, %0|%0, %1, %2}"; } [(set_attr "type" "sselog1") @@ -7229,11 +7234,12 @@ (match_operand 4 "const_0_to_15_operand") (match_operand 5 "const_0_to_15_operand")])))] "TARGET_AVX512F - && (INTVAL (operands[2]) == (INTVAL (operands[3]) - 1) - && INTVAL (operands[3]) == (INTVAL (operands[4]) - 1) - && INTVAL (operands[4]) == (INTVAL (operands[5]) - 1))" + && INTVAL (operands[2]) % 4 == 0 + && INTVAL (operands[2]) == INTVAL (operands[3]) - 1 + && INTVAL (operands[3]) == INTVAL (operands[4]) - 1 + && INTVAL (operands[4]) == INTVAL (operands[5]) - 1" { - operands[2] = GEN_INT ((INTVAL (operands[2])) >> 2); + operands[2] = GEN_INT (INTVAL (operands[2]) >> 2); return "vextract32x4\t{%2, %1, %0|%0, %1, %2}"; } [(set_attr "type" "sselog1") @@ -7260,9 +7266,10 @@ "TARGET_AVX512F" { rtx (*insn)(rtx, rtx, rtx, rtx); + rtx dest = operands[0]; - if (MEM_P (operands[0]) && GET_CODE (operands[3]) == CONST_VECTOR) - operands[0] = force_reg (mode, operands[0]); + if (MEM_P (dest) && !rtx_equal_p (dest, operands[3])) + dest = gen_reg_rtx (mode); switch (INTVAL (operands[2])) { @@ -7276,7 +7283,9 @@ gcc_unreachable (); } - emit_insn (insn (operands[0], operands[1], operands[3], operands[4])); + emit_insn (insn (dest, operands[1], operands[3], operands[4])); + if (dest != operands[0]) + emit_move_insn (operands[0], dest); DONE; }) @@ -7317,7 +7326,8 @@ (match_operand:V8FI 1 "nonimmediate_operand" "v,m") (parallel [(const_int 0) (const_int 1) (const_int 2) (const_int 3)])))] - "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "TARGET_AVX512F + && ( || !(MEM_P (operands[0]) && MEM_P (operands[1])))" { if ( || !TARGET_AVX512VL) return "vextract64x4\t{$0x0, %1, %0|%0, %1, 0x0}"; @@ -7411,10 +7421,19 @@ "TARGET_AVX512DQ && TARGET_AVX512VL" { rtx (*insn)(rtx, rtx, rtx, rtx); - - if (MEM_P (operands[0]) && GET_CODE (operands[3]) == CONST_VECTOR) - operands[0] = force_reg (mode, operands[0]); - + rtx dest = operands[0]; + + if (MEM_P (dest) + && (GET_MODE_SIZE (GET_MODE_INNER (mode)) == 4 + /* For V8S[IF]mode there are maskm insns with =m and 0 + constraints. */ + ? !rtx_equal_p (dest, operands[3]) + /* For V4D[IF]mode, hi insns don't allow memory, and + lo insns have =m and 0C constraints. */ + : (operands[2] != const0_rtx + || (!rtx_equal_p (dest, operands[3]) + && GET_CODE (operands[3]) != CONST_VECTOR)))) + dest = gen_reg_rtx (mode); switch (INTVAL (operands[2])) { case 0: @@ -7427,7 +7446,9 @@ gcc_unreachable (); } - emit_insn (insn (operands[0], operands[1], operands[3], operands[4])); + emit_insn (insn (dest, operands[1], operands[3], operands[4])); + if (dest != operands[0]) + emit_move_insn (operands[0], dest); DONE; }) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5d33ce78b67..c1b6566033a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-03-30 Jakub Jelinek + + PR target/80206 + * gcc.target/i386/pr80206.c: New test. + 2017-03-30 Richard Biener PR tree-optimization/77498 diff --git a/gcc/testsuite/gcc.target/i386/pr80206.c b/gcc/testsuite/gcc.target/i386/pr80206.c new file mode 100644 index 00000000000..dafa9a6cd7d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr80206.c @@ -0,0 +1,14 @@ +/* PR target/80206 */ +/* { dg-do compile } */ +/* { dg-options "-mavx512f -ffloat-store" } */ + +#include + +__m512d a; +__m256d b; + +void +foo (__m256d *p) +{ + *p = _mm512_mask_extractf64x4_pd (b, 1, a, 1); +} -- 2.30.2