; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -march=colossus -mattr=+ipu1 -enable-pipeliner < %s | FileCheck %s
; RUN: llc -march=colossus -mattr=+ipu2 -enable-pipeliner < %s | FileCheck %s


; LLVM IR generated from (reduced) poplibs vertex:
; #include <Vertex.hpp>
; using namespace poplar;
; constexpr auto ONE_PTR = VectorLayout::ONE_PTR;
; template <typename a> class b {
;   Input<Vector<a, ONE_PTR, 8>> c;
;   Output<Vector<float>> f;
;   unsigned d;
;   void m_fn1() {
;     for (unsigned e = d;;) {
;       auto i = e;
;       unsigned g;
;       for (unsigned h = 0; h < e; h++)
;         g += i <= c[h];
;       f[g] = e;
;     }
;   }
; };
; template class b<float>;
;;; Note: the resulting LLVM IR was further reduced with llvm-reduce.

define void @_ZN1bIfE5m_fn1Ev(ptr %this) {
; CHECK-LABEL: _ZN1bIfE5m_fn1Ev:
; CHECK:       # %bb.0: # %entry
; CHECK-NEXT:    mov $m2, $m15
; CHECK-NEXT:    mov $m1, $m15
; CHECK-NEXT:    setzi $m0, 1
; CHECK-NEXT:    cmpslt $m0, $m0, $m15
; CHECK-NEXT:    ld64 $a0:1, $m15, $m15, 0
; CHECK-NEXT:    brz $m0, .LBB0_4
; CHECK-NEXT:  # %bb.1: # %vector.body
; CHECK-NEXT:    {
; CHECK-NEXT:     setzi $m0, 2
; CHECK-NEXT:     f32v2cmpge $a2:3, $a0:1, $a14:15
; CHECK-NEXT:    }
; CHECK-NEXT:    cmpslt $m3, $m0, $m15
; CHECK-NEXT:    add $m0, $m15, -2
; CHECK-NEXT:    ld64 $a0:1, $m15, $m15, 0
; CHECK-NEXT:    mov $m4, $a2
; CHECK-NEXT:    mov $m5, $a3
; CHECK-NEXT:    sub $m1, $m1, $m5
; CHECK-NEXT:    sub $m2, $m2, $m4
; CHECK-NEXT:    brz $m3, .LBB0_4
; CHECK-NEXT:  # %bb.2: # %vector.body
; CHECK-NEXT:    add $m0, $m0, -1
; CHECK-NEXT:  .LBB0_3: # %vector.body
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    {
; CHECK-NEXT:     ld64 $a0:1, $m15, $m15, 0
; CHECK-NEXT:     f32v2cmpge $a2:3, $a0:1, $a14:15
; CHECK-NEXT:    }
; CHECK-NEXT:    mov $m4, $a2
; CHECK-NEXT:    mov $m5, $a3
; CHECK-NEXT:    sub $m2, $m2, $m4
; CHECK-NEXT:    sub $m1, $m1, $m5
; CHECK-NEXT:    brnzdec $m0, .LBB0_3
; CHECK-NEXT:  .LBB0_4: # %middle.block
; CHECK-NEXT:    br $m10
entry:
  %n.vec = and i32 0, 0
  %broadcast.splat = shufflevector <2 x float> zeroinitializer, <2 x float> zeroinitializer, <2 x i32> zeroinitializer
  br label %vector.ph

vector.ph:                                        ; preds = %entry
  br label %vector.body

vector.body:                                      ; preds = %vector.body, %vector.ph
  %index = phi i32 [ 0, %vector.ph ], [ %index.next, %vector.body ]
  %vec.phi = phi <2 x i32> [ zeroinitializer, %vector.ph ], [ %2, %vector.body ]
  %wide.load = load <2 x float>, ptr null, align 8
  %0 = fcmp oge <2 x float> %wide.load, zeroinitializer
  %1 = zext <2 x i1> %0 to <2 x i32>
  %2 = add <2 x i32> %vec.phi, %1
  %index.next = add nuw i32 %index, 1
  %3 = icmp eq i32 %index.next, 0
  br i1 %3, label %middle.block, label %vector.body

middle.block:                                     ; preds = %vector.body
  %4 = call i32 @llvm.vector.reduce.add.v2i32(<2 x i32> %vec.phi)
  ret void
}

declare i32 @llvm.vector.reduce.add.v2i32(<2 x i32>)

