summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2008-07-31 00:50:31 +0000
committerDan Gohman <gohman@apple.com>2008-07-31 00:50:31 +0000
commit75dcf08243d19a40d2e1cc12057bf9c00ca3df3b (patch)
treea4d75e535ab985343409f9d4b9878bbd708d4ee3
parent7030ae7728fb7d5f937f72943d73fc69c4d451c0 (diff)
downloadllvm-75dcf08243d19a40d2e1cc12057bf9c00ca3df3b.tar.gz
llvm-75dcf08243d19a40d2e1cc12057bf9c00ca3df3b.tar.bz2
llvm-75dcf08243d19a40d2e1cc12057bf9c00ca3df3b.tar.xz
Improve dagcombining for sext-loads and sext-in-reg nodes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@54239 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp30
-rw-r--r--test/CodeGen/X86/sext-trunc.ll9
2 files changed, 30 insertions, 9 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 747a0b1e54..d570a1aa91 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -3060,8 +3060,12 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
LN0->isVolatile(),
LN0->getAlignment());
CombineTo(N, ExtLoad);
- CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
- ExtLoad.getValue(1));
+ // Redirect any chain users to the new load.
+ DAG.ReplaceAllUsesOfValueWith(SDValue(LN0, 1), SDValue(ExtLoad.Val, 1));
+ // If any node needs the original loaded value, recompute it.
+ if (!LN0->use_empty())
+ CombineTo(LN0, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
+ ExtLoad.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
}
@@ -3169,17 +3173,16 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) {
// Do not generate loads of non-round integer types since these can
// be expensive (and would be wrong if the type is not byte sized).
- if (ISD::isNON_EXTLoad(N0.Val) && N0.hasOneUse() && VT.isRound() &&
+ if (isa<LoadSDNode>(N0) && N0.hasOneUse() && VT.isRound() &&
+ cast<LoadSDNode>(N0)->getMemoryVT().getSizeInBits() > EVTBits &&
// Do not change the width of a volatile load.
!cast<LoadSDNode>(N0)->isVolatile()) {
- assert(N0.getValueType().getSizeInBits() > EVTBits &&
- "Cannot truncate to larger type!");
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
MVT PtrType = N0.getOperand(1).getValueType();
// For big endian targets, we need to adjust the offset to the pointer to
// load the correct bytes.
if (TLI.isBigEndian()) {
- unsigned LVTStoreBits = N0.getValueType().getStoreSizeInBits();
+ unsigned LVTStoreBits = LN0->getMemoryVT().getStoreSizeInBits();
unsigned EVTStoreBits = EVT.getStoreSizeInBits();
ShAmt = LVTStoreBits - EVTStoreBits - ShAmt;
}
@@ -3190,11 +3193,11 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) {
AddToWorkList(NewPtr.Val);
SDValue Load = (ExtType == ISD::NON_EXTLOAD)
? DAG.getLoad(VT, LN0->getChain(), NewPtr,
- LN0->getSrcValue(), LN0->getSrcValueOffset(),
+ LN0->getSrcValue(), LN0->getSrcValueOffset() + PtrOff,
LN0->isVolatile(), NewAlign)
: DAG.getExtLoad(ExtType, VT, LN0->getChain(), NewPtr,
- LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT,
- LN0->isVolatile(), NewAlign);
+ LN0->getSrcValue(), LN0->getSrcValueOffset() + PtrOff,
+ EVT, LN0->isVolatile(), NewAlign);
AddToWorkList(N);
if (CombineSRL) {
WorkListRemover DeadNodes(*this);
@@ -3238,6 +3241,15 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0.getOperand(0), N1);
}
+ // fold (sext_in_reg (sext x)) -> (sext x)
+ // fold (sext_in_reg (aext x)) -> (sext x)
+ // if x is small enough.
+ if (N0.getOpcode() == ISD::SIGN_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND) {
+ SDValue N00 = N0.getOperand(0);
+ if (N00.getValueType().getSizeInBits() < EVTBits)
+ return DAG.getNode(ISD::SIGN_EXTEND, VT, N00, N1);
+ }
+
// fold (sext_in_reg x) -> (zext_in_reg x) if the sign bit is known zero.
if (DAG.MaskedValueIsZero(N0, APInt::getBitsSet(VTBits, EVTBits-1, EVTBits)))
return DAG.getZeroExtendInReg(N0, EVT);
diff --git a/test/CodeGen/X86/sext-trunc.ll b/test/CodeGen/X86/sext-trunc.ll
new file mode 100644
index 0000000000..97b4666827
--- /dev/null
+++ b/test/CodeGen/X86/sext-trunc.ll
@@ -0,0 +1,9 @@
+; RUN: llvm-as < %s | llc -march=x86 > %t
+; RUN: grep movsbl %t
+; RUN: not grep movz %t
+; RUN: not grep and %t
+
+define i8 @foo(i16 signext %x) signext nounwind {
+ %retval56 = trunc i16 %x to i8
+ ret i8 %retval56
+}