aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorliuhongt <hongtao.liu@intel.com>2020-07-20 10:13:58 +0800
committerGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-17 15:07:52 -0300
commit03b4e861518e65400524aaaefabb7813aba5fdae (patch)
tree18d7aed4905a9d449972b6a11aee3c9bb59c480e
parent4e4cf0e8a6606a8dcba2e08d1e9ec45accf4d15c (diff)
Using UNSPEC for vector compare to mask register.
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.
-rw-r--r--gcc/config/i386/i386-expand.c19
-rw-r--r--gcc/config/i386/i386-protos.h2
-rw-r--r--gcc/config/i386/i386.c35
-rw-r--r--gcc/config/i386/sse.md72
-rw-r--r--gcc/testsuite/gcc.target/i386/pr92865-1.c10
5 files changed, 26 insertions, 112 deletions
diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index e194214804b..1bd0df4daf4 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -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;
}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 0b95c57b1a0..b6088f22d55 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -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);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 8ea6a4d7ea7..10eb2dda3c7 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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))
{
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index b6348de67cb..ad8169f6f08 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -2945,18 +2945,6 @@
(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>
@@ -2971,18 +2959,6 @@
(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>
@@ -2997,18 +2973,6 @@
(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>
@@ -3023,18 +2987,6 @@
(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>
@@ -3069,18 +3021,6 @@
(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
@@ -3108,7 +3048,8 @@
(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;
})
@@ -3120,7 +3061,8 @@
(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;
})
@@ -3192,7 +3134,8 @@
(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;
})
@@ -3204,7 +3147,8 @@
(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;
})
diff --git a/gcc/testsuite/gcc.target/i386/pr92865-1.c b/gcc/testsuite/gcc.target/i386/pr92865-1.c
index 49b5778a067..8aeab608626 100644
--- a/gcc/testsuite/gcc.target/i386/pr92865-1.c
+++ b/gcc/testsuite/gcc.target/i386/pr92865-1.c
@@ -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];