[llvm] r219848 - R600/SI: Fix bug where immediates were being used in DS addr operands

Tom Stellard thomas.stellard at amd.com
Wed Oct 15 14:08:59 PDT 2014


Author: tstellar
Date: Wed Oct 15 16:08:59 2014
New Revision: 219848

URL: http://llvm.org/viewvc/llvm-project?rev=219848&view=rev
Log:
R600/SI: Fix bug where immediates were being used in DS addr operands

The SelectDS1Addr1Offset complex pattern always tries to store constant
lds pointers in the offset operand and store a zero value in the addr operand.
Since the addr operand does not accept immediates, the zero value
needs to first be copied to a register.

This newly created zero value will not go through normal instruction
selection, so we need to manually insert a V_MOV_B32_e32 in the complex
pattern.

This bug was hidden by the fact that if there was another zero value
in the DAG that had not been selected yet, then the CSE done by the DAG
would use the unselected node for the addr operand rather than the one
that was just created.  This would lead to the zero value being selected
and the DAG automatically inserting a V_MOV_B32_e32 instruction.

Modified:
    llvm/trunk/lib/Target/R600/AMDGPUISelDAGToDAG.cpp
    llvm/trunk/test/CodeGen/R600/load.ll

Modified: llvm/trunk/lib/Target/R600/AMDGPUISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUISelDAGToDAG.cpp?rev=219848&r1=219847&r2=219848&view=diff
==============================================================================
--- llvm/trunk/lib/Target/R600/AMDGPUISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/R600/AMDGPUISelDAGToDAG.cpp Wed Oct 15 16:08:59 2014
@@ -793,7 +793,10 @@ bool AMDGPUDAGToDAGISel::SelectDS1Addr1O
   // into read2 / write2 instructions.
   if (const ConstantSDNode *CAddr = dyn_cast<ConstantSDNode>(Addr)) {
     if (isUInt<16>(CAddr->getZExtValue())) {
-      Base = CurDAG->getConstant(0, MVT::i32);
+      SDValue Zero = CurDAG->getTargetConstant(0, MVT::i32);
+      MachineSDNode *MovZero = CurDAG->getMachineNode(AMDGPU::V_MOV_B32_e32,
+                                 SDLoc(Addr), MVT::i32, Zero);
+      Base = SDValue(MovZero, 0);
       Offset = Addr;
       return true;
     }

Modified: llvm/trunk/test/CodeGen/R600/load.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/R600/load.ll?rev=219848&r1=219847&r2=219848&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/R600/load.ll (original)
+++ llvm/trunk/test/CodeGen/R600/load.ll Wed Oct 15 16:08:59 2014
@@ -719,3 +719,21 @@ define void @load_i32_v2i32_local(<2 x i
   store <2 x i32> %vec, <2 x i32> addrspace(1)* %out
   ret void
 }
+
+
+ at lds = addrspace(3) global [512 x i32] zeroinitializer, align 4
+
+; On SI we need to make sure that the base offset is a register and not
+; an immediate.
+; FUNC-LABEL: {{^}}load_i32_local_const_ptr:
+; SI-CHECK: V_MOV_B32_e32 v[[ZERO:[0-9]+]], 0
+; SI-CHECK: DS_READ_B32 v0, v[[ZERO]] offset:4
+; R600-CHECK: LDS_READ_RET
+define void @load_i32_local_const_ptr(i32 addrspace(1)* %out, i32 addrspace(3)* %in) {
+entry:
+  %tmp0 = getelementptr [512 x i32] addrspace(3)* @lds, i32 0, i32 1
+  %tmp1 = load i32 addrspace(3)* %tmp0
+  %tmp2 = getelementptr i32 addrspace(1)* %out, i32 1
+  store i32 %tmp1, i32 addrspace(1)* %tmp2
+  ret void
+}





More information about the llvm-commits mailing list