[PATCH] R600: Implement TTI:getPopcntSupport
Tom Stellard
tom at stellard.net
Thu Jul 17 12:27:46 PDT 2014
On Thu, Jul 17, 2014 at 06:45:48PM +0000, Matt Arsenault wrote:
> The test is just copied from X86, and I don't know of a better way to test it.
>
LGTM.
> http://reviews.llvm.org/D4569
>
> Files:
> lib/Target/R600/AMDGPUSubtarget.h
> lib/Target/R600/AMDGPUTargetTransformInfo.cpp
> test/Transforms/LoopIdiom/R600/lit.local.cfg
> test/Transforms/LoopIdiom/R600/popcnt.ll
> Index: lib/Target/R600/AMDGPUSubtarget.h
> ===================================================================
> --- lib/Target/R600/AMDGPUSubtarget.h
> +++ lib/Target/R600/AMDGPUSubtarget.h
> @@ -123,8 +123,10 @@
> if (Size == 32)
> return (getGeneration() >= EVERGREEN);
>
> - assert(Size == 64);
> - return (getGeneration() >= SOUTHERN_ISLANDS);
> + if (Size == 64)
> + return (getGeneration() >= SOUTHERN_ISLANDS);
> +
> + return false;
> }
>
> bool hasMulU24() const {
> Index: lib/Target/R600/AMDGPUTargetTransformInfo.cpp
> ===================================================================
> --- lib/Target/R600/AMDGPUTargetTransformInfo.cpp
> +++ lib/Target/R600/AMDGPUTargetTransformInfo.cpp
> @@ -77,6 +77,8 @@
> void getUnrollingPreferences(Loop *L,
> UnrollingPreferences &UP) const override;
>
> + PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const override;
> +
> /// @}
> };
>
> @@ -119,3 +121,9 @@
> }
> }
> }
> +
> +AMDGPUTTI::PopcntSupportKind
> +AMDGPUTTI::getPopcntSupport(unsigned TyWidth) const {
> + assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2");
> + return ST->hasBCNT(TyWidth) ? PSK_FastHardware : PSK_Software;
> +}
> Index: test/Transforms/LoopIdiom/R600/lit.local.cfg
> ===================================================================
> --- /dev/null
> +++ test/Transforms/LoopIdiom/R600/lit.local.cfg
> @@ -0,0 +1,3 @@
> +if not 'R600' in config.root.targets:
> + config.unsupported = True
> +
> Index: test/Transforms/LoopIdiom/R600/popcnt.ll
> ===================================================================
> --- /dev/null
> +++ test/Transforms/LoopIdiom/R600/popcnt.ll
> @@ -0,0 +1,104 @@
> +; RUN: opt -loop-idiom -mtriple=r600-- -mcpu=SI -S < %s | FileCheck %s
> +
> +; Mostly copied from x86 version.
> +
> +;To recognize this pattern:
> +;int popcount(unsigned long long a) {
> +; int c = 0;
> +; while (a) {
> +; c++;
> +; a &= a - 1;
> +; }
> +; return c;
> +;}
> +;
> +
> +; CHECK-LABEL: @popcount_i64
> +; CHECK: entry
> +; CHECK: llvm.ctpop.i64
> +; CHECK: ret
> +define i32 @popcount_i64(i64 %a) nounwind uwtable readnone ssp {
> +entry:
> + %tobool3 = icmp eq i64 %a, 0
> + br i1 %tobool3, label %while.end, label %while.body
> +
> +while.body: ; preds = %entry, %while.body
> + %c.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
> + %a.addr.04 = phi i64 [ %and, %while.body ], [ %a, %entry ]
> + %inc = add nsw i32 %c.05, 1
> + %sub = add i64 %a.addr.04, -1
> + %and = and i64 %sub, %a.addr.04
> + %tobool = icmp eq i64 %and, 0
> + br i1 %tobool, label %while.end, label %while.body
> +
> +while.end: ; preds = %while.body, %entry
> + %c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ]
> + ret i32 %c.0.lcssa
> +}
> +
> +; CHECK-LABEL: @popcount_i32
> +; CHECK: entry
> +; CHECK: llvm.ctpop.i32
> +; CHECK: ret
> +define i32 @popcount_i32(i32 %a) nounwind uwtable readnone ssp {
> +entry:
> + %tobool3 = icmp eq i32 %a, 0
> + br i1 %tobool3, label %while.end, label %while.body
> +
> +while.body: ; preds = %entry, %while.body
> + %c.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
> + %a.addr.04 = phi i32 [ %and, %while.body ], [ %a, %entry ]
> + %inc = add nsw i32 %c.05, 1
> + %sub = add i32 %a.addr.04, -1
> + %and = and i32 %sub, %a.addr.04
> + %tobool = icmp eq i32 %and, 0
> + br i1 %tobool, label %while.end, label %while.body
> +
> +while.end: ; preds = %while.body, %entry
> + %c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ]
> + ret i32 %c.0.lcssa
> +}
> +
> +; To recognize this pattern:
> +;int popcount(unsigned long long a, int mydata1, int mydata2) {
> +; int c = 0;
> +; while (a) {
> +; c++;
> +; a &= a - 1;
> +; mydata1 *= c;
> +; mydata2 *= (int)a;
> +; }
> +; return c + mydata1 + mydata2;
> +;}
> +
> +; CHECK-LABEL: @popcount2
> +; CHECK: entry
> +; CHECK: llvm.ctpop.i64
> +; CHECK: ret
> +define i32 @popcount2(i64 %a, i32 %mydata1, i32 %mydata2) nounwind uwtable readnone ssp {
> +entry:
> + %tobool9 = icmp eq i64 %a, 0
> + br i1 %tobool9, label %while.end, label %while.body
> +
> +while.body: ; preds = %entry, %while.body
> + %c.013 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
> + %mydata2.addr.012 = phi i32 [ %mul1, %while.body ], [ %mydata2, %entry ]
> + %mydata1.addr.011 = phi i32 [ %mul, %while.body ], [ %mydata1, %entry ]
> + %a.addr.010 = phi i64 [ %and, %while.body ], [ %a, %entry ]
> + %inc = add nsw i32 %c.013, 1
> + %sub = add i64 %a.addr.010, -1
> + %and = and i64 %sub, %a.addr.010
> + %mul = mul nsw i32 %inc, %mydata1.addr.011
> + %conv = trunc i64 %and to i32
> + %mul1 = mul nsw i32 %conv, %mydata2.addr.012
> + %tobool = icmp eq i64 %and, 0
> + br i1 %tobool, label %while.end, label %while.body
> +
> +while.end: ; preds = %while.body, %entry
> + %c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ]
> + %mydata2.addr.0.lcssa = phi i32 [ %mydata2, %entry ], [ %mul1, %while.body ]
> + %mydata1.addr.0.lcssa = phi i32 [ %mydata1, %entry ], [ %mul, %while.body ]
> + %add = add i32 %mydata2.addr.0.lcssa, %mydata1.addr.0.lcssa
> + %add2 = add i32 %add, %c.0.lcssa
> + ret i32 %add2
> +}
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list