diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2017-09-18 22:05:35 +0000 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2017-09-18 22:05:35 +0000 |
| commit | f31b1a00ea4d2916dfcc0fd476bebdb0fc60ff9f (patch) | |
| tree | 58b2fbe068da8af4c73d501d153c817d79ce91b0 /llvm/lib/CodeGen | |
| parent | 1468677cbe9a39a8032a2e3e5363ffe74be96b40 (diff) | |
| download | bcm5719-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.cpp | 27 |
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(); } |

