From 0a7c2b2b165ced4861eb1eb6e73ed6ffd457c384 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Thu, 11 Apr 2019 19:57:44 +0000 Subject: [PATCH] [X86] Restrict vselect handling in scalarizeExtEltFP to only case to pre type legalization where the setcc result type is vXi1. If the vector setcc has been legalized then we will need to convert a vector boolean of 0 or -1 to a scalar boolean of 0 or 1. The added test case previously crashed in 32-bit mode by creating a setcc with an i64 condition that type legalization couldn't expand. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358218 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelLowering.cpp | 4 ++++ test/CodeGen/X86/extractelement-fp.ll | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index d62f14b767b..c967329d0dd 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -34555,8 +34555,12 @@ static SDValue scalarizeExtEltFP(SDNode *ExtElt, SelectionDAG &DAG) { // Vector FP selects don't fit the pattern of FP math ops (because the // condition has a different type and we have to change the opcode), so deal // with those here. + // FIXME: This is restricted to pre type legalization by ensuring the setcc + // has i1 elements. If we loosen this we need to convert vector bool to a + // scalar bool. if (Vec.getOpcode() == ISD::VSELECT && Vec.getOperand(0).getOpcode() == ISD::SETCC && + Vec.getOperand(0).getValueType().getScalarType() == MVT::i1 && Vec.getOperand(0).getOperand(0).getValueType() == VecVT) { // ext (sel Cond, X, Y), 0 --> sel (ext Cond, 0), (ext X, 0), (ext Y, 0) SDLoc DL(ExtElt); diff --git a/test/CodeGen/X86/extractelement-fp.ll b/test/CodeGen/X86/extractelement-fp.ll index f25cce89372..9c038ed7026 100644 --- a/test/CodeGen/X86/extractelement-fp.ll +++ b/test/CodeGen/X86/extractelement-fp.ll @@ -313,6 +313,31 @@ define void @extsetcc(<4 x float> %x) { ret void } +; This used to crash by creating a setcc with an i64 condition on a 32-bit target. +define <3 x double> @extvselectsetcc_crash(<2 x double> %x) { +; X64-LABEL: extvselectsetcc_crash: +; X64: # %bb.0: +; X64-NEXT: vcmpeqpd {{.*}}(%rip), %xmm0, %xmm1 +; X64-NEXT: vmovsd {{.*#+}} xmm2 = mem[0],zero +; X64-NEXT: vandpd %xmm2, %xmm1, %xmm1 +; X64-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; X64-NEXT: vpermpd {{.*#+}} ymm0 = ymm0[0,2,3,3] +; X64-NEXT: retq +; +; X86-LABEL: extvselectsetcc_crash: +; X86: # %bb.0: +; X86-NEXT: vcmpeqpd {{\.LCPI.*}}, %xmm0, %xmm1 +; X86-NEXT: vmovsd {{.*#+}} xmm2 = mem[0],zero +; X86-NEXT: vandpd %xmm2, %xmm1, %xmm1 +; X86-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 +; X86-NEXT: vpermpd {{.*#+}} ymm0 = ymm0[0,2,3,3] +; X86-NEXT: retl + %cmp = fcmp oeq <2 x double> %x, + %s = select <2 x i1> %cmp, <2 x double> , <2 x double> + %r = shufflevector <2 x double> %s, <2 x double> %x, <3 x i32> + ret <3 x double> %r +} + define float @select_fcmp_v4f32(<4 x float> %x, <4 x float> %y, <4 x float> %z, <4 x float> %w) nounwind { ; X64-LABEL: select_fcmp_v4f32: ; X64: # %bb.0: -- 2.50.1