summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2014-08-29 13:05:18 +0000
committerTim Northover <tnorthover@apple.com>2014-08-29 13:05:18 +0000
commitc1c05aeb5dc2b68ff85f0164665f2f2023c1701e (patch)
tree359c2bce1bfe20e77d43f05881db16de62ccd77b
parent73e171f76d7c070d862c139ed438a46c9b5f3f7e (diff)
downloadbcm5719-llvm-c1c05aeb5dc2b68ff85f0164665f2f2023c1701e.tar.gz
bcm5719-llvm-c1c05aeb5dc2b68ff85f0164665f2f2023c1701e.zip
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. llvm-svn: 216725
-rw-r--r--llvm/lib/Target/AArch64/AArch64ISelLowering.cpp18
-rw-r--r--llvm/test/CodeGen/AArch64/cond-sel.ll10
2 files changed, 20 insertions, 8 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index d3ec172c9d4..430938e2f43 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/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<int, 8> 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/llvm/test/CodeGen/AArch64/cond-sel.ll b/llvm/test/CodeGen/AArch64/cond-sel.ll
index 5f81cba66cb..333f2436133 100644
--- a/llvm/test/CodeGen/AArch64/cond-sel.ll
+++ b/llvm/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> <i1 1>, <1 x i1> zeroinitializer
+ ret <1 x i1> %res
+}
OpenPOWER on IntegriCloud