(in-package :sb-simd-avx)

(defun simd-sum (array &aux (n (array-total-size array)))
  (declare (type (simple-array double-float (*)) array)
           (optimize speed (safety 0)))
  (do ((index 0 (the (integer 0 #.(- array-total-size-limit 16)) (+ index 16)))
       (acc1 (f64.4 0) (f64.4+ acc1 (f64.4-aref array (+ index 0))))
       (acc2 (f64.4 0) (f64.4+ acc2 (f64.4-aref array (+ index 4))))
       (acc3 (f64.4 0) (f64.4+ acc3 (f64.4-aref array (+ index 8))))
       (acc4 (f64.4 0) (f64.4+ acc4 (f64.4-aref array (+ index 12)))))
      ((>= index (- n 16))
       (do ((result (f64.4-horizontal+ (f64.4+ acc1 acc2 acc3 acc4))
                    (+ result (row-major-aref array index)))
            (index index (1+ index)))
           ((>= index n) result)))))
