summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp29
1 files changed, 29 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index e92a099753b..37026ce0f12 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -24757,6 +24757,8 @@ static SDValue PerformLOADCombine(SDNode *N, SelectionDAG &DAG,
LoadSDNode *Ld = cast<LoadSDNode>(N);
EVT RegVT = Ld->getValueType(0);
EVT MemVT = Ld->getMemoryVT();
+ SDValue Ptr = Ld->getBasePtr();
+ SDValue Chain = Ld->getChain();
SDLoc dl(Ld);
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
@@ -24795,6 +24797,33 @@ static SDValue PerformLOADCombine(SDNode *N, SelectionDAG &DAG,
return DCI.CombineTo(N, NewVec, TF, true);
}
+ // Conversion from x86mmx/i64 to v2i64 types is often done via stack
+ // store/load. Under certain conditions we can bypass the memory access and
+ // combine this load to use a scalar_to_vector instead. This leads to
+ // a reduction in the stack use, redundant emission of shuffles and create
+ // isel matching candidates for movq2dq instructions.
+ if (RegVT == MVT::v2i64 && Subtarget->hasSSE2() && Ext == ISD::EXTLOAD &&
+ !Ld->isVolatile() && ISD::isNON_TRUNCStore(Chain.getNode())) {
+
+ // If this load is directly stored, get the original source value.
+ StoreSDNode *PrevST = cast<StoreSDNode>(Chain);
+ EVT SrcTy = PrevST->getValue().getValueType();
+ if (PrevST->getBasePtr() != Ptr ||
+ !(SrcTy == MVT::i64 || SrcTy == MVT::x86mmx))
+ return SDValue();
+ SDValue SrcVal = Chain.getOperand(1);
+
+ // On 32bit systems, we can't save 64bit integers, use f64 instead.
+ bool Usef64 = TLI.isTypeLegal(MVT::f64) && !Subtarget->is64Bit();
+ if (Usef64)
+ SrcVal = DAG.getNode(ISD::BITCAST, dl, MVT::f64, SrcVal);
+ SrcVal = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, Usef64 ? MVT::v2f64 : RegVT,
+ SrcVal);
+
+ return DCI.CombineTo(N, Usef64 ?
+ DAG.getNode(ISD::BITCAST, dl, RegVT, SrcVal) : SrcVal, Chain);
+ }
+
return SDValue();
}
OpenPOWER on IntegriCloud