diff options
author | Chris Lattner <sabre@nondot.org> | 2007-10-13 06:58:48 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-10-13 06:58:48 +0000 |
commit | e33544ce55ca18e6e9c90ab7a4de85c90f907258 (patch) | |
tree | 50fbe0d49ef52c7caa4feeeb2b52b545c1329d53 /lib/CodeGen/SelectionDAG/DAGCombiner.cpp | |
parent | f8f7cf398768dc6be39cb6ca2ec7f8c125c8882f (diff) |
Enhance the truncstore optimization code to handle shifted
values and propagate demanded bits through them in simple cases.
This allows this code:
void foo(char *P) {
strcpy(P, "abc");
}
to compile to:
_foo:
ldrb r3, [r1]
ldrb r2, [r1, #+1]
ldrb r12, [r1, #+2]!
ldrb r1, [r1, #+1]
strb r1, [r0, #+3]
strb r2, [r0, #+1]
strb r12, [r0, #+2]
strb r3, [r0]
bx lr
instead of:
_foo:
ldrb r3, [r1, #+3]
ldrb r2, [r1, #+2]
orr r3, r2, r3, lsl #8
ldrb r2, [r1, #+1]
ldrb r1, [r1]
orr r2, r1, r2, lsl #8
orr r3, r2, r3, lsl #16
strb r3, [r0]
mov r2, r3, lsr #24
strb r2, [r0, #+3]
mov r2, r3, lsr #16
strb r2, [r0, #+2]
mov r3, r3, lsr #8
strb r3, [r0, #+1]
bx lr
testcase here: test/CodeGen/ARM/truncstore-dag-combine.ll
This also helps occasionally for X86 and other cases not involving
unaligned load/stores.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42954 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index ced48166da..4d813a0cb4 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -156,10 +156,10 @@ namespace { /// SimplifyDemandedBits - Check the specified integer node value to see if /// it can be simplified or if things it uses can be simplified by bit /// propagation. If so, return true. - bool SimplifyDemandedBits(SDOperand Op) { + bool SimplifyDemandedBits(SDOperand Op, uint64_t Demanded = ~0ULL) { TargetLowering::TargetLoweringOpt TLO(DAG); uint64_t KnownZero, KnownOne; - uint64_t Demanded = MVT::getIntVTBitMask(Op.getValueType()); + Demanded &= MVT::getIntVTBitMask(Op.getValueType()); if (!TLI.SimplifyDemandedBits(Op, Demanded, KnownZero, KnownOne, TLO)) return false; @@ -2809,6 +2809,20 @@ SDOperand DAGCombiner::GetDemandedBits(SDOperand V, uint64_t Mask) { if (DAG.MaskedValueIsZero(V.getOperand(1), Mask)) return V.getOperand(0); break; + case ISD::SRL: + // Only look at single-use SRLs. + if (!V.Val->hasOneUse()) + break; + if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(V.getOperand(1))) { + // See if we can recursively simplify the LHS. + unsigned Amt = RHSC->getValue(); + Mask = (Mask << Amt) & MVT::getIntVTBitMask(V.getValueType()); + SDOperand SimplifyLHS = GetDemandedBits(V.getOperand(0), Mask); + if (SimplifyLHS.Val) { + return DAG.getNode(ISD::SRL, V.getValueType(), + SimplifyLHS, V.getOperand(1)); + } + } } return SDOperand(); } @@ -4040,6 +4054,11 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) { return DAG.getTruncStore(Chain, Shorter, Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->getStoredVT(), ST->isVolatile(), ST->getAlignment()); + + // Otherwise, see if we can simplify the operation with + // SimplifyDemandedBits, which only works if the value has a single use. + if (SimplifyDemandedBits(Value, MVT::getIntVTBitMask(ST->getStoredVT()))) + return SDOperand(N, 0); } return SDOperand(); |