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
This commit is contained in:
Chris Lattner 2007-10-13 06:58:48 +00:00
parent f8f7cf3987
commit e33544ce55

View File

@ -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();