[llvm] [LV] Vectorize histogram operations (PR #99851)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 30 02:57:22 PDT 2024


================
@@ -0,0 +1,973 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
+; RUN: opt < %s -passes=loop-vectorize,instcombine -enable-histogram-loop-vectorization -sve-gather-overhead=2 -sve-scatter-overhead=2 -debug-only=loop-vectorize -S 2>&1 | FileCheck %s
+; REQUIRES: asserts
+
+target triple = "aarch64-unknown-linux-gnu"
+
+;; Based on the following C code:
+;;
+;; void simple_histogram(int *buckets, unsigned *indices, int N) {
+;;   for (int i = 0; i < N; ++i)
+;;     buckets[indices[i]]++;
+;; }
+
+; CHECK-LABEL: Checking a loop in 'simple_histogram'
+
+; CHECK: LV: Checking for a histogram on: store i32 %inc, ptr %arrayidx2, align 4
+; CHECK: LV: Found histogram for: store i32 %inc, ptr %arrayidx2, align 4
+
+;; Check that the scalar plan contains the original instructions.
+; CHECK: VPlan 'Initial VPlan for VF={1},UF>=1' {
+; CHECK-NEXT: Live-in vp<%0> = VF * UF
+; CHECK-NEXT: Live-in vp<%1> = vector-trip-count
+; CHECK-NEXT: Live-in ir<%N> = original trip-count
+; CHECK-EMPTY:
+; CHECK-NEXT: vector.ph:
+; CHECK-NEXT: Successor(s): vector loop
+; CHECK-EMPTY:
+; CHECK-NEXT: <x1> vector loop: {
+; CHECK-NEXT:   vector.body:
+; CHECK-NEXT:     EMIT vp<%2> = CANONICAL-INDUCTION ir<0>, vp<%4>
+; CHECK-NEXT:     vp<%3> = SCALAR-STEPS vp<%2>, ir<1>
+; CHECK-NEXT:     CLONE ir<%arrayidx> = getelementptr inbounds ir<%indices>, vp<%3>
+; CHECK-NEXT:     CLONE ir<%0> = load ir<%arrayidx>
+; CHECK-NEXT:     CLONE ir<%idxprom1> = zext ir<%0>
+; CHECK-NEXT:     CLONE ir<%arrayidx2> = getelementptr inbounds ir<%buckets>, ir<%idxprom1>
+; CHECK-NEXT:     CLONE ir<%1> = load ir<%arrayidx2>
+; CHECK-NEXT:     CLONE ir<%inc> = add nsw ir<%1>, ir<1>
+; CHECK-NEXT:     CLONE store ir<%inc>, ir<%arrayidx2>
+; CHECK-NEXT:     EMIT vp<%4> = add nuw vp<%2>, vp<%0>
+; CHECK-NEXT:     EMIT branch-on-count vp<%4>, vp<%1>
+; CHECK-NEXT:   No successors
+; CHECK-NEXT: }
+; CHECK-NEXT: Successor(s): middle.block
+; CHECK-EMPTY:
+; CHECK-NEXT: middle.block:
+; CHECK-NEXT:   EMIT vp<%6> = icmp eq ir<%N>, vp<%1>
+; CHECK-NEXT:   EMIT branch-on-cond vp<%6>
+; CHECK-NEXT: Successor(s): ir-bb<for.exit>, scalar.ph
+; CHECK-EMPTY:
+; CHECK-NEXT: ir-bb<for.exit>:
+; CHECK-NEXT: No successors
+; CHECK-EMPTY:
+; CHECK-NEXT: scalar.ph:
+; CHECK-NEXT: No successors
+; CHECK-NEXT: }
+
+;; Check that the vectorized plan contains a histogram recipe instead.
+; CHECK: VPlan 'Initial VPlan for VF={vscale x 2,vscale x 4},UF>=1' {
+; CHECK-NEXT: Live-in vp<%0> = VF * UF
+; CHECK-NEXT: Live-in vp<%1> = vector-trip-count
+; CHECK-NEXT: Live-in ir<%N> = original trip-count
+; CHECK-EMPTY:
+; CHECK-NEXT: vector.ph:
+; CHECK-NEXT: Successor(s): vector loop
+; CHECK-EMPTY:
+; CHECK-NEXT: <x1> vector loop: {
+; CHECK-NEXT:   vector.body:
+; CHECK-NEXT:     EMIT vp<%2> = CANONICAL-INDUCTION ir<0>, vp<%5>
+; CHECK-NEXT:     vp<%3> = SCALAR-STEPS vp<%2>, ir<1>
+; CHECK-NEXT:     CLONE ir<%arrayidx> = getelementptr inbounds ir<%indices>, vp<%3>
+; CHECK-NEXT:     vp<%4> = vector-pointer ir<%arrayidx>
+; CHECK-NEXT:     WIDEN ir<%0> = load vp<%4>
+; CHECK-NEXT:     WIDEN-CAST ir<%idxprom1> = zext  ir<%0> to i64
+; CHECK-NEXT:     WIDEN-GEP Inv[Var] ir<%arrayidx2> = getelementptr inbounds ir<%buckets>, ir<%idxprom1>
+; CHECK-NEXT:     WIDEN-HISTOGRAM buckets: ir<%arrayidx2>, inc: ir<1>
----------------
fhahn wrote:

It would probably better to have a separate test file to check printing of a plan with a histogram recipe. 

It should be sufficient to check printing for a single loop; Ideally also avoiding hard-coded `vp<%xx>` as this makes the tests fragile.

https://github.com/llvm/llvm-project/pull/99851


More information about the llvm-commits mailing list