summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-01-17 19:59:44 +0000
committerChris Lattner <sabre@nondot.org>2008-01-17 19:59:44 +0000
commit1ea55cf8166d46b1518b83dce5c14f1e175ac03c (patch)
tree46a8c6da33bec80d1103e03cebcd48438c1acd71 /llvm/lib/CodeGen
parent9f7fed1c1bd315e291a49dbe815baf3bd7d1c0a0 (diff)
downloadbcm5719-llvm-1ea55cf8166d46b1518b83dce5c14f1e175ac03c.tar.gz
bcm5719-llvm-1ea55cf8166d46b1518b83dce5c14f1e175ac03c.zip
This commit changes:
1. Legalize now always promotes truncstore of i1 to i8. 2. Remove patterns and gunk related to truncstore i1 from targets. 3. Rename the StoreXAction stuff to TruncStoreAction in TLI. 4. Make the TLI TruncStoreAction table a 2d table to handle from/to conversions. 5. Mark a wide variety of invalid truncstores as such in various targets, e.g. X86 currently doesn't support truncstore of any of its integer types. 6. Add legalize support for truncstores with invalid value input types. 7. Add a dag combine transform to turn store(truncate) into truncstore when safe. The later allows us to compile CodeGen/X86/storetrunc-fp.ll to: _foo: fldt 20(%esp) fldt 4(%esp) faddp %st(1) movl 36(%esp), %eax fstps (%eax) ret instead of: _foo: subl $4, %esp fldt 24(%esp) fldt 8(%esp) faddp %st(1) fstps (%esp) movl 40(%esp), %eax movss (%esp), %xmm0 movss %xmm0, (%eax) addl $4, %esp ret llvm-svn: 46140
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp30
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp30
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp2
3 files changed, 40 insertions, 22 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index d7a92293213..879a4100e21 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -1690,8 +1690,7 @@ SDOperand DAGCombiner::visitAND(SDNode *N) {
if (N1C && N0.getOpcode() == ISD::LOAD) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
if (LN0->getExtensionType() != ISD::SEXTLOAD &&
- LN0->getAddressingMode() == ISD::UNINDEXED &&
- N0.hasOneUse()) {
+ LN0->isUnindexed() && N0.hasOneUse()) {
MVT::ValueType EVT, LoadedVT;
if (N1C->getValue() == 255)
EVT = MVT::i8;
@@ -3810,7 +3809,7 @@ bool DAGCombiner::CombineToPreIndexedLoadStore(SDNode *N) {
SDOperand Ptr;
MVT::ValueType VT;
if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
- if (LD->getAddressingMode() != ISD::UNINDEXED)
+ if (LD->isIndexed())
return false;
VT = LD->getLoadedVT();
if (!TLI.isIndexedLoadLegal(ISD::PRE_INC, VT) &&
@@ -3818,7 +3817,7 @@ bool DAGCombiner::CombineToPreIndexedLoadStore(SDNode *N) {
return false;
Ptr = LD->getBasePtr();
} else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
- if (ST->getAddressingMode() != ISD::UNINDEXED)
+ if (ST->isIndexed())
return false;
VT = ST->getStoredVT();
if (!TLI.isIndexedStoreLegal(ISD::PRE_INC, VT) &&
@@ -3937,7 +3936,7 @@ bool DAGCombiner::CombineToPostIndexedLoadStore(SDNode *N) {
SDOperand Ptr;
MVT::ValueType VT;
if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
- if (LD->getAddressingMode() != ISD::UNINDEXED)
+ if (LD->isIndexed())
return false;
VT = LD->getLoadedVT();
if (!TLI.isIndexedLoadLegal(ISD::POST_INC, VT) &&
@@ -3945,7 +3944,7 @@ bool DAGCombiner::CombineToPostIndexedLoadStore(SDNode *N) {
return false;
Ptr = LD->getBasePtr();
} else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
- if (ST->getAddressingMode() != ISD::UNINDEXED)
+ if (ST->isIndexed())
return false;
VT = ST->getStoredVT();
if (!TLI.isIndexedStoreLegal(ISD::POST_INC, VT) &&
@@ -4187,7 +4186,7 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) {
// If this is a store of a bit convert, store the input value if the
// resultant store does not need a higher alignment than the original.
if (Value.getOpcode() == ISD::BIT_CONVERT && !ST->isTruncatingStore() &&
- ST->getAddressingMode() == ISD::UNINDEXED) {
+ ST->isUnindexed()) {
unsigned Align = ST->getAlignment();
MVT::ValueType SVT = Value.getOperand(0).getValueType();
unsigned OrigAlign = TLI.getTargetMachine().getTargetData()->
@@ -4285,7 +4284,7 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) {
return SDOperand(N, 0);
// FIXME: is there such a thing as a truncating indexed store?
- if (ST->isTruncatingStore() && ST->getAddressingMode() == ISD::UNINDEXED &&
+ if (ST->isTruncatingStore() && ST->isUnindexed() &&
MVT::isInteger(Value.getValueType())) {
// See if we can simplify the input to this truncstore with knowledge that
// only the low bits are being used. For example:
@@ -4308,8 +4307,7 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) {
// is dead/noop.
if (LoadSDNode *Ld = dyn_cast<LoadSDNode>(Value)) {
if (Ld->getBasePtr() == Ptr && ST->getStoredVT() == Ld->getLoadedVT() &&
- ST->getAddressingMode() == ISD::UNINDEXED &&
- !ST->isVolatile() &&
+ ST->isUnindexed() && !ST->isVolatile() &&
// There can't be any side effects between the load and store, such as
// a call or store.
Chain.reachesChainWithoutSideEffects(SDOperand(Ld, 1))) {
@@ -4318,6 +4316,18 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) {
}
}
+ // If this is an FP_ROUND or TRUNC followed by a store, fold this into a
+ // truncating store. We can do this even if this is already a truncstore.
+ if ((Value.getOpcode() == ISD::FP_ROUND || Value.getOpcode() == ISD::TRUNCATE)
+ && TLI.isTypeLegal(Value.getOperand(0).getValueType()) &&
+ Value.Val->hasOneUse() && ST->isUnindexed() &&
+ TLI.isTruncStoreLegal(Value.getOperand(0).getValueType(),
+ ST->getStoredVT())) {
+ return DAG.getTruncStore(Chain, Value.getOperand(0), Ptr, ST->getSrcValue(),
+ ST->getSrcValueOffset(), ST->getStoredVT(),
+ ST->isVolatile(), ST->getAlignment());
+ }
+
return SDOperand();
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 18d3a6d55a8..8d7c85ce936 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -2239,15 +2239,24 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
break;
}
} else {
- // Truncating store
- assert(isTypeLegal(ST->getValue().getValueType()) &&
- "Cannot handle illegal TRUNCSTORE yet!");
- Tmp3 = LegalizeOp(ST->getValue());
+ switch (getTypeAction(ST->getValue().getValueType())) {
+ case Legal:
+ Tmp3 = LegalizeOp(ST->getValue());
+ break;
+ case Promote:
+ // We can promote the value, the truncstore will still take care of it.
+ Tmp3 = PromoteOp(ST->getValue());
+ break;
+ case Expand:
+ // Just store the low part. This may become a non-trunc store, so make
+ // sure to use getTruncStore, not UpdateNodeOperands below.
+ ExpandOp(ST->getValue(), Tmp3, Tmp4);
+ return DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+ SVOffset, MVT::i8, isVolatile, Alignment);
+ }
- // The only promote case we handle is TRUNCSTORE:i1 X into
- // -> TRUNCSTORE:i8 (and X, 1)
- if (ST->getStoredVT() == MVT::i1 &&
- TLI.getStoreXAction(MVT::i1) == TargetLowering::Promote) {
+ // Unconditionally promote TRUNCSTORE:i1 X -> TRUNCSTORE:i8 (and X, 1)
+ if (ST->getStoredVT() == MVT::i1) {
// Promote the bool to a mask then store.
Tmp3 = DAG.getNode(ISD::AND, Tmp3.getValueType(), Tmp3,
DAG.getConstant(1, Tmp3.getValueType()));
@@ -2261,7 +2270,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
}
MVT::ValueType StVT = cast<StoreSDNode>(Result.Val)->getStoredVT();
- switch (TLI.getStoreXAction(StVT)) {
+ switch (TLI.getTruncStoreAction(ST->getValue().getValueType(), StVT)) {
default: assert(0 && "This action is not supported yet!");
case TargetLowering::Legal:
// If this is an unaligned store and the target doesn't support it,
@@ -2275,8 +2284,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
}
break;
case TargetLowering::Custom:
- Tmp1 = TLI.LowerOperation(Result, DAG);
- if (Tmp1.Val) Result = Tmp1;
+ Result = TLI.LowerOperation(Result, DAG);
break;
}
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index cb12b7c7329..8e7e87dd294 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -158,7 +158,7 @@ TargetLowering::TargetLowering(TargetMachine &tm)
// All operations default to being supported.
memset(OpActions, 0, sizeof(OpActions));
memset(LoadXActions, 0, sizeof(LoadXActions));
- memset(&StoreXActions, 0, sizeof(StoreXActions));
+ memset(TruncStoreActions, 0, sizeof(TruncStoreActions));
memset(&IndexedModeActions, 0, sizeof(IndexedModeActions));
memset(&ConvertActions, 0, sizeof(ConvertActions));
OpenPOWER on IntegriCloud