summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2018-12-05 17:10:30 +0000
committerSanjay Patel <spatel@rotateright.com>2018-12-05 17:10:30 +0000
commit33a448f935286de94f00a631277340b8c471a4c0 (patch)
treee2e7d43a7319b3f76fd5cd98080c4d1f90973e8b /llvm/lib/CodeGen/SelectionDAG
parent12e3a8af81da5f55381a47fada6f76a63ca735ce (diff)
downloadbcm5719-llvm-33a448f935286de94f00a631277340b8c471a4c0.tar.gz
bcm5719-llvm-33a448f935286de94f00a631277340b8c471a4c0.zip
[DAGCombiner] don't try to extract a fraction of a vector binop and crash (PR39893)
Because we're potentially peeking through a bitcast in this transform, we need to use overall bitwidths rather than number of elements to determine when it's safe to proceed. Should fix: https://bugs.llvm.org/show_bug.cgi?id=39893 llvm-svn: 348383
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp24
1 files changed, 14 insertions, 10 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index b6be6d1dfc5..326b08d60ce 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -16660,29 +16660,33 @@ static SDValue narrowExtractedVectorBinOp(SDNode *Extract, SelectionDAG &DAG) {
if (!ISD::isBinaryOp(BinOp.getNode()))
return SDValue();
- // The binop must be a vector type, so we can chop it in half.
+ // The binop must be a vector type, so we can extract some fraction of it.
EVT WideBVT = BinOp.getValueType();
if (!WideBVT.isVector())
return SDValue();
EVT VT = Extract->getValueType(0);
- unsigned NumElems = VT.getVectorNumElements();
unsigned ExtractIndex = ExtractIndexC->getZExtValue();
- assert(ExtractIndex % NumElems == 0 &&
+ assert(ExtractIndex % VT.getVectorNumElements() == 0 &&
"Extract index is not a multiple of the vector length.");
- EVT SrcVT = Extract->getOperand(0).getValueType();
// Bail out if this is not a proper multiple width extraction.
- unsigned NumSrcElems = SrcVT.getVectorNumElements();
- if (NumSrcElems % NumElems != 0)
+ unsigned WideWidth = WideBVT.getSizeInBits();
+ unsigned NarrowWidth = VT.getSizeInBits();
+ if (WideWidth % NarrowWidth != 0)
return SDValue();
- // Bail out if the target does not support a narrower version of the binop.
- unsigned NarrowingRatio = NumSrcElems / NumElems;
- unsigned BOpcode = BinOp.getOpcode();
+ // Bail out if we are extracting a fraction of a single operation. This can
+ // occur because we potentially looked through a bitcast of the binop.
+ unsigned NarrowingRatio = WideWidth / NarrowWidth;
unsigned WideNumElts = WideBVT.getVectorNumElements();
+ if (WideNumElts % NarrowingRatio != 0)
+ return SDValue();
+
+ // Bail out if the target does not support a narrower version of the binop.
EVT NarrowBVT = EVT::getVectorVT(*DAG.getContext(), WideBVT.getScalarType(),
WideNumElts / NarrowingRatio);
+ unsigned BOpcode = BinOp.getOpcode();
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
if (!TLI.isOperationLegalOrCustomOrPromote(BOpcode, NarrowBVT))
return SDValue();
@@ -16691,7 +16695,7 @@ static SDValue narrowExtractedVectorBinOp(SDNode *Extract, SelectionDAG &DAG) {
// for concat ops. The narrow binop alone makes this transform profitable.
// We can't just reuse the original extract index operand because we may have
// bitcasted.
- unsigned ConcatOpNum = ExtractIndex / NumElems;
+ unsigned ConcatOpNum = ExtractIndex / VT.getVectorNumElements();
unsigned ExtBOIdx = ConcatOpNum * NarrowBVT.getVectorNumElements();
EVT ExtBOIdxVT = Extract->getOperand(1).getValueType();
if (TLI.isExtractSubvectorCheap(NarrowBVT, WideBVT, ExtBOIdx) &&
OpenPOWER on IntegriCloud