forked from OSchip/llvm-project
[DAGCombiner] Distribute TRUNC through AND in rotation amount
This is already done for shifts. Allow it for rotations as well. E.g.: (rotl:i32 x, (trunc (and y, 31))) -> (rotl:i32 x, (and (trunc y), 31)) Use the newly factored-out distributeTruncateThroughAnd. With this patch and some X86.td tweaks we should be able to remove redundant masking of the rotation amount like in the example above. HW implicitly performs this masking. The testcase will be added as part of the X86 patch. llvm-svn: 203316
This commit is contained in:
parent
5117f5dffc
commit
7f928f14f4
|
@ -229,6 +229,7 @@ namespace {
|
||||||
SDValue visitSHL(SDNode *N);
|
SDValue visitSHL(SDNode *N);
|
||||||
SDValue visitSRA(SDNode *N);
|
SDValue visitSRA(SDNode *N);
|
||||||
SDValue visitSRL(SDNode *N);
|
SDValue visitSRL(SDNode *N);
|
||||||
|
SDValue visitRotate(SDNode *N);
|
||||||
SDValue visitCTLZ(SDNode *N);
|
SDValue visitCTLZ(SDNode *N);
|
||||||
SDValue visitCTLZ_ZERO_UNDEF(SDNode *N);
|
SDValue visitCTLZ_ZERO_UNDEF(SDNode *N);
|
||||||
SDValue visitCTTZ(SDNode *N);
|
SDValue visitCTTZ(SDNode *N);
|
||||||
|
@ -1194,6 +1195,8 @@ SDValue DAGCombiner::visit(SDNode *N) {
|
||||||
case ISD::SHL: return visitSHL(N);
|
case ISD::SHL: return visitSHL(N);
|
||||||
case ISD::SRA: return visitSRA(N);
|
case ISD::SRA: return visitSRA(N);
|
||||||
case ISD::SRL: return visitSRL(N);
|
case ISD::SRL: return visitSRL(N);
|
||||||
|
case ISD::ROTR:
|
||||||
|
case ISD::ROTL: return visitRotate(N);
|
||||||
case ISD::CTLZ: return visitCTLZ(N);
|
case ISD::CTLZ: return visitCTLZ(N);
|
||||||
case ISD::CTLZ_ZERO_UNDEF: return visitCTLZ_ZERO_UNDEF(N);
|
case ISD::CTLZ_ZERO_UNDEF: return visitCTLZ_ZERO_UNDEF(N);
|
||||||
case ISD::CTTZ: return visitCTTZ(N);
|
case ISD::CTTZ: return visitCTTZ(N);
|
||||||
|
@ -3899,6 +3902,19 @@ SDValue DAGCombiner::distributeTruncateThroughAnd(SDNode *N) {
|
||||||
|
|
||||||
return SDValue();
|
return SDValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDValue DAGCombiner::visitRotate(SDNode *N) {
|
||||||
|
// fold (rot* x, (trunc (and y, c))) -> (rot* x, (and (trunc y), (trunc c))).
|
||||||
|
if (N->getOperand(1).getOpcode() == ISD::TRUNCATE &&
|
||||||
|
N->getOperand(1).getOperand(0).getOpcode() == ISD::AND) {
|
||||||
|
SDValue NewOp1 = distributeTruncateThroughAnd(N->getOperand(1).getNode());
|
||||||
|
if (NewOp1.getNode())
|
||||||
|
return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0),
|
||||||
|
N->getOperand(0), NewOp1);
|
||||||
|
}
|
||||||
|
return SDValue();
|
||||||
|
}
|
||||||
|
|
||||||
SDValue DAGCombiner::visitSHL(SDNode *N) {
|
SDValue DAGCombiner::visitSHL(SDNode *N) {
|
||||||
SDValue N0 = N->getOperand(0);
|
SDValue N0 = N->getOperand(0);
|
||||||
SDValue N1 = N->getOperand(1);
|
SDValue N1 = N->getOperand(1);
|
||||||
|
|
Loading…
Reference in New Issue