From f9b2b5e67e46ada55ada74580e2939027d6f11eb Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Tue, 13 Nov 2018 08:37:09 +0000 Subject: [SystemZ] Increase the number of VLREPs If a loaded value is replicated it is best to combine these two operations into a VLREP (load and replicate), but isel will not produce this if the load has other users as well. This patch handles this by putting the other users of the load to use the REPLICATE 0-element instead of the load. This way the load has only the REPLICATE node as user, and we get a VLREP. Review: Ulrich Weigand https://reviews.llvm.org/D54264 llvm-svn: 346746 --- llvm/lib/Target/SystemZ/SystemZISelLowering.cpp | 42 +++++++++++++++++++++++++ llvm/lib/Target/SystemZ/SystemZISelLowering.h | 1 + 2 files changed, 43 insertions(+) (limited to 'llvm/lib') diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp index 2aff585f9f3..d7951ca810e 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -523,6 +523,7 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM, setTargetDAGCombine(ISD::ZERO_EXTEND); setTargetDAGCombine(ISD::SIGN_EXTEND); setTargetDAGCombine(ISD::SIGN_EXTEND_INREG); + setTargetDAGCombine(ISD::LOAD); setTargetDAGCombine(ISD::STORE); setTargetDAGCombine(ISD::EXTRACT_VECTOR_ELT); setTargetDAGCombine(ISD::FP_ROUND); @@ -5368,6 +5369,46 @@ SDValue SystemZTargetLowering::combineMERGE( return SDValue(); } +SDValue SystemZTargetLowering::combineLOAD( + SDNode *N, DAGCombinerInfo &DCI) const { + SelectionDAG &DAG = DCI.DAG; + EVT LdVT = N->getValueType(0); + if (LdVT.isVector() || LdVT.isInteger()) + return SDValue(); + // Transform a scalar load that is REPLICATEd as well as having other + // use(s) to the form where the other use(s) use the first element of the + // REPLICATE instead of the load. Otherwise instruction selection will not + // produce a VLREP. Avoid extracting to a GPR, so only do this for floating + // point loads. + + SDValue Replicate; + SmallVector OtherUses; + for (SDNode::use_iterator UI = N->use_begin(), UE = N->use_end(); + UI != UE; ++UI) { + if (UI->getOpcode() == SystemZISD::REPLICATE) { + if (Replicate) + return SDValue(); // Should never happen + Replicate = SDValue(*UI, 0); + } + else if (UI.getUse().getResNo() == 0) + OtherUses.push_back(*UI); + } + if (!Replicate || OtherUses.empty()) + return SDValue(); + + SDLoc DL(N); + SDValue Extract0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, LdVT, + Replicate, DAG.getConstant(0, DL, MVT::i32)); + // Update uses of the loaded Value while preserving old chains. + for (SDNode *U : OtherUses) { + SmallVector Ops; + for (SDValue Op : U->ops()) + Ops.push_back((Op.getNode() == N && Op.getResNo() == 0) ? Extract0 : Op); + DAG.UpdateNodeOperands(U, Ops); + } + return SDValue(N, 0); +} + SDValue SystemZTargetLowering::combineSTORE( SDNode *N, DAGCombinerInfo &DCI) const { SelectionDAG &DAG = DCI.DAG; @@ -5699,6 +5740,7 @@ SDValue SystemZTargetLowering::PerformDAGCombine(SDNode *N, case ISD::SIGN_EXTEND_INREG: return combineSIGN_EXTEND_INREG(N, DCI); case SystemZISD::MERGE_HIGH: case SystemZISD::MERGE_LOW: return combineMERGE(N, DCI); + case ISD::LOAD: return combineLOAD(N, DCI); case ISD::STORE: return combineSTORE(N, DCI); case ISD::EXTRACT_VECTOR_ELT: return combineEXTRACT_VECTOR_ELT(N, DCI); case SystemZISD::JOIN_DWORDS: return combineJOIN_DWORDS(N, DCI); diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h index 9bf94407947..172dbeec26d 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h @@ -587,6 +587,7 @@ private: SDValue combineSIGN_EXTEND(SDNode *N, DAGCombinerInfo &DCI) const; SDValue combineSIGN_EXTEND_INREG(SDNode *N, DAGCombinerInfo &DCI) const; SDValue combineMERGE(SDNode *N, DAGCombinerInfo &DCI) const; + SDValue combineLOAD(SDNode *N, DAGCombinerInfo &DCI) const; SDValue combineSTORE(SDNode *N, DAGCombinerInfo &DCI) const; SDValue combineEXTRACT_VECTOR_ELT(SDNode *N, DAGCombinerInfo &DCI) const; SDValue combineJOIN_DWORDS(SDNode *N, DAGCombinerInfo &DCI) const; -- cgit v1.2.3