diff options
author | Sanjay Patel <spatel@rotateright.com> | 2018-12-05 17:10:30 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2018-12-05 17:10:30 +0000 |
commit | 33a448f935286de94f00a631277340b8c471a4c0 (patch) | |
tree | e2e7d43a7319b3f76fd5cd98080c4d1f90973e8b /llvm/lib/CodeGen/SelectionDAG | |
parent | 12e3a8af81da5f55381a47fada6f76a63ca735ce (diff) | |
download | bcm5719-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.cpp | 24 |
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) && |