OSDN Git Service

R600/SI: Legalize INSERT_SUBREG instructions during PostISelFolding
authorTom Stellard <thomas.stellard@amd.com>
Thu, 9 Oct 2014 18:09:15 +0000 (18:09 +0000)
committerTom Stellard <thomas.stellard@amd.com>
Thu, 9 Oct 2014 18:09:15 +0000 (18:09 +0000)
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

lib/Target/R600/SIISelLowering.cpp
test/CodeGen/R600/insert_subreg.ll [new file with mode: 0644]

index be42ceb..1a73d9b 100644 (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);
 }
 
diff --git a/test/CodeGen/R600/insert_subreg.ll b/test/CodeGen/R600/insert_subreg.ll
new file mode 100644 (file)
index 0000000..e311e19
--- /dev/null
@@ -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
+}