R600/SI: Legalize INSERT_SUBREG instructions during PostISelFolding

LLVM assumes INSERT_SUBREG will always have register operands, so
we need to legalize non-register operands, like FrameIndexes, to
avoid random assertion failures.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219420 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Tom Stellard 2014-10-09 18:09:15 +00:00
parent 81a95a816b
commit d0fb5b1c11
2 changed files with 44 additions and 0 deletions

View File

@ -1920,6 +1920,30 @@ void SITargetLowering::adjustWritemask(MachineSDNode *&Node,
}
}
/// \brief Legalize INSERT_SUBREG instructions with frame index operands.
/// LLVM assumes that all INSERT_SUBREG inputs are registers.
static void legalizeInsertSubreg(MachineSDNode *InsertSubreg,
SelectionDAG &DAG) {
assert(InsertSubreg->getMachineOpcode() == AMDGPU::INSERT_SUBREG);
SmallVector<SDValue, 8> Ops;
for (unsigned i = 0; i < 2; ++i) {
if (!isa<FrameIndexSDNode>(InsertSubreg->getOperand(i))) {
Ops.push_back(InsertSubreg->getOperand(i));
continue;
}
SDLoc DL(InsertSubreg);
Ops.push_back(SDValue(DAG.getMachineNode(AMDGPU::S_MOV_B32, DL,
InsertSubreg->getOperand(i).getValueType(),
InsertSubreg->getOperand(i)), 0));
}
DAG.UpdateNodeOperands(InsertSubreg, Ops[0], Ops[1],
InsertSubreg->getOperand(2));
}
/// \brief Fold the instructions after selecting them.
SDNode *SITargetLowering::PostISelFolding(MachineSDNode *Node,
SelectionDAG &DAG) const {
@ -1930,6 +1954,11 @@ SDNode *SITargetLowering::PostISelFolding(MachineSDNode *Node,
if (TII->isMIMG(Node->getMachineOpcode()))
adjustWritemask(Node, DAG);
if (Node->getMachineOpcode() == AMDGPU::INSERT_SUBREG) {
legalizeTargetIndependentNode(Node, DAG);
return Node;
}
return legalizeOperands(Node, DAG);
}

View File

@ -0,0 +1,15 @@
; RUN: llc -march=r600 -mcpu=SI -mattr=-promote-alloca -verify-machineinstrs < %s
; Test that INSERT_SUBREG instructions don't have non-register operands after
; instruction selection.
; Make sure this doesn't crash
; CHECK-LABEL: test:
define void @test(i64 addrspace(1)* %out) {
entry:
%tmp0 = alloca [16 x i32]
%tmp1 = ptrtoint [16 x i32]* %tmp0 to i32
%tmp2 = sext i32 %tmp1 to i64
store i64 %tmp2, i64 addrspace(1)* %out
ret void
}