[llvm] r219698 - R600/SI: Use DS offsets for constant addresses

Matt Arsenault Matthew.Arsenault at amd.com
Tue Oct 14 10:21:19 PDT 2014


Author: arsenm
Date: Tue Oct 14 12:21:19 2014
New Revision: 219698

URL: http://llvm.org/viewvc/llvm-project?rev=219698&view=rev
Log:
R600/SI: Use DS offsets for constant addresses

Use 0 as the base address for a constant address, so if
we have a constant address we can save moves and form
read2/write2s.

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

Modified: llvm/trunk/lib/Target/R600/AMDGPUISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUISelDAGToDAG.cpp?rev=219698&r1=219697&r2=219698&view=diff
==============================================================================
--- llvm/trunk/lib/Target/R600/AMDGPUISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/R600/AMDGPUISelDAGToDAG.cpp Tue Oct 14 12:21:19 2014
@@ -787,6 +787,18 @@ bool AMDGPUDAGToDAGISel::SelectDS1Addr1O
     }
   }
 
+  // If we have a constant address, prefer to put the constant into the
+  // offset. This can save moves to load the constant address since multiple
+  // operations can share the zero base address register, and enables merging
+  // into read2 / write2 instructions.
+  if (const ConstantSDNode *CAddr = dyn_cast<ConstantSDNode>(Addr)) {
+    if (isUInt<16>(CAddr->getZExtValue())) {
+      Base = CurDAG->getConstant(0, MVT::i32);
+      Offset = Addr;
+      return true;
+    }
+  }
+
   // default case
   Base = Addr;
   Offset = CurDAG->getTargetConstant(0, MVT::i16);

Modified: llvm/trunk/test/CodeGen/R600/ds_read2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/R600/ds_read2.ll?rev=219698&r1=219697&r2=219698&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/R600/ds_read2.ll (original)
+++ llvm/trunk/test/CodeGen/R600/ds_read2.ll Tue Oct 14 12:21:19 2014
@@ -382,6 +382,30 @@ define void @misaligned_read2_f64(double
   ret void
 }
 
+ at foo = addrspace(3) global [4 x i32] zeroinitializer, align 4
+
+; SI-LABEL: @load_constant_adjacent_offsets
+; SI: V_MOV_B32_e32 [[ZERO:v[0-9]+]], 0{{$}}
+; SI: DS_READ2_B32 v{{\[[0-9]+:[0-9]+\]}}, [[ZERO]] offset0:0 offset1:1
+define void @load_constant_adjacent_offsets(i32 addrspace(1)* %out) {
+  %val0 = load i32 addrspace(3)* getelementptr inbounds ([4 x i32] addrspace(3)* @foo, i32 0, i32 0), align 4
+  %val1 = load i32 addrspace(3)* getelementptr inbounds ([4 x i32] addrspace(3)* @foo, i32 0, i32 1), align 4
+  %sum = add i32 %val0, %val1
+  store i32 %sum, i32 addrspace(1)* %out, align 4
+  ret void
+}
+
+; SI-LABEL: @load_constant_disjoint_offsets
+; SI: V_MOV_B32_e32 [[ZERO:v[0-9]+]], 0{{$}}
+; SI: DS_READ2_B32 v{{\[[0-9]+:[0-9]+\]}}, [[ZERO]] offset0:0 offset1:2
+define void @load_constant_disjoint_offsets(i32 addrspace(1)* %out) {
+  %val0 = load i32 addrspace(3)* getelementptr inbounds ([4 x i32] addrspace(3)* @foo, i32 0, i32 0), align 4
+  %val1 = load i32 addrspace(3)* getelementptr inbounds ([4 x i32] addrspace(3)* @foo, i32 0, i32 2), align 4
+  %sum = add i32 %val0, %val1
+  store i32 %sum, i32 addrspace(1)* %out, align 4
+  ret void
+}
+
 @sgemm.lA = internal unnamed_addr addrspace(3) global [264 x float] zeroinitializer, align 4
 @sgemm.lB = internal unnamed_addr addrspace(3) global [776 x float] zeroinitializer, align 4
 

Modified: llvm/trunk/test/CodeGen/R600/ds_write2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/R600/ds_write2.ll?rev=219698&r1=219697&r2=219698&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/R600/ds_write2.ll (original)
+++ llvm/trunk/test/CodeGen/R600/ds_write2.ll Tue Oct 14 12:21:19 2014
@@ -320,6 +320,27 @@ define void @simple_write2_two_val_f64(d
   ret void
 }
 
+ at foo = addrspace(3) global [4 x i32] zeroinitializer, align 4
+
+; SI-LABEL: @store_constant_adjacent_offsets
+; SI: V_MOV_B32_e32 [[ZERO:v[0-9]+]], 0{{$}}
+; SI: DS_WRITE2_B32 [[ZERO]], v{{[0-9]+}}, v{{[0-9]+}} offset0:0 offset1:1
+define void @store_constant_adjacent_offsets() {
+  store i32 123, i32 addrspace(3)* getelementptr inbounds ([4 x i32] addrspace(3)* @foo, i32 0, i32 0), align 4
+  store i32 123, i32 addrspace(3)* getelementptr inbounds ([4 x i32] addrspace(3)* @foo, i32 0, i32 1), align 4
+  ret void
+}
+
+; SI-LABEL: @store_constant_disjoint_offsets
+; SI-DAG: V_MOV_B32_e32 [[VAL:v[0-9]+]], 0x7b{{$}}
+; SI-DAG: V_MOV_B32_e32 [[ZERO:v[0-9]+]], 0{{$}}
+; SI: DS_WRITE2_B32 [[ZERO]], [[VAL]], [[VAL]] offset0:0 offset1:2
+define void @store_constant_disjoint_offsets() {
+  store i32 123, i32 addrspace(3)* getelementptr inbounds ([4 x i32] addrspace(3)* @foo, i32 0, i32 0), align 4
+  store i32 123, i32 addrspace(3)* getelementptr inbounds ([4 x i32] addrspace(3)* @foo, i32 0, i32 2), align 4
+  ret void
+}
+
 @sgemm.lA = internal unnamed_addr addrspace(3) global [264 x float] zeroinitializer, align 4
 @sgemm.lB = internal unnamed_addr addrspace(3) global [776 x float] zeroinitializer, align 4
 





More information about the llvm-commits mailing list