summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff options
context:
space:
mode:
authorSilviu Baranga <silviu.baranga@arm.com>2015-09-10 10:34:34 +0000
committerSilviu Baranga <silviu.baranga@arm.com>2015-09-10 10:34:34 +0000
commitdf9ce8408a2ca784856032f0a2e32022430e5fec (patch)
treecff626959ed38008a0986ffa3ba0101148c0d214 /llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
parentd47634d78123c998dd2ae58dbf5ec29ee832b0b4 (diff)
downloadbcm5719-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.cpp36
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)
OpenPOWER on IntegriCloud