diff options
author | Silviu Baranga <silviu.baranga@arm.com> | 2015-09-10 10:34:34 +0000 |
---|---|---|
committer | Silviu Baranga <silviu.baranga@arm.com> | 2015-09-10 10:34:34 +0000 |
commit | df9ce8408a2ca784856032f0a2e32022430e5fec (patch) | |
tree | cff626959ed38008a0986ffa3ba0101148c0d214 /llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | |
parent | d47634d78123c998dd2ae58dbf5ec29ee832b0b4 (diff) | |
download | bcm5719-llvm-df9ce8408a2ca784856032f0a2e32022430e5fec.tar.gz bcm5719-llvm-df9ce8408a2ca784856032f0a2e32022430e5fec.zip |
[DAGCombine] Truncate BUILD_VECTOR operators if necessary when constant folding vectors
Summary:
The BUILD_VECTOR node will truncate its operators to match the
type. We need to take this into account when constant folding -
we need to perform a truncation before constant folding the elements.
This is because the upper bits can change the result, depending on
the operation type (for example this is the case for min/max).
This change also adds a regression test.
Reviewers: jmolloy
Subscribers: jmolloy, llvm-commits
Differential Revision: http://reviews.llvm.org/D12697
llvm-svn: 247265
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 755edee1c6c..f81da723e69 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -13325,20 +13325,34 @@ SDValue DAGCombiner::SimplifyVBinOp(SDNode *N) { EVT VT = LHSOp.getValueType(); EVT RVT = RHSOp.getValueType(); - if (RVT != VT) { - // Integer BUILD_VECTOR operands may have types larger than the element - // size (e.g., when the element type is not legal). Prior to type - // legalization, the types may not match between the two BUILD_VECTORS. - // Truncate one of the operands to make them match. - if (RVT.getSizeInBits() > VT.getSizeInBits()) { - RHSOp = DAG.getNode(ISD::TRUNCATE, SDLoc(N), VT, RHSOp); - } else { - LHSOp = DAG.getNode(ISD::TRUNCATE, SDLoc(N), RVT, LHSOp); - VT = RVT; - } + EVT ST = VT; + + if (RVT.getSizeInBits() < VT.getSizeInBits()) + ST = RVT; + + // Integer BUILD_VECTOR operands may have types larger than the element + // size (e.g., when the element type is not legal). Prior to type + // legalization, the types may not match between the two BUILD_VECTORS. + // Truncate the operands to make them match. + if (VT.getSizeInBits() != LHS.getValueType().getScalarSizeInBits()) { + EVT ScalarT = LHS.getValueType().getScalarType(); + LHSOp = DAG.getNode(ISD::TRUNCATE, SDLoc(N), ScalarT, LHSOp); + VT = LHSOp.getValueType(); } + if (RVT.getSizeInBits() != RHS.getValueType().getScalarSizeInBits()) { + EVT ScalarT = RHS.getValueType().getScalarType(); + RHSOp = DAG.getNode(ISD::TRUNCATE, SDLoc(N), ScalarT, RHSOp); + RVT = RHSOp.getValueType(); + } + SDValue FoldOp = DAG.getNode(N->getOpcode(), SDLoc(LHS), VT, LHSOp, RHSOp); + + // We need the resulting constant to be legal if we are in a phase after + // legalization, so zero extend to the smallest operand type if required. + if (ST != VT && Level != BeforeLegalizeTypes) + FoldOp = DAG.getNode(ISD::ANY_EXTEND, SDLoc(LHS), ST, FoldOp); + if (FoldOp.getOpcode() != ISD::UNDEF && FoldOp.getOpcode() != ISD::Constant && FoldOp.getOpcode() != ISD::ConstantFP) |