Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -18128,6 +18128,9 @@ X86::CondCode X86CC; if (isNullConstant(Op1)) { X86CC = CC == ISD::SETEQ ? X86::COND_E : X86::COND_NE; + } else if (isAllOnesConstant(Op1)) { + // C flag is set for all ones. + X86CC = CC == ISD::SETEQ ? X86::COND_B : X86::COND_AE; } else return SDValue(); Index: test/CodeGen/X86/avx512-mask-op.ll =================================================================== --- test/CodeGen/X86/avx512-mask-op.ll +++ test/CodeGen/X86/avx512-mask-op.ll @@ -2836,3 +2836,82 @@ } declare void @foo() +; Make sure we don't emit a ktest for signed comparisons. +define void @ktest_allones(<16 x i32> %x, <16 x i32> %y) { +; KNL-LABEL: ktest_allones: +; KNL: ## %bb.0: +; KNL-NEXT: pushq %rax +; KNL-NEXT: .cfi_def_cfa_offset 16 +; KNL-NEXT: vporq %zmm1, %zmm0, %zmm0 +; KNL-NEXT: vptestnmd %zmm0, %zmm0, %k0 +; KNL-NEXT: kmovw %k0, %eax +; KNL-NEXT: cmpl $65535, %eax ## imm = 0xFFFF +; KNL-NEXT: je LBB65_2 +; KNL-NEXT: ## %bb.1: ## %bb.1 +; KNL-NEXT: vzeroupper +; KNL-NEXT: callq _foo +; KNL-NEXT: LBB65_2: ## %bb.2 +; KNL-NEXT: popq %rax +; KNL-NEXT: vzeroupper +; KNL-NEXT: retq +; +; SKX-LABEL: ktest_allones: +; SKX: ## %bb.0: +; SKX-NEXT: pushq %rax +; SKX-NEXT: .cfi_def_cfa_offset 16 +; SKX-NEXT: vporq %zmm1, %zmm0, %zmm0 +; SKX-NEXT: vptestnmd %zmm0, %zmm0, %k0 +; SKX-NEXT: ktestw %k0, %k0 +; SKX-NEXT: jb LBB65_2 +; SKX-NEXT: ## %bb.1: ## %bb.1 +; SKX-NEXT: vzeroupper +; SKX-NEXT: callq _foo +; SKX-NEXT: LBB65_2: ## %bb.2 +; SKX-NEXT: popq %rax +; SKX-NEXT: vzeroupper +; SKX-NEXT: retq +; +; AVX512BW-LABEL: ktest_allones: +; AVX512BW: ## %bb.0: +; AVX512BW-NEXT: pushq %rax +; AVX512BW-NEXT: .cfi_def_cfa_offset 16 +; AVX512BW-NEXT: vporq %zmm1, %zmm0, %zmm0 +; AVX512BW-NEXT: vptestnmd %zmm0, %zmm0, %k0 +; AVX512BW-NEXT: kmovw %k0, %eax +; AVX512BW-NEXT: cmpl $65535, %eax ## imm = 0xFFFF +; AVX512BW-NEXT: je LBB65_2 +; AVX512BW-NEXT: ## %bb.1: ## %bb.1 +; AVX512BW-NEXT: vzeroupper +; AVX512BW-NEXT: callq _foo +; AVX512BW-NEXT: LBB65_2: ## %bb.2 +; AVX512BW-NEXT: popq %rax +; AVX512BW-NEXT: vzeroupper +; AVX512BW-NEXT: retq +; +; AVX512DQ-LABEL: ktest_allones: +; AVX512DQ: ## %bb.0: +; AVX512DQ-NEXT: pushq %rax +; AVX512DQ-NEXT: .cfi_def_cfa_offset 16 +; AVX512DQ-NEXT: vporq %zmm1, %zmm0, %zmm0 +; AVX512DQ-NEXT: vptestnmd %zmm0, %zmm0, %k0 +; AVX512DQ-NEXT: ktestw %k0, %k0 +; AVX512DQ-NEXT: jb LBB65_2 +; AVX512DQ-NEXT: ## %bb.1: ## %bb.1 +; AVX512DQ-NEXT: vzeroupper +; AVX512DQ-NEXT: callq _foo +; AVX512DQ-NEXT: LBB65_2: ## %bb.2 +; AVX512DQ-NEXT: popq %rax +; AVX512DQ-NEXT: vzeroupper +; AVX512DQ-NEXT: retq + %a = icmp eq <16 x i32> %x, zeroinitializer + %b = icmp eq <16 x i32> %y, zeroinitializer + %c = and <16 x i1> %a, %b + %d = bitcast <16 x i1> %c to i16 + %e = icmp eq i16 %d, -1 + br i1 %e, label %bb.2, label %bb.1 +bb.1: + call void @foo() + br label %bb.2 +bb.2: + ret void +}