+/// PerformSTORECombine - Do target-specific dag combines on STORE nodes.
+static SDOperand PerformSTORECombine(StoreSDNode *St, SelectionDAG &DAG,
+ const X86Subtarget *Subtarget) {
+ // Turn load->store of MMX types into GPR load/stores. This avoids clobbering
+ // the FP state in cases where an emms may be missing.
+ if (MVT::isVector(St->getValue().getValueType()) &&
+ MVT::getSizeInBits(St->getValue().getValueType()) == 64 &&
+ // Must be a store of a load.
+ isa<LoadSDNode>(St->getChain()) &&
+ St->getChain().Val == St->getValue().Val &&
+ St->getValue().hasOneUse() && St->getChain().hasOneUse() &&
+ !St->isVolatile() && !cast<LoadSDNode>(St->getChain())->isVolatile()) {
+ LoadSDNode *Ld = cast<LoadSDNode>(St->getChain());
+
+ // If we are a 64-bit capable x86, lower to a single movq load/store pair.
+ if (Subtarget->is64Bit()) {
+ SDOperand NewLd = DAG.getLoad(MVT::i64, Ld->getChain(), Ld->getBasePtr(),
+ Ld->getSrcValue(), Ld->getSrcValueOffset(),
+ Ld->isVolatile(), Ld->getAlignment());
+ return DAG.getStore(NewLd.getValue(1), NewLd, St->getBasePtr(),
+ St->getSrcValue(), St->getSrcValueOffset(),
+ St->isVolatile(), St->getAlignment());
+ }
+
+ // TODO: 2 32-bit copies.
+ }
+ return SDOperand();
+}
+