[llvm-commits] [llvm] r58825 - /llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
Dale Johannesen
dalej at apple.com
Thu Nov 6 17:28:02 PST 2008
Author: johannes
Date: Thu Nov 6 19:28:02 2008
New Revision: 58825
URL: http://llvm.org/viewvc/llvm-project?rev=58825&view=rev
Log:
When we're doing a compare of load-AND-constant to 0
(e.g. a bitfield test) narrow the load as much as possible.
The has the potential to avoid unnecessary partial-word
load-after-store conflicts, which cause stalls on several targets.
Also a size win on x86 (testb vs testl).
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=58825&r1=58824&r2=58825&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Thu Nov 6 19:28:02 2008
@@ -1352,6 +1352,52 @@
Zero, Cond);
}
}
+
+ // If the LHS is '(and load, const)', the RHS is 0,
+ // the test is for equality or unsigned, and all 1 bits of the const are
+ // in the same partial word, see if we can shorten the load.
+ if (DCI.isBeforeLegalize() &&
+ N0.getOpcode() == ISD::AND && C1 == 0 &&
+ isa<LoadSDNode>(N0.getOperand(0)) &&
+ N0.getOperand(0).getNode()->hasOneUse() &&
+ isa<ConstantSDNode>(N0.getOperand(1))) {
+ LoadSDNode *Lod = cast<LoadSDNode>(N0.getOperand(0));
+ uint64_t Mask = cast<ConstantSDNode>(N0.getOperand(1))->getZExtValue();
+ unsigned bestWidth = 0, bestOffset = 0;
+ if (!Lod->isVolatile()) {
+ unsigned origWidth = N0.getValueType().getSizeInBits();
+ for (unsigned width = origWidth / 2; width>=8; width /= 2) {
+ uint64_t newMask = (1ULL << width) - 1;
+ for (unsigned offset=0; offset<origWidth/width; offset++) {
+ if ((newMask & Mask)==Mask) {
+ bestOffset = (uint64_t)offset * (width/8);
+ bestWidth = width;
+ break;
+ }
+ newMask = newMask << width;
+ }
+ }
+ }
+ if (bestWidth) {
+ MVT newVT = MVT::getIntegerVT(bestWidth);
+ if (newVT.isRound()) {
+ uint64_t bestMask = Mask >> (bestOffset * 8);
+ MVT PtrType = Lod->getOperand(1).getValueType();
+ SDValue Ptr = Lod->getBasePtr();
+ if (bestOffset != 0)
+ Ptr = DAG.getNode(ISD::ADD, PtrType, Lod->getBasePtr(),
+ DAG.getConstant(bestOffset, PtrType));
+ unsigned NewAlign = MinAlign(Lod->getAlignment(), bestOffset);
+ SDValue NewLoad = DAG.getLoad(newVT, Lod->getChain(), Ptr,
+ Lod->getSrcValue(),
+ Lod->getSrcValueOffset() + bestOffset,
+ false, NewAlign);
+ return DAG.getSetCC(VT, DAG.getNode(ISD::AND, newVT, NewLoad,
+ DAG.getConstant(bestMask, newVT)),
+ DAG.getConstant(0LL, newVT), Cond);
+ }
+ }
+ }
// If the LHS is a ZERO_EXTEND, perform the comparison on the input.
if (N0.getOpcode() == ISD::ZERO_EXTEND) {
More information about the llvm-commits
mailing list