mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-19 20:34:38 +00:00
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:
parent
f8f7cf3987
commit
e33544ce55
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user