#!/bin/sh
set -ex
trap 'rm o' 0
# Why do we get stack smashing on GCC but not on Clang with the stack protector?
c++ -fno-stack-protector `pkg-config --cflags --libs libhwy` -x c++ - -o o <<EOF
#include <hwy/highway.h>
namespace hn = hwy::HWY_NAMESPACE;
using T = int;
void MulAddLoop(const T* HWY_RESTRICT mul_array,
                const T* HWY_RESTRICT add_array,
                const size_t size, T* HWY_RESTRICT x_array) {
  const hn::ScalableTag<T> d;
  for (size_t i = 0; i < size; i += hn::Lanes(d)) {
    const auto mul = hn::Load(d, mul_array + i);
    const auto add = hn::Load(d, add_array + i);
    auto x = hn::Load(d, x_array + i);
    x = hn::MulAdd(mul, x, add);
    hn::Store(x, d, x_array + i);
  }
}
int main(){
  const T a[]={1,2,3,4,5},b[]={6,7,9,0,0},expect[]={5,5,6,-4,-5};
  T c[]={-1,-1,-1,-1,-1};
  MulAddLoop(a,b,sizeof(c)/sizeof(c[0]),c);
  for(auto i=0;i<sizeof(c)/sizeof(c[0]);i++)
    if (c[i]!=expect[i])
      return 1;
  return 0;
}
EOF
./o
