From 1f70cb9c146df188f665e3496a31b34182a00252 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Fri, 29 Aug 2014 13:05:18 +0000 Subject: [PATCH] AArch64: skip select/setcc combine in complex case. In an llvm-stress generated test, we were trying to create a v0iN type and asserting when that failed. This case could probably be handled by the function, but not without added complexity and the situation it arises in is sufficiently odd that there's probably no benefit anyway. Should fix PR20775. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216725 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64ISelLowering.cpp | 18 ++++++++++-------- test/CodeGen/AArch64/cond-sel.ll | 10 ++++++++++ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp index d3ec172c9d4..430938e2f43 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -7994,22 +7994,24 @@ static SDValue performVSelectCombine(SDNode *N, SelectionDAG &DAG) { static SDValue performSelectCombine(SDNode *N, SelectionDAG &DAG) { SDValue N0 = N->getOperand(0); EVT ResVT = N->getValueType(0); + EVT SrcVT = N0.getOperand(0).getValueType(); + int NumMaskElts = ResVT.getSizeInBits() / SrcVT.getSizeInBits(); - if (!N->getOperand(1).getValueType().isVector()) + // If NumMaskElts == 0, the comparison is larger than select result. The + // largest real NEON comparison is 64-bits per lane, which means the result is + // at most 32-bits and an illegal vector. Just bail out for now. + if (!ResVT.isVector() || NumMaskElts == 0) return SDValue(); if (N0.getOpcode() != ISD::SETCC || N0.getValueType() != MVT::i1) return SDValue(); - SDLoc DL(N0); - - EVT SrcVT = N0.getOperand(0).getValueType(); - SrcVT = EVT::getVectorVT(*DAG.getContext(), SrcVT, - ResVT.getSizeInBits() / SrcVT.getSizeInBits()); + SrcVT = EVT::getVectorVT(*DAG.getContext(), SrcVT, NumMaskElts); EVT CCVT = SrcVT.changeVectorElementTypeToInteger(); // First perform a vector comparison, where lane 0 is the one we're interested // in. + SDLoc DL(N0); SDValue LHS = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, SrcVT, N0.getOperand(0)); SDValue RHS = @@ -8019,8 +8021,8 @@ static SDValue performSelectCombine(SDNode *N, SelectionDAG &DAG) { // Now duplicate the comparison mask we want across all other lanes. SmallVector DUPMask(CCVT.getVectorNumElements(), 0); SDValue Mask = DAG.getVectorShuffle(CCVT, DL, SetCC, SetCC, DUPMask.data()); - Mask = DAG.getNode(ISD::BITCAST, DL, ResVT.changeVectorElementTypeToInteger(), - Mask); + Mask = DAG.getNode(ISD::BITCAST, DL, + ResVT.changeVectorElementTypeToInteger(), Mask); return DAG.getSelect(DL, ResVT, Mask, N->getOperand(1), N->getOperand(2)); } diff --git a/test/CodeGen/AArch64/cond-sel.ll b/test/CodeGen/AArch64/cond-sel.ll index 5f81cba66cb..333f2436133 100644 --- a/test/CodeGen/AArch64/cond-sel.ll +++ b/test/CodeGen/AArch64/cond-sel.ll @@ -214,3 +214,13 @@ define void @test_csetm(i32 %lhs, i32 %rhs, i64 %lhs64) { ret void ; CHECK: ret } + +define <1 x i1> @test_wide_comparison(i32 %in) { +; CHECK-LABEL: test_wide_comparison: +; CHECK: cmp w0, #1234 +; CHECK: cset + + %tmp = icmp sgt i32 %in, 1234 + %res = select i1 %tmp, <1 x i1> , <1 x i1> zeroinitializer + ret <1 x i1> %res +} -- 2.11.0