rtx tmp;
/* Handle special case - vector comparsion with boolean result, transform
- it using ptest instruction. */
+ it using ptest instruction or vpcmpeq + kortest. */
if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
|| (mode == TImode && !TARGET_64BIT)
- || mode == OImode)
+ || mode == OImode
+ || GET_MODE_SIZE (mode) == 64)
{
- rtx flag = gen_rtx_REG (CCZmode, FLAGS_REG);
- machine_mode p_mode = GET_MODE_SIZE (mode) == 32 ? V4DImode : V2DImode;
+ unsigned msize = GET_MODE_SIZE (mode);
+ machine_mode p_mode
+ = msize == 64 ? V16SImode : msize == 32 ? V4DImode : V2DImode;
+ /* kortest set CF when result is 0xFFFF (op0 == op1). */
+ rtx flag = gen_rtx_REG (msize == 64 ? CCCmode : CCZmode, FLAGS_REG);
gcc_assert (code == EQ || code == NE);
- if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
+ /* Using vpcmpeq zmm zmm k + kortest for 512-bit vectors. */
+ if (msize == 64)
{
- op0 = lowpart_subreg (p_mode, force_reg (mode, op0), mode);
- op1 = lowpart_subreg (p_mode, force_reg (mode, op1), mode);
- mode = p_mode;
+ if (mode != V16SImode)
+ {
+ op0 = lowpart_subreg (p_mode, force_reg (mode, op0), mode);
+ op1 = lowpart_subreg (p_mode, force_reg (mode, op1), mode);
+ }
+
+ tmp = gen_reg_rtx (HImode);
+ emit_insn (gen_avx512f_cmpv16si3 (tmp, op0, op1, GEN_INT (0)));
+ emit_insn (gen_kortesthi_ccc (tmp, tmp));
+ }
+ /* Using ptest for 128/256-bit vectors. */
+ else
+ {
+ if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
+ {
+ op0 = lowpart_subreg (p_mode, force_reg (mode, op0), mode);
+ op1 = lowpart_subreg (p_mode, force_reg (mode, op1), mode);
+ mode = p_mode;
+ }
+
+ /* Generate XOR since we can't check that one operand is zero
+ vector. */
+ tmp = gen_reg_rtx (mode);
+ emit_insn (gen_rtx_SET (tmp, gen_rtx_XOR (mode, op0, op1)));
+ tmp = gen_lowpart (p_mode, tmp);
+ emit_insn (gen_rtx_SET (gen_rtx_REG (CCZmode, FLAGS_REG),
+ gen_rtx_UNSPEC (CCZmode,
+ gen_rtvec (2, tmp, tmp),
+ UNSPEC_PTEST)));
}
- /* Generate XOR since we can't check that one operand is zero vector. */
- tmp = gen_reg_rtx (mode);
- emit_insn (gen_rtx_SET (tmp, gen_rtx_XOR (mode, op0, op1)));
- tmp = gen_lowpart (p_mode, tmp);
- emit_insn (gen_rtx_SET (gen_rtx_REG (CCZmode, FLAGS_REG),
- gen_rtx_UNSPEC (CCZmode,
- gen_rtvec (2, tmp, tmp),
- UNSPEC_PTEST)));
tmp = gen_rtx_fmt_ee (code, VOIDmode, flag, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode, label),
DONE;
})
+(define_expand "cbranchxi4"
+ [(set (reg:CC FLAGS_REG)
+ (compare:CC (match_operand:XI 1 "nonimmediate_operand")
+ (match_operand:XI 2 "nonimmediate_operand")))
+ (set (pc) (if_then_else
+ (match_operator 0 "bt_comparison_operator"
+ [(reg:CC FLAGS_REG) (const_int 0)])
+ (label_ref (match_operand 3))
+ (pc)))]
+ "TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256"
+{
+ ix86_expand_branch (GET_CODE (operands[0]),
+ operands[1], operands[2], operands[3]);
+ DONE;
+})
+
(define_expand "cstore<mode>4"
[(set (reg:CC FLAGS_REG)
(compare:CC (match_operand:SDWIM 2 "nonimmediate_operand")
(set_attr "type" "msklog")
(set_attr "prefix" "vex")])
-(define_insn "kortest<mode>"
- [(set (reg:CC FLAGS_REG)
- (unspec:CC
+(define_insn "*kortest<mode>"
+ [(set (reg FLAGS_REG)
+ (unspec
[(match_operand:SWI1248_AVX512BWDQ 0 "register_operand" "k")
(match_operand:SWI1248_AVX512BWDQ 1 "register_operand" "k")]
UNSPEC_KORTEST))]
(set_attr "type" "msklog")
(set_attr "prefix" "vex")])
+(define_insn "kortest<mode>_ccc"
+ [(set (reg:CCC FLAGS_REG)
+ (unspec:CCC
+ [(match_operand:SWI1248_AVX512BWDQ 0 "register_operand")
+ (match_operand:SWI1248_AVX512BWDQ 1 "register_operand")]
+ UNSPEC_KORTEST))]
+ "TARGET_AVX512F")
+
+(define_insn "kortest<mode>_ccz"
+ [(set (reg:CCZ FLAGS_REG)
+ (unspec:CCZ
+ [(match_operand:SWI1248_AVX512BWDQ 0 "register_operand")
+ (match_operand:SWI1248_AVX512BWDQ 1 "register_operand")]
+ UNSPEC_KORTEST))]
+ "TARGET_AVX512F")
+
+(define_expand "kortest<mode>"
+ [(set (reg:CC FLAGS_REG)
+ (unspec:CC
+ [(match_operand:SWI1248_AVX512BWDQ 0 "register_operand")
+ (match_operand:SWI1248_AVX512BWDQ 1 "register_operand")]
+ UNSPEC_KORTEST))]
+ "TARGET_AVX512F")
+
(define_insn "kunpckhi"
[(set (match_operand:HI 0 "register_operand" "=k")
(ior:HI
(define_expand "cbranch<mode>4"
[(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:VI48_AVX 1 "register_operand")
- (match_operand:VI48_AVX 2 "nonimmediate_operand")))
+ (compare:CC (match_operand:VI48_AVX_AVX512F 1 "register_operand")
+ (match_operand:VI48_AVX_AVX512F 2 "nonimmediate_operand")))
(set (pc) (if_then_else
(match_operator 0 "bt_comparison_operator"
[(reg:CC FLAGS_REG) (const_int 0)])
(label_ref (match_operand 3))
(pc)))]
- "TARGET_SSE4_1"
+ "TARGET_SSE4_1 && (<MODE_SIZE> != 64 || !TARGET_PREFER_AVX256)"
{
ix86_expand_branch (GET_CODE (operands[0]),
operands[1], operands[2], operands[3]);