R600: Fix mishandling of load / store chains.

Fixes various bugs with reordering loads and stores.
Scalarized vector loads weren't collecting the chains
at all.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212473 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Matt Arsenault
2014-07-07 18:34:45 +00:00
parent 7b1c5f52b0
commit 0e1619e77c
4 changed files with 194 additions and 36 deletions

View File

@@ -618,13 +618,13 @@ SDValue SITargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
Load->getAddressSpace() == AMDGPUAS::PRIVATE_ADDRESS ||
(Load->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS &&
Op.getValueType().getVectorNumElements() > 4))) {
SDValue MergedValues[2] = {
SplitVectorLoad(Op, DAG),
Load->getChain()
};
return DAG.getMergeValues(MergedValues, SDLoc(Op));
return SplitVectorLoad(Op, DAG);
} else {
return LowerLOAD(Op, DAG);
SDValue Result = LowerLOAD(Op, DAG);
assert((!Result.getNode() ||
Result.getNode()->getNumValues() == 2) &&
"Load should return a value and a chain");
return Result;
}
}
@@ -841,13 +841,9 @@ SDValue SITargetLowering::LowerBRCOND(SDValue BRCOND,
SDValue SITargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const {
SDLoc DL(Op);
LoadSDNode *Load = cast<LoadSDNode>(Op);
SDValue Ret = AMDGPUTargetLowering::LowerLOAD(Op, DAG);
SDValue MergedValues[2];
MergedValues[1] = Load->getChain();
if (Ret.getNode()) {
MergedValues[0] = Ret;
return DAG.getMergeValues(MergedValues, DL);
}
SDValue Lowered = AMDGPUTargetLowering::LowerLOAD(Op, DAG);
if (Lowered.getNode())
return Lowered;
if (Load->getAddressSpace() != AMDGPUAS::PRIVATE_ADDRESS) {
return SDValue();
@@ -860,25 +856,38 @@ SDValue SITargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const {
SDValue Ptr = DAG.getNode(ISD::SRL, DL, MVT::i32, Load->getBasePtr(),
DAG.getConstant(2, MVT::i32));
Ret = DAG.getNode(AMDGPUISD::REGISTER_LOAD, DL, MVT::i32,
Load->getChain(), Ptr,
DAG.getTargetConstant(0, MVT::i32),
Op.getOperand(2));
// FIXME: REGISTER_LOAD should probably have a chain result.
SDValue Chain = Load->getChain();
SDValue LoLoad = DAG.getNode(AMDGPUISD::REGISTER_LOAD, DL, MVT::i32,
Chain, Ptr,
DAG.getTargetConstant(0, MVT::i32),
Op.getOperand(2));
SDValue Ret = LoLoad.getValue(0);
if (MemVT.getSizeInBits() == 64) {
// TODO: This needs a test to make sure the right thing is happening with
// the chain. That is hard without general function support.
SDValue IncPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, Ptr,
DAG.getConstant(1, MVT::i32));
SDValue LoadUpper = DAG.getNode(AMDGPUISD::REGISTER_LOAD, DL, MVT::i32,
Load->getChain(), IncPtr,
DAG.getTargetConstant(0, MVT::i32),
Op.getOperand(2));
SDValue HiLoad = DAG.getNode(AMDGPUISD::REGISTER_LOAD, DL, MVT::i32,
Chain, IncPtr,
DAG.getTargetConstant(0, MVT::i32),
Op.getOperand(2));
Ret = DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Ret, LoadUpper);
Ret = DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, LoLoad, HiLoad);
// Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
// LoLoad.getValue(1), HiLoad.getValue(1));
}
MergedValues[0] = Ret;
return DAG.getMergeValues(MergedValues, DL);
SDValue Ops[] = {
Ret,
Chain
};
return DAG.getMergeValues(Ops, DL);
}
SDValue SITargetLowering::LowerSampleIntrinsic(unsigned Opcode,