From 93fb1bac674b07134f7de59ba22d3d5acf741637 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Thu, 6 Apr 2023 11:22:36 +0100 Subject: [PATCH] [X86] LowerVectorAllEqual - don't attempt to match comparisons of float data FCMP may use ISD::SETNE when nnan, we don't want to end up with cases where we mismatch signed zeros etc. Thanks to @pengfei for the test case from D147688 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 4 +++ llvm/test/CodeGen/X86/movmsk-cmp.ll | 48 +++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index eb3afd4..dc07a03 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -24352,6 +24352,10 @@ static SDValue LowerVectorAllEqual(const SDLoc &DL, SDValue LHS, SDValue RHS, if (!llvm::has_single_bit(VT.getSizeInBits())) return SDValue(); + // FCMP may use ISD::SETNE when nnan - early out if we manage to get here. + if (VT.isFloatingPoint()) + return SDValue(); + assert((CC == ISD::SETEQ || CC == ISD::SETNE) && "Unsupported ISD::CondCode"); X86CC = (CC == ISD::SETEQ ? X86::COND_E : X86::COND_NE); diff --git a/llvm/test/CodeGen/X86/movmsk-cmp.ll b/llvm/test/CodeGen/X86/movmsk-cmp.ll index 9e0d2a9..e7f9b36 100644 --- a/llvm/test/CodeGen/X86/movmsk-cmp.ll +++ b/llvm/test/CodeGen/X86/movmsk-cmp.ll @@ -3330,6 +3330,54 @@ define i1 @allzeros_v8i64_and4(<8 x i64> %arg) { ret i1 %tmp3 } +; FCMP may use ISD::SETNE when nnan, don't attempt to use LowerVectorAllEqual. +define i1 @allzeros_v8f32_nnan(<8 x float> %a0) { +; SSE-LABEL: allzeros_v8f32_nnan: +; SSE: # %bb.0: +; SSE-NEXT: xorps %xmm2, %xmm2 +; SSE-NEXT: cmpneqps %xmm2, %xmm1 +; SSE-NEXT: cmpneqps %xmm2, %xmm0 +; SSE-NEXT: packssdw %xmm1, %xmm0 +; SSE-NEXT: pmovmskb %xmm0, %eax +; SSE-NEXT: testl %eax, %eax +; SSE-NEXT: setne %al +; SSE-NEXT: retq +; +; AVX1OR2-LABEL: allzeros_v8f32_nnan: +; AVX1OR2: # %bb.0: +; AVX1OR2-NEXT: vxorps %xmm1, %xmm1, %xmm1 +; AVX1OR2-NEXT: vcmpneqps %ymm1, %ymm0, %ymm0 +; AVX1OR2-NEXT: vmovmskps %ymm0, %eax +; AVX1OR2-NEXT: testl %eax, %eax +; AVX1OR2-NEXT: setne %al +; AVX1OR2-NEXT: vzeroupper +; AVX1OR2-NEXT: retq +; +; KNL-LABEL: allzeros_v8f32_nnan: +; KNL: # %bb.0: +; KNL-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0 +; KNL-NEXT: vxorps %xmm1, %xmm1, %xmm1 +; KNL-NEXT: vcmpneqps %zmm1, %zmm0, %k0 +; KNL-NEXT: kmovw %k0, %eax +; KNL-NEXT: testb %al, %al +; KNL-NEXT: setne %al +; KNL-NEXT: vzeroupper +; KNL-NEXT: retq +; +; SKX-LABEL: allzeros_v8f32_nnan: +; SKX: # %bb.0: +; SKX-NEXT: vxorps %xmm1, %xmm1, %xmm1 +; SKX-NEXT: vcmpneqps %ymm1, %ymm0, %k0 +; SKX-NEXT: kortestb %k0, %k0 +; SKX-NEXT: setne %al +; SKX-NEXT: vzeroupper +; SKX-NEXT: retq + %1 = fcmp nnan une <8 x float> %a0, zeroinitializer + %2 = bitcast <8 x i1> %1 to i8 + %3 = icmp ne i8 %2, 0 + ret i1 %3 +} + ; The below are IR patterns that should directly represent the behavior of a ; MOVMSK instruction. -- 2.7.4