summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2017-09-18 22:05:35 +0000
committerSanjay Patel <spatel@rotateright.com>2017-09-18 22:05:35 +0000
commitf31b1a00ea4d2916dfcc0fd476bebdb0fc60ff9f (patch)
tree58b2fbe068da8af4c73d501d153c817d79ce91b0 /llvm/lib/CodeGen
parent1468677cbe9a39a8032a2e3e5363ffe74be96b40 (diff)
downloadbcm5719-llvm-f31b1a00ea4d2916dfcc0fd476bebdb0fc60ff9f.tar.gz
bcm5719-llvm-f31b1a00ea4d2916dfcc0fd476bebdb0fc60ff9f.zip
[DAGCombiner] fold assertzexts separated by trunc
If we have an AssertZext of a truncated value that has already been AssertZext'ed, we can assert on the wider source op to improve the zext-y knowledge: assert (trunc (assert X, i8) to iN), i1 --> trunc (assert X, i1) to iN This moves a fold from being Mips-specific to general combining, and x86 shows improvements. Differential Revision: https://reviews.llvm.org/D37017 llvm-svn: 313577
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp27
1 files changed, 25 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index b69a5f4738c..018ea1b48b8 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -7970,16 +7970,39 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
return SDValue();
}
+// TODO: These transforms should work with AssertSext too.
+// Change the function name, comments, opcode references, and caller.
SDValue DAGCombiner::visitAssertZext(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
- EVT EVT = cast<VTSDNode>(N1)->getVT();
+ EVT AssertVT = cast<VTSDNode>(N1)->getVT();
// fold (assertzext (assertzext x, vt), vt) -> (assertzext x, vt)
if (N0.getOpcode() == ISD::AssertZext &&
- EVT == cast<VTSDNode>(N0.getOperand(1))->getVT())
+ AssertVT == cast<VTSDNode>(N0.getOperand(1))->getVT())
return N0;
+ if (N0.getOpcode() == ISD::TRUNCATE && N0.hasOneUse() &&
+ N0.getOperand(0).getOpcode() == ISD::AssertZext) {
+ // We have an assert, truncate, assert sandwich. Make one stronger assert
+ // by asserting on the smallest asserted type to the larger source type.
+ // This eliminates the later assert:
+ // assert (trunc (assert X, i8) to iN), i1 --> trunc (assert X, i1) to iN
+ // assert (trunc (assert X, i1) to iN), i8 --> trunc (assert X, i1) to iN
+ SDValue BigA = N0.getOperand(0);
+ EVT BigA_AssertVT = cast<VTSDNode>(BigA.getOperand(1))->getVT();
+ assert(BigA_AssertVT.bitsLE(N0.getValueType()) &&
+ "Asserting zero/sign-extended bits from a type larger than the "
+ "truncated destination does not provide information");
+
+ SDLoc DL(N);
+ EVT MinAssertVT = AssertVT.bitsLT(BigA_AssertVT) ? AssertVT : BigA_AssertVT;
+ SDValue MinAssertVTVal = DAG.getValueType(MinAssertVT);
+ SDValue NewAssert = DAG.getNode(ISD::AssertZext, DL, BigA.getValueType(),
+ BigA.getOperand(0), MinAssertVTVal);
+ return DAG.getNode(ISD::TRUNCATE, DL, N->getValueType(0), NewAssert);
+ }
+
return SDValue();
}
OpenPOWER on IntegriCloud