Using UNSPEC for vector compare to mask register.
authorliuhongt <hongtao.liu@intel.com>
Mon, 20 Jul 2020 02:13:58 +0000 (10:13 +0800)
committerliuhongt <hongtao.liu@intel.com>
Mon, 10 Aug 2020 02:28:08 +0000 (10:28 +0800)
For rtx like (eq:HI (V8SI 90) (V8SI 91)), cse will take it as a
boolean value and try to do some optimization. But it is not true for
vector compare, also other places in rtl passes hold the same
assumption.

2020-07-20  Hongtao Liu  <hongtao.liu@intel.com>

gcc/
PR target/96243
* config/i386/i386-expand.c (ix86_expand_sse_cmp): Refine for
maskcmp.
(ix86_expand_mask_vec_cmp): Change prototype.
* config/i386/i386-protos.h (ix86_expand_mask_vec_cmp): Change prototype.
* config/i386/i386.c (ix86_print_operand): Remove operand
modifier 'I'.
* config/i386/sse.md
(*<avx512>_cmp<mode>3<mask_scalar_merge_name><round_saeonly_name>): Deleted.
(*<avx512>_cmp<mode>3<mask_scalar_merge_name>): Ditto.
(*<avx512>_ucmp<mode>3<mask_scalar_merge_name>): Ditto.
(*<avx512>_ucmp<mode>3<mask_scalar_merge_name>,
avx512f_maskcmp<mode>3): Ditto.

gcc/testsuite
* gcc.target/i386/pr92865-1.c: Adjust testcase.

gcc/config/i386/i386-expand.c
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/i386/sse.md
gcc/testsuite/gcc.target/i386/pr92865-1.c

index e194214804b041c12b1682d7b5b8a585278b29ac..1bd0df4daf460ee5fa963a555b244c23363833b1 100644 (file)
@@ -3480,6 +3480,13 @@ ix86_expand_sse_cmp (rtx dest, enum rtx_code code, rtx cmp_op0, rtx cmp_op1,
       || (op_false && reg_overlap_mentioned_p (dest, op_false)))
     dest = gen_reg_rtx (maskcmp ? cmp_mode : mode);
 
+  if (maskcmp)
+    {
+      bool ok = ix86_expand_mask_vec_cmp (dest, code, cmp_op0, cmp_op1);
+      gcc_assert (ok);
+      return dest;
+    }
+
   x = gen_rtx_fmt_ee (code, cmp_mode, cmp_op0, cmp_op1);
 
   if (cmp_mode != mode && !maskcmp)
@@ -3915,11 +3922,10 @@ ix86_cmp_code_to_pcmp_immediate (enum rtx_code code, machine_mode mode)
 /* Expand AVX-512 vector comparison.  */
 
 bool
-ix86_expand_mask_vec_cmp (rtx operands[])
+ix86_expand_mask_vec_cmp (rtx dest, enum rtx_code code, rtx cmp_op0, rtx cmp_op1)
 {
-  machine_mode mask_mode = GET_MODE (operands[0]);
-  machine_mode cmp_mode = GET_MODE (operands[2]);
-  enum rtx_code code = GET_CODE (operands[1]);
+  machine_mode mask_mode = GET_MODE (dest);
+  machine_mode cmp_mode = GET_MODE (cmp_op0);
   rtx imm = GEN_INT (ix86_cmp_code_to_pcmp_immediate (code, cmp_mode));
   int unspec_code;
   rtx unspec;
@@ -3937,10 +3943,9 @@ ix86_expand_mask_vec_cmp (rtx operands[])
       unspec_code = UNSPEC_PCMP;
     }
 
-  unspec = gen_rtx_UNSPEC (mask_mode, gen_rtvec (3, operands[2],
-                                                operands[3], imm),
+  unspec = gen_rtx_UNSPEC (mask_mode, gen_rtvec (3, cmp_op0, cmp_op1, imm),
                           unspec_code);
-  emit_insn (gen_rtx_SET (operands[0], unspec));
+  emit_insn (gen_rtx_SET (dest, unspec));
 
   return true;
 }
index 0b95c57b1a0f3133de1aa2c50b85b614c26e20b2..b6088f22d55908378bcacef77dea6ab0e284cc45 100644 (file)
@@ -143,7 +143,7 @@ extern bool ix86_expand_fp_movcc (rtx[]);
 extern bool ix86_expand_fp_vcond (rtx[]);
 extern bool ix86_expand_int_vcond (rtx[]);
 extern void ix86_expand_vec_perm (rtx[]);
-extern bool ix86_expand_mask_vec_cmp (rtx[]);
+extern bool ix86_expand_mask_vec_cmp (rtx, enum rtx_code, rtx, rtx);
 extern bool ix86_expand_int_vec_cmp (rtx[]);
 extern bool ix86_expand_fp_vec_cmp (rtx[]);
 extern void ix86_expand_sse_movcc (rtx, rtx, rtx, rtx);
index 8ea6a4d7ea7ad184942283da3036b274a793ab04..10eb2dda3c7666b2de1af6ddf22b2bcdb5442010 100644 (file)
@@ -12409,7 +12409,6 @@ print_reg (rtx x, int code, FILE *file)
    M -- print addr32 prefix for TARGET_X32 with VSIB address.
    ! -- print NOTRACK prefix for jxx/call/ret instructions if required.
    N -- print maskz if it's constant 0 operand.
-   I -- print comparision predicate operand for sse cmp condition.
  */
 
 void
@@ -12639,40 +12638,6 @@ ix86_print_operand (FILE *file, rtx x, int code)
            }
          return;
 
-       case 'I':
-         if (ASSEMBLER_DIALECT == ASM_ATT)
-           putc ('$', file);
-         switch (GET_CODE (x))
-           {
-           case EQ:
-             putc ('0', file);
-             break;
-           case NE:
-             putc ('4', file);
-             break;
-           case GE:
-           case GEU:
-             putc ('5', file);
-             break;
-           case GT:
-           case GTU:
-             putc ('6', file);
-             break;
-           case LE:
-           case LEU:
-             putc ('2', file);
-             break;
-           case LT:
-           case LTU:
-             putc ('1', file);
-             break;
-           default:
-             output_operand_lossage ("operand is not a condition code, "
-                                     "invalid operand code 'I'");
-             return;
-           }
-         return;
-
        case 'Y':
          switch (GET_CODE (x))
            {
index b6348de67cb7dcd4da852a89ccf0029ce031dd15..ad8169f6f08ef28d56c721ec2d524726f34aa863 100644 (file)
    (set_attr "prefix" "evex")
    (set_attr "mode" "<sseinsnmode>")])
 
-(define_insn "*<avx512>_cmp<mode>3<mask_scalar_merge_name><round_saeonly_name>"
-  [(set (match_operand:<avx512fmaskmode> 0 "register_operand" "=k")
-       (match_operator:<avx512fmaskmode> 3 "ix86_comparison_int_operator"
-         [(match_operand:VI48_AVX512VL 1 "register_operand" "v")
-          (match_operand:VI48_AVX512VL 2 "nonimmediate_operand" "<round_saeonly_constraint>")]))]
-  "TARGET_AVX512F && <round_saeonly_mode512bit_condition>"
-  "vpcmp<ssemodesuffix>\t{%I3, <round_saeonly_mask_scalar_merge_op4>%2, %1, %0<mask_scalar_merge_operand4>|%0<mask_scalar_merge_operand4>, %1, %2<round_saeonly_mask_scalar_merge_op4>, %I3}"
-  [(set_attr "type" "ssecmp")
-   (set_attr "length_immediate" "1")
-   (set_attr "prefix" "evex")
-   (set_attr "mode" "<sseinsnmode>")])
-
 (define_insn "<avx512>_cmp<mode>3<mask_scalar_merge_name>"
   [(set (match_operand:<avx512fmaskmode> 0 "register_operand" "=k")
        (unspec:<avx512fmaskmode>
    (set_attr "prefix" "evex")
    (set_attr "mode" "<sseinsnmode>")])
 
-(define_insn "*<avx512>_cmp<mode>3<mask_scalar_merge_name>"
-  [(set (match_operand:<avx512fmaskmode> 0 "register_operand" "=k")
-       (match_operator:<avx512fmaskmode> 3 "ix86_comparison_int_operator"
-         [(match_operand:VI12_AVX512VL 1 "register_operand" "v")
-          (match_operand:VI12_AVX512VL 2 "nonimmediate_operand" "vm")]))]
-  "TARGET_AVX512BW"
-  "vpcmp<ssemodesuffix>\t{%I3, %2, %1, %0<mask_scalar_merge_operand4>|%0<mask_scalar_merge_operand4>, %1, %2, %I3}"
-  [(set_attr "type" "ssecmp")
-   (set_attr "length_immediate" "1")
-   (set_attr "prefix" "evex")
-   (set_attr "mode" "<sseinsnmode>")])
-
 (define_insn "<avx512>_ucmp<mode>3<mask_scalar_merge_name>"
   [(set (match_operand:<avx512fmaskmode> 0 "register_operand" "=k")
        (unspec:<avx512fmaskmode>
    (set_attr "prefix" "evex")
    (set_attr "mode" "<sseinsnmode>")])
 
-(define_insn "*<avx512>_ucmp<mode>3<mask_scalar_merge_name>"
-  [(set (match_operand:<avx512fmaskmode> 0 "register_operand" "=k")
-       (match_operator:<avx512fmaskmode> 3 "ix86_comparison_uns_operator"
-         [(match_operand:VI12_AVX512VL 1 "register_operand" "v")
-          (match_operand:VI12_AVX512VL 2 "nonimmediate_operand" "vm")]))]
-  "TARGET_AVX512BW"
-  "vpcmpu<ssemodesuffix>\t{%I3, %2, %1, %0<mask_scalar_merge_operand4>|%0<mask_scalar_merge_operand4>, %1, %2, %I3}"
-  [(set_attr "type" "ssecmp")
-   (set_attr "length_immediate" "1")
-   (set_attr "prefix" "evex")
-   (set_attr "mode" "<sseinsnmode>")])
-
 (define_insn "<avx512>_ucmp<mode>3<mask_scalar_merge_name>"
   [(set (match_operand:<avx512fmaskmode> 0 "register_operand" "=k")
        (unspec:<avx512fmaskmode>
    (set_attr "prefix" "evex")
    (set_attr "mode" "<sseinsnmode>")])
 
-(define_insn "*<avx512>_ucmp<mode>3<mask_scalar_merge_name>"
-  [(set (match_operand:<avx512fmaskmode> 0 "register_operand" "=k")
-       (match_operator:<avx512fmaskmode> 3 "ix86_comparison_uns_operator"
-         [(match_operand:VI48_AVX512VL 1 "register_operand" "v")
-          (match_operand:VI48_AVX512VL 2 "nonimmediate_operand" "vm")]))]
-  "TARGET_AVX512F"
-  "vpcmpu<ssemodesuffix>\t{%I3, %2, %1, %0<mask_scalar_merge_operand4>|%0<mask_scalar_merge_operand4>, %1, %2, %I3}"
-  [(set_attr "type" "ssecmp")
-   (set_attr "length_immediate" "1")
-   (set_attr "prefix" "evex")
-   (set_attr "mode" "<sseinsnmode>")])
-
 (define_insn "avx512f_vmcmp<mode>3<round_saeonly_name>"
   [(set (match_operand:<avx512fmaskmode> 0 "register_operand" "=k")
        (and:<avx512fmaskmode>
    (set_attr "prefix" "evex")
    (set_attr "mode" "<ssescalarmode>")])
 
-(define_insn "avx512f_maskcmp<mode>3"
-  [(set (match_operand:<avx512fmaskmode> 0 "register_operand" "=k")
-       (match_operator:<avx512fmaskmode> 3 "sse_comparison_operator"
-         [(match_operand:VF_AVX512VL 1 "register_operand" "v")
-          (match_operand:VF_AVX512VL 2 "nonimmediate_operand" "vm")]))]
-  "TARGET_AVX512F"
-  "vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
-  [(set_attr "type" "ssecmp")
-   (set_attr "length_immediate" "1")
-   (set_attr "prefix" "evex")
-   (set_attr "mode" "<sseinsnmode>")])
-
 (define_insn "<sse>_<unord>comi<round_saeonly_name>"
   [(set (reg:CCFP FLAGS_REG)
        (compare:CCFP
           (match_operand:V48_AVX512VL 3 "nonimmediate_operand")]))]
   "TARGET_AVX512F"
 {
-  bool ok = ix86_expand_mask_vec_cmp (operands);
+  bool ok = ix86_expand_mask_vec_cmp (operands[0], GET_CODE (operands[1]),
+                                     operands[2], operands[3]);
   gcc_assert (ok);
   DONE;
 })
           (match_operand:VI12_AVX512VL 3 "nonimmediate_operand")]))]
   "TARGET_AVX512BW"
 {
-  bool ok = ix86_expand_mask_vec_cmp (operands);
+  bool ok = ix86_expand_mask_vec_cmp (operands[0], GET_CODE (operands[1]),
+                                     operands[2], operands[3]);
   gcc_assert (ok);
   DONE;
 })
           (match_operand:VI48_AVX512VL 3 "nonimmediate_operand")]))]
   "TARGET_AVX512F"
 {
-  bool ok = ix86_expand_mask_vec_cmp (operands);
+  bool ok = ix86_expand_mask_vec_cmp (operands[0], GET_CODE (operands[1]),
+                                     operands[2], operands[3]);
   gcc_assert (ok);
   DONE;
 })
           (match_operand:VI12_AVX512VL 3 "nonimmediate_operand")]))]
   "TARGET_AVX512BW"
 {
-  bool ok = ix86_expand_mask_vec_cmp (operands);
+  bool ok = ix86_expand_mask_vec_cmp (operands[0], GET_CODE (operands[1]),
+                                     operands[2], operands[3]);
   gcc_assert (ok);
   DONE;
 })
index 49b5778a067fb93db939876a75a1c7e81ea67e96..8aeab6086264a1a528eb8254e7d5f14d4e4a746d 100644 (file)
@@ -1,12 +1,12 @@
 /* PR target/92865 */
 /* { dg-do compile } */
-/* { dg-options "-Ofast -mavx512f -mavx512bw -mxop" } */
+/* { dg-options "-Ofast -mavx512bw -mxop" } */
 /* { dg-final { scan-assembler-times "vpcmp\[bwdq\]\[\t ]" 4 } } */
 /* { dg-final { scan-assembler-times "vpcmpu\[bwdq\]\[\t ]" 4 } } */
-/* { dg-final { scan-assembler-times "vmovdq\[au\]8\[\t ]" 4 } } */
-/* { dg-final { scan-assembler-times "vmovdq\[au\]16\[\t ]" 4 } } *
-/* { dg-final { scan-assembler-times "vmovdq\[au\]32\[\t ]" 4 } } */
-/* { dg-final { scan-assembler-times "vmovdq\[au\]64\[\t ]" 4 } } */
+/* { dg-final { scan-assembler-times "vmovdq\[au\]8\[\t ]" 6 } } */
+/* { dg-final { scan-assembler-times "vmovdq\[au\]16\[\t ]" 6 } } *
+/* { dg-final { scan-assembler-times "vmovdq\[au\]32\[\t ]" 6 } } */
+/* { dg-final { scan-assembler-times "vmovdq\[au\]64\[\t ]" 6 } } */
 
 extern char arraysb[64];
 extern short arraysw[32];