From e33544ce55ca18e6e9c90ab7a4de85c90f907258 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 13 Oct 2007 06:58:48 +0000 Subject: [PATCH] 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 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index ced48166da3..4d813a0cb4d 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(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(); -- 2.34.1