From 9afb620acffec194d77b531b372e8599a8cb1ebd Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 14 Mar 2019 15:32:34 +0000 Subject: [PATCH] [x86] prevent infinite looping from vselect commutation (PR41066) This is an immediate fix for: https://bugs.llvm.org/show_bug.cgi?id=41066 ...but as noted there and the code comments, we should do better by stubbing this out sooner. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@356158 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelLowering.cpp | 14 ++++++++------ test/CodeGen/X86/avx512-vec-cmp.ll | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index ef6622e41aa..47ebe254b99 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -34559,11 +34559,15 @@ combineVSelectWithAllOnesOrZeros(SDNode *N, SelectionDAG &DAG, assert(CondVT.isVector() && "Vector select expects a vector selector!"); - bool TValIsAllZeros = ISD::isBuildVectorAllZeros(LHS.getNode()); // Check if the first operand is all zeros and Cond type is vXi1. // This situation only applies to avx512. - if (TValIsAllZeros && Subtarget.hasAVX512() && Cond.hasOneUse() && - CondVT.getVectorElementType() == MVT::i1) { + // TODO: Use isNullOrNullSplat() to distinguish constants with undefs? + // TODO: Can we assert that both operands are not zeros (because that should + // get simplified at node creation time)? + bool TValIsAllZeros = ISD::isBuildVectorAllZeros(LHS.getNode()); + bool FValIsAllZeros = ISD::isBuildVectorAllZeros(RHS.getNode()); + if (TValIsAllZeros && !FValIsAllZeros && Subtarget.hasAVX512() && + Cond.hasOneUse() && CondVT.getVectorElementType() == MVT::i1) { // Invert the cond to not(cond) : xor(op,allones)=not(op) SDValue CondNew = DAG.getNOT(DL, Cond, CondVT); // Vselect cond, op1, op2 = Vselect not(cond), op2, op1 @@ -34578,11 +34582,9 @@ combineVSelectWithAllOnesOrZeros(SDNode *N, SelectionDAG &DAG, if (CondVT.getScalarSizeInBits() != VT.getScalarSizeInBits()) return SDValue(); - bool TValIsAllOnes = ISD::isBuildVectorAllOnes(LHS.getNode()); - bool FValIsAllZeros = ISD::isBuildVectorAllZeros(RHS.getNode()); - // Try to invert the condition if true value is not all 1s and false value is // not all 0s. Only do this if the condition has one use. + bool TValIsAllOnes = ISD::isBuildVectorAllOnes(LHS.getNode()); if (!TValIsAllOnes && !FValIsAllZeros && Cond.hasOneUse() && // Check if the selector will be produced by CMPP*/PCMP*. Cond.getOpcode() == ISD::SETCC && diff --git a/test/CodeGen/X86/avx512-vec-cmp.ll b/test/CodeGen/X86/avx512-vec-cmp.ll index cae7d418f91..2040ccc92c7 100644 --- a/test/CodeGen/X86/avx512-vec-cmp.ll +++ b/test/CodeGen/X86/avx512-vec-cmp.ll @@ -1108,3 +1108,22 @@ define i16 @pcmpeq_mem_2(<16 x i32> %a, <16 x i32>* %b) { %cast = bitcast <16 x i1> %cmp to i16 ret i16 %cast } + +; Don't let a degenerate case trigger an infinite loop. +; This should get simplified before it even exists as a vselect node, +; but that does not happen as of this change. + +define <2 x i64> @PR41066(<2 x i64> %t0, <2 x double> %x, <2 x double> %y) { +; AVX512-LABEL: PR41066: +; AVX512: ## %bb.0: +; AVX512-NEXT: vxorps %xmm0, %xmm0, %xmm0 ## encoding: [0xc5,0xf8,0x57,0xc0] +; AVX512-NEXT: retq ## encoding: [0xc3] +; +; SKX-LABEL: PR41066: +; SKX: ## %bb.0: +; SKX-NEXT: vxorps %xmm0, %xmm0, %xmm0 ## EVEX TO VEX Compression encoding: [0xc5,0xf8,0x57,0xc0] +; SKX-NEXT: retq ## encoding: [0xc3] + %t1 = fcmp ogt <2 x double> %x, %y + %t2 = select <2 x i1> %t1, <2 x i64> , <2 x i64> zeroinitializer + ret <2 x i64> %t2 +} -- 2.50.1