From: Tom Stellard Date: Fri, 20 Jun 2014 17:06:11 +0000 (+0000) Subject: R600/SI: Add patterns for ctpop inside a branch X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ae4c9e7bc3cea05ed104e3532c4a9b5bc308401b;p=platform%2Fupstream%2Fllvm.git R600/SI: Add patterns for ctpop inside a branch llvm-svn: 211378 --- diff --git a/llvm/lib/Target/R600/SIInstructions.td b/llvm/lib/Target/R600/SIInstructions.td index d489f51..f888b8e 100644 --- a/llvm/lib/Target/R600/SIInstructions.td +++ b/llvm/lib/Target/R600/SIInstructions.td @@ -1742,6 +1742,24 @@ def : Pat < (S_BUFFER_LOAD_DWORD_SGPR $sbase, (S_MOV_B32 imm:$offset)) >; +} // Predicates = [isSI] in { + +//===----------------------------------------------------------------------===// +// SOP1 Patterns +//===----------------------------------------------------------------------===// + +let Predicates = [isSI, isCFDepth0] in { + +def : Pat < + (i64 (ctpop i64:$src)), + (INSERT_SUBREG (INSERT_SUBREG (i64 (IMPLICIT_DEF)), + (S_BCNT1_I32_B64 $src), sub0), + (S_MOV_B32 0), sub1) +>; + +} // Predicates = [isSI, isCFDepth0] + +let Predicates = [isSI] in { //===----------------------------------------------------------------------===// // SOP2 Patterns //===----------------------------------------------------------------------===// @@ -1793,6 +1811,26 @@ class SextInReg : Pat < def : SextInReg ; def : SextInReg ; +def : Pat < + (i32 (add (i32 (ctpop i32:$popcnt)), i32:$val)), + (V_BCNT_U32_B32_e32 $popcnt, $val) +>; + +def : Pat < + (i32 (ctpop i32:$popcnt)), + (V_BCNT_U32_B32_e64 $popcnt, 0, 0, 0) +>; + +def : Pat < + (i64 (ctpop i64:$src)), + (INSERT_SUBREG + (INSERT_SUBREG (i64 (IMPLICIT_DEF)), + (V_BCNT_U32_B32_e32 (EXTRACT_SUBREG $src, sub1), + (V_BCNT_U32_B32_e64 (EXTRACT_SUBREG $src, sub0), 0, 0, 0)), + sub0), + (V_MOV_B32_e32 0), sub1) +>; + /********** ======================= **********/ /********** Image sampling patterns **********/ /********** ======================= **********/ @@ -2786,18 +2824,6 @@ def : Pat < (S_ADD_I32 $src0, $src1) >; -def : Pat < - (i32 (add (i32 (ctpop i32:$popcnt)), i32:$val)), - (V_BCNT_U32_B32_e32 $popcnt, $val) ->; - -def : Pat < - (i64 (ctpop i64:$src)), - (INSERT_SUBREG (INSERT_SUBREG (i64 (IMPLICIT_DEF)), - (S_BCNT1_I32_B64 $src), sub0), - (S_MOV_B32 0), sub1) ->; - //============================================================================// // Miscellaneous Optimization Patterns //============================================================================// diff --git a/llvm/test/CodeGen/R600/ctpop.ll b/llvm/test/CodeGen/R600/ctpop.ll index e4d11e0..15be8e1 100644 --- a/llvm/test/CodeGen/R600/ctpop.ll +++ b/llvm/test/CodeGen/R600/ctpop.ll @@ -252,3 +252,33 @@ define void @v_ctpop_i32_add_vvar_inv(i32 addrspace(1)* noalias %out, i32 addrsp store i32 %add, i32 addrspace(1)* %out, align 4 ret void } + +; FIXME: We currently disallow SALU instructions in all branches, +; 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: 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) { +entry: + %0 = icmp eq i32 %cond, 0 + br i1 %0, label %if, label %else + +if: + %1 = load i32 addrspace(1)* %in + %2 = call i32 @llvm.ctpop.i32(i32 %1) + br label %endif + +else: + %3 = getelementptr i32 addrspace(1)* %in, i32 1 + %4 = load i32 addrspace(1)* %3 + br label %endif + +endif: + %5 = phi i32 [%2, %if], [%4, %else] + store i32 %5, i32 addrspace(1)* %out + ret void +} diff --git a/llvm/test/CodeGen/R600/ctpop64.ll b/llvm/test/CodeGen/R600/ctpop64.ll index 798d8f5..b36ecc6 100644 --- a/llvm/test/CodeGen/R600/ctpop64.ll +++ b/llvm/test/CodeGen/R600/ctpop64.ll @@ -89,3 +89,34 @@ define void @v_ctpop_v4i64(<4 x i32> addrspace(1)* noalias %out, <4 x i64> addrs store <4 x i32> %truncctpop, <4 x i32> addrspace(1)* %out, align 16 ret void } + +; FIXME: We currently disallow SALU instructions in all branches, +; 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_ENDPGM +define void @ctpop_i64_in_br(i64 addrspace(1)* %out, i64 addrspace(1)* %in, i32 %cond) { +entry: + %0 = icmp eq i32 %cond, 0 + br i1 %0, label %if, label %else + +if: + %1 = load i64 addrspace(1)* %in + %2 = call i64 @llvm.ctpop.i64(i64 %1) + br label %endif + +else: + %3 = getelementptr i64 addrspace(1)* %in, i32 1 + %4 = load i64 addrspace(1)* %3 + br label %endif + +endif: + %5 = phi i64 [%2, %if], [%4, %else] + store i64 %5, i64 addrspace(1)* %out + ret void +}