diff options
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 30 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 30 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 2 |
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)); |