[llvm] r218353 - R600/SI: Enable selecting SALU inside branches

Tom Stellard thomas.stellard at amd.com
Tue Sep 23 18:33:28 PDT 2014


Author: tstellar
Date: Tue Sep 23 20:33:28 2014
New Revision: 218353

URL: http://llvm.org/viewvc/llvm-project?rev=218353&view=rev
Log:
R600/SI: Enable selecting SALU inside branches

We can do this now that the FixSGPRLiveRanges pass is working.

Modified:
    llvm/trunk/lib/Target/R600/AMDGPUISelDAGToDAG.cpp
    llvm/trunk/lib/Target/R600/SIInstructions.td
    llvm/trunk/test/CodeGen/R600/add.ll
    llvm/trunk/test/CodeGen/R600/ctpop.ll
    llvm/trunk/test/CodeGen/R600/ctpop64.ll
    llvm/trunk/test/CodeGen/R600/mul.ll
    llvm/trunk/test/CodeGen/R600/sgpr-control-flow.ll
    llvm/trunk/test/CodeGen/R600/xor.ll

Modified: llvm/trunk/lib/Target/R600/AMDGPUISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUISelDAGToDAG.cpp?rev=218353&r1=218352&r2=218353&view=diff
==============================================================================
--- llvm/trunk/lib/Target/R600/AMDGPUISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/R600/AMDGPUISelDAGToDAG.cpp Tue Sep 23 20:33:28 2014
@@ -79,11 +79,6 @@ private:
   bool isLocalLoad(const LoadSDNode *N) const;
   bool isRegionLoad(const LoadSDNode *N) const;
 
-  /// \returns True if the current basic block being selected is at control
-  ///          flow depth 0.  Meaning that the current block dominates the
-  //           exit block.
-  bool isCFDepth0() const;
-
   const TargetRegisterClass *getOperandRegClass(SDNode *N, unsigned OpNo) const;
   bool SelectGlobalValueConstantOffset(SDValue Addr, SDValue& IntPtr);
   bool SelectGlobalValueVariableOffset(SDValue Addr, SDValue &BaseReg,
@@ -605,14 +600,6 @@ bool AMDGPUDAGToDAGISel::isPrivateLoad(c
   return false;
 }
 
-bool AMDGPUDAGToDAGISel::isCFDepth0() const {
-  // FIXME: Figure out a way to use DominatorTree analysis here.
-  const BasicBlock *CurBlock = FuncInfo->MBB->getBasicBlock();
-  const Function *Fn = FuncInfo->Fn;
-  return &Fn->front() == CurBlock || &Fn->back() == CurBlock;
-}
-
-
 const char *AMDGPUDAGToDAGISel::getPassName() const {
   return "AMDGPU DAG->DAG Pattern Instruction Selection";
 }
@@ -718,11 +705,6 @@ SDNode *AMDGPUDAGToDAGISel::SelectADD_SU
   unsigned Opc = IsAdd ? AMDGPU::S_ADD_U32 : AMDGPU::S_SUB_U32;
   unsigned CarryOpc = IsAdd ? AMDGPU::S_ADDC_U32 : AMDGPU::S_SUBB_U32;
 
-  if (!isCFDepth0()) {
-    Opc = IsAdd ? AMDGPU::V_ADD_I32_e32 : AMDGPU::V_SUB_I32_e32;
-    CarryOpc = IsAdd ? AMDGPU::V_ADDC_U32_e32 : AMDGPU::V_SUBB_U32_e32;
-  }
-
   SDNode *AddLo = CurDAG->getMachineNode( Opc, DL, VTList, AddLoArgs);
   SDValue Carry(AddLo, 1);
   SDNode *AddHi

Modified: llvm/trunk/lib/Target/R600/SIInstructions.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/SIInstructions.td?rev=218353&r1=218352&r2=218353&view=diff
==============================================================================
--- llvm/trunk/lib/Target/R600/SIInstructions.td (original)
+++ llvm/trunk/lib/Target/R600/SIInstructions.td Tue Sep 23 20:33:28 2014
@@ -33,12 +33,9 @@ def isCI : Predicate<"Subtarget.getGener
                       ">= AMDGPUSubtarget::SEA_ISLANDS">;
 def HasFlatAddressSpace : Predicate<"Subtarget.hasFlatAddressSpace()">;
 
-def isCFDepth0 : Predicate<"isCFDepth0()">;
-
 def WAIT_FLAG : InstFlag<"printWaitFlag">;
 
 let SubtargetPredicate = isSI in {
-let OtherPredicates  = [isCFDepth0] in {
 
 //===----------------------------------------------------------------------===//
 // SMRD Instructions
@@ -365,8 +362,6 @@ def S_GETREG_REGRD_B32 : SOPK_32 <0x0000
 //def S_SETREG_IMM32_B32 : SOPK_32 <0x00000015, "S_SETREG_IMM32_B32", []>;
 //def EXP : EXP_ <0x00000000, "EXP", []>;
 
-} // End let OtherPredicates = [isCFDepth0]
-
 //===----------------------------------------------------------------------===//
 // SOPP Instructions
 //===----------------------------------------------------------------------===//
@@ -1944,8 +1939,6 @@ def : Pat <
 // SOP1 Patterns
 //===----------------------------------------------------------------------===//
 
-let Predicates = [isSI, isCFDepth0] in {
-
 def : Pat <
   (i64 (ctpop i64:$src)),
   (INSERT_SUBREG (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
@@ -1964,8 +1957,6 @@ def : Pat <
   (S_ADD_U32 $src0, $src1)
 >;
 
-} // Predicates = [isSI, isCFDepth0]
-
 let  Predicates = [isSI] in {
 
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/test/CodeGen/R600/add.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/R600/add.ll?rev=218353&r1=218352&r2=218353&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/R600/add.ll (original)
+++ llvm/trunk/test/CodeGen/R600/add.ll Tue Sep 23 20:33:28 2014
@@ -141,12 +141,10 @@ entry:
   ret void
 }
 
-; Test i64 add inside a branch.  We don't allow SALU instructions inside of
-; branches.
-; FIXME: We are being conservative here.  We could allow this in some cases.
+; Test i64 add inside a branch.
 ; FUNC-LABEL: @add64_in_branch
-; SI-CHECK-NOT: S_ADD_I32
-; SI-CHECK-NOT: S_ADDC_U32
+; SI-CHECK: S_ADD_U32
+; SI-CHECK: S_ADDC_U32
 define void @add64_in_branch(i64 addrspace(1)* %out, i64 addrspace(1)* %in, i64 %a, i64 %b, i64 %c) {
 entry:
   %0 = icmp eq i64 %a, 0

Modified: llvm/trunk/test/CodeGen/R600/ctpop.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/R600/ctpop.ll?rev=218353&r1=218352&r2=218353&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/R600/ctpop.ll (original)
+++ llvm/trunk/test/CodeGen/R600/ctpop.ll Tue Sep 23 20:33:28 2014
@@ -270,28 +270,28 @@ define void @v_ctpop_i32_add_vvar_inv(i3
 ; but there are some cases when the should be allowed.
 
 ; FUNC-LABEL: @ctpop_i32_in_br
-; SI: BUFFER_LOAD_DWORD [[VAL:v[0-9]+]],
-; SI: V_BCNT_U32_B32_e64 [[RESULT:v[0-9]+]], [[VAL]], 0
+; SI: S_LOAD_DWORD [[VAL:s[0-9]+]], s[{{[0-9]+:[0-9]+}}], 0xd
+; SI: S_BCNT1_I32_B32  [[SRESULT:s[0-9]+]], [[VAL]]
+; SI: V_MOV_B32_e32 [[RESULT]], [[SRESULT]]
 ; SI: BUFFER_STORE_DWORD [[RESULT]],
 ; SI: S_ENDPGM
 ; EG: BCNT_INT
-define void @ctpop_i32_in_br(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %cond) {
+define void @ctpop_i32_in_br(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %ctpop_arg, i32 %cond) {
 entry:
-  %0 = icmp eq i32 %cond, 0
-  br i1 %0, label %if, label %else
+  %tmp0 = icmp eq i32 %cond, 0
+  br i1 %tmp0, label %if, label %else
 
 if:
-  %1 = load i32 addrspace(1)* %in
-  %2 = call i32 @llvm.ctpop.i32(i32 %1)
+  %tmp2 = call i32 @llvm.ctpop.i32(i32 %ctpop_arg)
   br label %endif
 
 else:
-  %3 = getelementptr i32 addrspace(1)* %in, i32 1
-  %4 = load i32 addrspace(1)* %3
+  %tmp3 = getelementptr i32 addrspace(1)* %in, i32 1
+  %tmp4 = load i32 addrspace(1)* %tmp3
   br label %endif
 
 endif:
-  %5 = phi i32 [%2, %if], [%4, %else]
-  store i32 %5, i32 addrspace(1)* %out
+  %tmp5 = phi i32 [%tmp2, %if], [%tmp4, %else]
+  store i32 %tmp5, i32 addrspace(1)* %out
   ret void
 }

Modified: llvm/trunk/test/CodeGen/R600/ctpop64.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/R600/ctpop64.ll?rev=218353&r1=218352&r2=218353&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/R600/ctpop64.ll (original)
+++ llvm/trunk/test/CodeGen/R600/ctpop64.ll Tue Sep 23 20:33:28 2014
@@ -94,29 +94,28 @@ define void @v_ctpop_v4i64(<4 x i32> add
 ; but there are some cases when the should be allowed.
 
 ; FUNC-LABEL: @ctpop_i64_in_br
-; SI: V_BCNT_U32_B32_e64 [[BCNT_LO:v[0-9]+]], v{{[0-9]+}}, 0
-; SI: V_BCNT_U32_B32_e32 v[[BCNT:[0-9]+]], v{{[0-9]+}}, [[BCNT_LO]]
-; SI: V_MOV_B32_e32 v[[ZERO:[0-9]+]], 0
-; SI: BUFFER_STORE_DWORDX2 v[
-; SI: [[BCNT]]:[[ZERO]]]
+; SI: S_LOAD_DWORDX2 s{{\[}}[[LOVAL:[0-9]+]]:[[HIVAL:[0-9]+]]{{\]}}, s[{{[0-9]+:[0-9]+}}], 0xd
+; SI: S_BCNT1_I32_B64 [[RESULT:s[0-9]+]], {{s\[}}[[LOVAL]]:[[HIVAL]]{{\]}}
+; SI: V_MOV_B32_e32 v[[VLO:[0-9]+]], [[RESULT]]
+; SI: V_MOV_B32_e32 v[[VHI:[0-9]+]], s[[HIVAL]]
+; SI: BUFFER_STORE_DWORDX2 {{v\[}}[[VLO]]:[[VHI]]{{\]}}
 ; SI: S_ENDPGM
-define void @ctpop_i64_in_br(i64 addrspace(1)* %out, i64 addrspace(1)* %in, i32 %cond) {
+define void @ctpop_i64_in_br(i64 addrspace(1)* %out, i64 addrspace(1)* %in, i64 %ctpop_arg, i32 %cond) {
 entry:
-  %0 = icmp eq i32 %cond, 0
-  br i1 %0, label %if, label %else
+  %tmp0 = icmp eq i32 %cond, 0
+  br i1 %tmp0, label %if, label %else
 
 if:
-  %1 = load i64 addrspace(1)* %in
-  %2 = call i64 @llvm.ctpop.i64(i64 %1)
+  %tmp2 = call i64 @llvm.ctpop.i64(i64 %ctpop_arg)
   br label %endif
 
 else:
-  %3 = getelementptr i64 addrspace(1)* %in, i32 1
-  %4 = load i64 addrspace(1)* %3
+  %tmp3 = getelementptr i64 addrspace(1)* %in, i32 1
+  %tmp4 = load i64 addrspace(1)* %tmp3
   br label %endif
 
 endif:
-  %5 = phi i64 [%2, %if], [%4, %else]
-  store i64 %5, i64 addrspace(1)* %out
+  %tmp5 = phi i64 [%tmp2, %if], [%tmp4, %else]
+  store i64 %tmp5, i64 addrspace(1)* %out
   ret void
 }

Modified: llvm/trunk/test/CodeGen/R600/mul.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/R600/mul.ll?rev=218353&r1=218352&r2=218353&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/R600/mul.ll (original)
+++ llvm/trunk/test/CodeGen/R600/mul.ll Tue Sep 23 20:33:28 2014
@@ -155,7 +155,7 @@ define void @v_mul_i64(i64 addrspace(1)*
 }
 
 ; FUNC-LABEL: @mul32_in_branch
-; SI: V_MUL_LO_I32
+; SI: S_MUL_I32
 define void @mul32_in_branch(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %a, i32 %b, i32 %c) {
 entry:
   %0 = icmp eq i32 %a, 0
@@ -176,7 +176,7 @@ endif:
 }
 
 ; FUNC-LABEL: @mul64_in_branch
-; SI-DAG: V_MUL_LO_I32
+; SI-DAG: S_MUL_I32
 ; SI-DAG: V_MUL_HI_U32
 ; SI: S_ENDPGM
 define void @mul64_in_branch(i64 addrspace(1)* %out, i64 addrspace(1)* %in, i64 %a, i64 %b, i64 %c) {

Modified: llvm/trunk/test/CodeGen/R600/sgpr-control-flow.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/R600/sgpr-control-flow.ll?rev=218353&r1=218352&r2=218353&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/R600/sgpr-control-flow.ll (original)
+++ llvm/trunk/test/CodeGen/R600/sgpr-control-flow.ll Tue Sep 23 20:33:28 2014
@@ -4,9 +4,14 @@
 ; Most SALU instructions ignore control flow, so we need to make sure
 ; they don't overwrite values from other blocks.
 
-; SI-NOT: S_ADD
+; If the branch decision is made based on a value in an SGPR then all
+; threads will execute the same code paths, so we don't need to worry
+; about instructions in different blocks overwriting each other.
+; SI-LABEL: @sgpr_if_else_salu_br
+; SI: S_ADD
+; SI: S_ADD
 
-define void @sgpr_if_else(i32 addrspace(1)* %out, i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
+define void @sgpr_if_else_salu_br(i32 addrspace(1)* %out, i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
 entry:
   %0 = icmp eq i32 %a, 0
   br i1 %0, label %if, label %else
@@ -25,3 +30,35 @@ endif:
   store i32 %4, i32 addrspace(1)* %out
   ret void
 }
+
+; The two S_ADD instructions should write to different registers, since
+; different threads will take different control flow paths.
+
+; SI-LABEL: @sgpr_if_else_valu_br
+; SI: S_ADD_I32 [[SGPR:s[0-9]+]]
+; SI-NOT: S_ADD_I32 [[SGPR]]
+
+define void @sgpr_if_else_valu_br(i32 addrspace(1)* %out, float %a, i32 %b, i32 %c, i32 %d, i32 %e) {
+entry:
+  %tid = call i32 @llvm.r600.read.tidig.x() #0
+  %tid_f = uitofp i32 %tid to float
+  %tmp1 = fcmp ueq float %tid_f, 0.0
+  br i1 %tmp1, label %if, label %else
+
+if:
+  %tmp2 = add i32 %b, %c
+  br label %endif
+
+else:
+  %tmp3 = add i32 %d, %e
+  br label %endif
+
+endif:
+  %tmp4 = phi i32 [%tmp2, %if], [%tmp3, %else]
+  store i32 %tmp4, i32 addrspace(1)* %out
+  ret void
+}
+
+declare i32 @llvm.r600.read.tidig.x() #0
+
+attributes #0 = { readnone }

Modified: llvm/trunk/test/CodeGen/R600/xor.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/R600/xor.ll?rev=218353&r1=218352&r2=218353&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/R600/xor.ll (original)
+++ llvm/trunk/test/CodeGen/R600/xor.ll Tue Sep 23 20:33:28 2014
@@ -136,8 +136,7 @@ define void @vector_not_i64(i64 addrspac
 ; use an SALU instruction for this.
 
 ; SI-CHECK-LABEL: @xor_cf
-; SI-CHECK: V_XOR
-; SI-CHECK: V_XOR
+; SI-CHECK: S_XOR_B64
 define void @xor_cf(i64 addrspace(1)* %out, i64 addrspace(1)* %in, i64 %a, i64 %b) {
 entry:
   %0 = icmp eq i64 %a, 0





More information about the llvm-commits mailing list