Rename ADD quantization parameters to ADDSUB

Prepare for re-use in quantized SUB microkernels

PiperOrigin-RevId: 395352416
diff --git a/src/init.c b/src/init.c
index 12ec7c7..9a4037c 100644
--- a/src/init.c
+++ b/src/init.c
@@ -52,7 +52,7 @@
 #include <xnnpack/rmax.h>
 #include <xnnpack/spmm.h>
 #include <xnnpack/unpool.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 #include <xnnpack/vbinary.h>
 #include <xnnpack/vmul.h>
 #include <xnnpack/vmulcaddc.h>
@@ -177,7 +177,7 @@
         .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vadd_minmax_ukernel__neon_ld64_x16,
         .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__neon_ld64_x16,
         .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__neon_ld64_x16,
-        .init.qs8_add = xnn_init_qs8_add_minmax_neon_params,
+        .init.qs8_addsub = xnn_init_qs8_add_minmax_neon_params,
         .element_tile = 16,
       };
       if (cpuinfo_has_arm_neon_v8()) {
@@ -245,7 +245,7 @@
         .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vadd_minmax_ukernel__neon_ld64_x16,
         .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__neon_ld64_x16,
         .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__neon_ld64_x16,
-        .init.qu8_add = xnn_init_qu8_add_minmax_neon_params,
+        .init.qu8_addsub = xnn_init_qu8_add_minmax_neon_params,
         .element_tile = 8,
       };
       if (cpuinfo_has_arm_neon_v8()) {
@@ -682,7 +682,7 @@
         .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vadd_minmax_ukernel__scalar_x1,
         .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__scalar_x1,
         .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__scalar_x1,
-        .init.qs8_add = xnn_init_qs8_add_minmax_scalar_params,
+        .init.qs8_addsub = xnn_init_qs8_add_minmax_scalar_params,
         .element_tile = 1,
       };
       xnn_params.qs8.vmul = (struct vbinary_parameters) {
@@ -730,7 +730,7 @@
         .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vadd_minmax_ukernel__scalar_x1,
         .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__scalar_x1,
         .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__scalar_x1,
-        .init.qu8_add = xnn_init_qu8_add_minmax_scalar_params,
+        .init.qu8_addsub = xnn_init_qu8_add_minmax_scalar_params,
         .element_tile = 1,
       };
       xnn_params.qu8.vmul = (struct vbinary_parameters) {
@@ -1412,7 +1412,7 @@
       .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vadd_minmax_ukernel__neon_ld64_x32,
       .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__neon_ld64_x32,
       .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__neon_ld64_x32,
-      .init.qs8_add = xnn_init_qs8_add_minmax_neon_params,
+      .init.qs8_addsub = xnn_init_qs8_add_minmax_neon_params,
       .element_tile = 32,
     };
     xnn_params.qs8.vmul = (struct vbinary_parameters) {
@@ -1582,7 +1582,7 @@
       .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vadd_minmax_ukernel__neon_ld64_x32,
       .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__neon_ld64_x32,
       .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__neon_ld64_x32,
-      .init.qu8_add = xnn_init_qu8_add_minmax_neon_params,
+      .init.qu8_addsub = xnn_init_qu8_add_minmax_neon_params,
       .element_tile = 8,
     };
     xnn_params.qu8.vmul = (struct vbinary_parameters) {
@@ -2430,7 +2430,7 @@
         .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vadd_minmax_ukernel__avx512skx_mul32_ld128_x16,
         .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__avx512skx_mul32_ld128_x16,
         .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__avx512skx_mul32_ld128_x16,
-        .init.qs8_add = xnn_init_qs8_add_minmax_avx512_params,
+        .init.qs8_addsub = xnn_init_qs8_add_minmax_avx512_params,
         .element_tile = 16,
       };
     } else if (cpuinfo_has_x86_xop()) {
@@ -2438,7 +2438,7 @@
         .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vadd_minmax_ukernel__xop_mul32_ld32_x8,
         .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__xop_mul32_ld32_x8,
         .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__xop_mul32_ld32_x8,
-        .init.qs8_add = xnn_init_qs8_add_minmax_sse4_mul32_params,
+        .init.qs8_addsub = xnn_init_qs8_add_minmax_sse4_mul32_params,
         .element_tile = 8,
       };
     } else if (cpuinfo_has_x86_avx2()) {
@@ -2446,7 +2446,7 @@
         .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vadd_minmax_ukernel__avx2_mul32_ld64_x16,
         .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__avx2_mul32_ld64_x16,
         .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__avx2_mul32_ld64_x16,
-        .init.qs8_add = xnn_init_qs8_add_minmax_avx2_params,
+        .init.qs8_addsub = xnn_init_qs8_add_minmax_avx2_params,
         .element_tile = 16,
       };
     } else if (cpuinfo_has_x86_avx()) {
@@ -2454,7 +2454,7 @@
         .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vadd_minmax_ukernel__avx_mul32_ld32_x8,
         .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__avx_mul32_ld32_x8,
         .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__avx_mul32_ld32_x8,
-        .init.qs8_add = xnn_init_qs8_add_minmax_sse4_mul32_params,
+        .init.qs8_addsub = xnn_init_qs8_add_minmax_sse4_mul32_params,
         .element_tile = 8,
       };
     } else if (cpuinfo_has_x86_sse4_1()) {
@@ -2462,7 +2462,7 @@
         .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vadd_minmax_ukernel__sse41_mul16_ld64_x8,
         .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__sse41_mul16_ld64_x8,
         .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__sse41_mul16_ld64_x8,
-        .init.qs8_add = xnn_init_qs8_add_minmax_sse4_mul16_params,
+        .init.qs8_addsub = xnn_init_qs8_add_minmax_sse4_mul16_params,
         .element_tile = 8,
       };
     } else {
@@ -2470,7 +2470,7 @@
         .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vadd_minmax_ukernel__sse2_mul16_ld64_x8,
         .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__sse2_mul16_ld64_x8,
         .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__sse2_mul16_ld64_x8,
-        .init.qs8_add = xnn_init_qs8_add_minmax_sse2_params,
+        .init.qs8_addsub = xnn_init_qs8_add_minmax_sse2_params,
         .element_tile = 8,
       };
     }
@@ -2626,7 +2626,7 @@
         .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vadd_minmax_ukernel__avx512skx_mul32_ld128_x16,
         .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__avx512skx_mul32_ld128_x16,
         .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__avx512skx_mul32_ld128_x16,
-        .init.qu8_add = xnn_init_qu8_add_minmax_avx512_params,
+        .init.qu8_addsub = xnn_init_qu8_add_minmax_avx512_params,
         .element_tile = 16,
       };
     } else if (cpuinfo_has_x86_xop()) {
@@ -2634,7 +2634,7 @@
         .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vadd_minmax_ukernel__xop_mul32_ld32_x8,
         .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__xop_mul32_ld32_x8,
         .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__xop_mul32_ld32_x8,
-        .init.qu8_add = xnn_init_qu8_add_minmax_sse4_params,
+        .init.qu8_addsub = xnn_init_qu8_add_minmax_sse4_params,
         .element_tile = 8,
       };
     } else if (cpuinfo_has_x86_avx2()) {
@@ -2642,7 +2642,7 @@
         .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vadd_minmax_ukernel__avx2_mul32_ld64_x16,
         .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__avx2_mul32_ld64_x16,
         .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__avx2_mul32_ld64_x16,
-        .init.qu8_add = xnn_init_qu8_add_minmax_avx2_params,
+        .init.qu8_addsub = xnn_init_qu8_add_minmax_avx2_params,
         .element_tile = 16,
       };
     } else if (cpuinfo_has_x86_avx()) {
@@ -2650,7 +2650,7 @@
         .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vadd_minmax_ukernel__avx_mul32_ld32_x8,
         .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__avx_mul32_ld32_x8,
         .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__avx_mul32_ld32_x8,
-        .init.qu8_add = xnn_init_qu8_add_minmax_sse4_params,
+        .init.qu8_addsub = xnn_init_qu8_add_minmax_sse4_params,
         .element_tile = 8,
       };
     } else if (cpuinfo_has_x86_sse4_1()) {
@@ -2658,7 +2658,7 @@
         .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vadd_minmax_ukernel__sse41_mul16_ld64_x8,
         .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__sse41_mul16_ld64_x8,
         .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__sse41_mul16_ld64_x8,
-        .init.qu8_add = xnn_init_qu8_add_minmax_sse2_params,
+        .init.qu8_addsub = xnn_init_qu8_add_minmax_sse2_params,
         .element_tile = 8,
       };
     } else {
@@ -2666,7 +2666,7 @@
         .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vadd_minmax_ukernel__sse2_mul16_ld64_x8,
         .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__sse2_mul16_ld64_x8,
         .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__sse2_mul16_ld64_x8,
-        .init.qu8_add = xnn_init_qu8_add_minmax_sse2_params,
+        .init.qu8_addsub = xnn_init_qu8_add_minmax_sse2_params,
         .element_tile = 8,
       };
     }
@@ -3361,7 +3361,7 @@
       .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vadd_minmax_ukernel__wasmsimd_x8,
       .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__wasmsimd_x8,
       .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__wasmsimd_x8,
-      .init.qs8_add = xnn_init_qs8_add_minmax_wasmsimd_params,
+      .init.qs8_addsub = xnn_init_qs8_add_minmax_wasmsimd_params,
       .element_tile = 8,
     };
     xnn_params.qs8.vmul = (struct vbinary_parameters) {
@@ -3422,7 +3422,7 @@
       .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vadd_minmax_ukernel__wasmsimd_x8,
       .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__wasmsimd_x8,
       .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__wasmsimd_x8,
-      .init.qu8_add = xnn_init_qu8_add_minmax_wasmsimd_params,
+      .init.qu8_addsub = xnn_init_qu8_add_minmax_wasmsimd_params,
       .element_tile = 8,
     };
     xnn_params.qu8.vmul = (struct vbinary_parameters) {
@@ -4017,7 +4017,7 @@
       .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vadd_minmax_ukernel__scalar_x4,
       .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__scalar_x4,
       .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__scalar_x4,
-      .init.qs8_add = xnn_init_qs8_add_minmax_scalar_params,
+      .init.qs8_addsub = xnn_init_qs8_add_minmax_scalar_params,
       .element_tile = 4,
     };
     xnn_params.qs8.vmul = (struct vbinary_parameters) {
@@ -4076,7 +4076,7 @@
       .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vadd_minmax_ukernel__scalar_x4,
       .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__scalar_x4,
       .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__scalar_x4,
-      .init.qu8_add = xnn_init_qu8_add_minmax_scalar_params,
+      .init.qu8_addsub = xnn_init_qu8_add_minmax_scalar_params,
       .element_tile = 4,
     };
     xnn_params.qu8.vmul = (struct vbinary_parameters) {
@@ -4459,7 +4459,7 @@
       .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vadd_minmax_ukernel__scalar_x4,
       .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__scalar_x4,
       .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qs8_vaddc_minmax_ukernel__scalar_x4,
-      .init.qs8_add = xnn_init_qs8_add_minmax_scalar_params,
+      .init.qs8_addsub = xnn_init_qs8_add_minmax_scalar_params,
       .element_tile = 4,
     };
   #endif  // XNN_NO_QS8_OPERATORS
@@ -4495,7 +4495,7 @@
       .minmax.op_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vadd_minmax_ukernel__scalar_x4,
       .minmax.opc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__scalar_x4,
       .minmax.ropc_ukernel = (xnn_vbinary_ukernel_function) xnn_qu8_vaddc_minmax_ukernel__scalar_x4,
-      .init.qu8_add = xnn_init_qu8_add_minmax_scalar_params,
+      .init.qu8_addsub = xnn_init_qu8_add_minmax_scalar_params,
       .element_tile = 4,
     };
   #endif  // XNN_NO_QU8_OPERATORS
diff --git a/src/operators/binary-elementwise-nd.c b/src/operators/binary-elementwise-nd.c
index 013f576..90bebbb 100644
--- a/src/operators/binary-elementwise-nd.c
+++ b/src/operators/binary-elementwise-nd.c
@@ -219,15 +219,15 @@
   }
 
   struct {
-    union xnn_qs8_add_minmax_params qs8_add;
-    union xnn_qs8_add_minmax_params qs8_radd;
+    union xnn_qs8_addsub_minmax_params qs8_addsub;
+    union xnn_qs8_addsub_minmax_params qs8_raddsub;
   } params;
-  if (xnn_params.qs8.vadd.init.qs8_add != NULL) {
-    xnn_params.qs8.vadd.init.qs8_add(
-      &params.qs8_add, input1_zero_point, input2_zero_point, output_zero_point,
+  if (xnn_params.qs8.vadd.init.qs8_addsub != NULL) {
+    xnn_params.qs8.vadd.init.qs8_addsub(
+      &params.qs8_addsub, input1_zero_point, input2_zero_point, output_zero_point,
       input1_output_scale, input2_output_scale, output_min, output_max);
-    xnn_params.qs8.vadd.init.qs8_add(
-      &params.qs8_radd, input2_zero_point, input1_zero_point, output_zero_point,
+    xnn_params.qs8.vadd.init.qs8_addsub(
+      &params.qs8_raddsub, input2_zero_point, input1_zero_point, output_zero_point,
       input2_output_scale, input1_output_scale, output_min, output_max);
   }
   return create_binary_elementwise_nd(
@@ -297,15 +297,15 @@
   }
 
   struct {
-    union xnn_qu8_add_minmax_params qu8_add;
-    union xnn_qu8_add_minmax_params qu8_radd;
+    union xnn_qu8_addsub_minmax_params qu8_addsub;
+    union xnn_qu8_addsub_minmax_params qu8_raddsub;
   } params;
-  if (xnn_params.qu8.vadd.init.qu8_add != NULL) {
-    xnn_params.qu8.vadd.init.qu8_add(
-      &params.qu8_add, input1_zero_point, input2_zero_point, output_zero_point,
+  if (xnn_params.qu8.vadd.init.qu8_addsub != NULL) {
+    xnn_params.qu8.vadd.init.qu8_addsub(
+      &params.qu8_addsub, input1_zero_point, input2_zero_point, output_zero_point,
       input1_output_scale, input2_output_scale, output_min, output_max);
-    xnn_params.qu8.vadd.init.qu8_add(
-      &params.qu8_radd, input2_zero_point, input1_zero_point, output_zero_point,
+    xnn_params.qu8.vadd.init.qu8_addsub(
+      &params.qu8_raddsub, input2_zero_point, input1_zero_point, output_zero_point,
       input2_output_scale, input1_output_scale, output_min, output_max);
   }
   return create_binary_elementwise_nd(
@@ -857,8 +857,8 @@
     input1, input2, output,
     XNN_INIT_FLAG_QS8,
     0 /* log2(sizeof(int8_t))) */,
-    &add_op->params.qs8_add, sizeof(add_op->params.qs8_add),
-    &add_op->params.qs8_radd, sizeof(add_op->params.qs8_radd),
+    &add_op->params.qs8_addsub, sizeof(add_op->params.qs8_addsub),
+    &add_op->params.qs8_raddsub, sizeof(add_op->params.qs8_raddsub),
     &xnn_params.qs8.vadd,
     pthreadpool_get_threads_count(threadpool));
 }
@@ -881,8 +881,8 @@
     input1, input2, output,
     XNN_INIT_FLAG_QU8,
     0 /* log2(sizeof(uint8_t))) */,
-    &add_op->params.qu8_add, sizeof(add_op->params.qu8_add),
-    &add_op->params.qu8_radd, sizeof(add_op->params.qu8_radd),
+    &add_op->params.qu8_addsub, sizeof(add_op->params.qu8_addsub),
+    &add_op->params.qu8_raddsub, sizeof(add_op->params.qu8_raddsub),
     &xnn_params.qu8.vadd,
     pthreadpool_get_threads_count(threadpool));
 }
diff --git a/src/params-init.c b/src/params-init.c
index 0fd12c1..a1eb97c 100644
--- a/src/params-init.c
+++ b/src/params-init.c
@@ -1934,7 +1934,7 @@
 
 #if XNN_ARCH_X86 || XNN_ARCH_X86_64
 void xnn_init_qu8_add_minmax_sse2_params(
-  union xnn_qu8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qu8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   uint8_t a_zero_point,
   uint8_t b_zero_point,
   uint8_t output_zero_point,
@@ -1997,7 +1997,7 @@
 }
 
 void xnn_init_qu8_add_minmax_sse4_params(
-  union xnn_qu8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qu8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   uint8_t a_zero_point,
   uint8_t b_zero_point,
   uint8_t output_zero_point,
@@ -2049,7 +2049,7 @@
 }
 
 void xnn_init_qu8_add_minmax_avx2_params(
-  union xnn_qu8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qu8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   uint8_t a_zero_point,
   uint8_t b_zero_point,
   uint8_t output_zero_point,
@@ -2099,7 +2099,7 @@
 }
 
 void xnn_init_qu8_add_minmax_avx512_params(
-  union xnn_qu8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qu8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   uint8_t a_zero_point,
   uint8_t b_zero_point,
   uint8_t output_zero_point,
@@ -2151,7 +2151,7 @@
 
 #if XNN_ARCH_ARM || XNN_ARCH_ARM64
 void xnn_init_qu8_add_minmax_neon_params(
-  union xnn_qu8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qu8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   uint8_t a_zero_point,
   uint8_t b_zero_point,
   uint8_t output_zero_point,
@@ -2197,7 +2197,7 @@
 
 #if XNN_ARCH_WASMSIMD
 void xnn_init_qu8_add_minmax_wasmsimd_params(
-  union xnn_qu8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qu8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   uint8_t a_zero_point,
   uint8_t b_zero_point,
   uint8_t output_zero_point,
@@ -2250,7 +2250,7 @@
 #endif  // XNN_ARCH_WASMSIMD
 
 void xnn_init_qu8_add_minmax_scalar_params(
-  union xnn_qu8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qu8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   uint8_t a_zero_point,
   uint8_t b_zero_point,
   uint8_t output_zero_point,
@@ -2296,7 +2296,7 @@
 
 #if XNN_ARCH_X86 || XNN_ARCH_X86_64
 void xnn_init_qs8_add_minmax_sse2_params(
-  union xnn_qs8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qs8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   int8_t a_zero_point,
   int8_t b_zero_point,
   int8_t output_zero_point,
@@ -2357,7 +2357,7 @@
 }
 
 void xnn_init_qs8_add_minmax_sse4_mul16_params(
-  union xnn_qs8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qs8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   int8_t a_zero_point,
   int8_t b_zero_point,
   int8_t output_zero_point,
@@ -2420,7 +2420,7 @@
 }
 
 void xnn_init_qs8_add_minmax_sse4_mul32_params(
-  union xnn_qs8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qs8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   int8_t a_zero_point,
   int8_t b_zero_point,
   int8_t output_zero_point,
@@ -2472,7 +2472,7 @@
 }
 
 void xnn_init_qs8_add_minmax_avx2_params(
-  union xnn_qs8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qs8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   int8_t a_zero_point,
   int8_t b_zero_point,
   int8_t output_zero_point,
@@ -2522,7 +2522,7 @@
 }
 
 void xnn_init_qs8_add_minmax_avx512_params(
-  union xnn_qs8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qs8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   int8_t a_zero_point,
   int8_t b_zero_point,
   int8_t output_zero_point,
@@ -2574,7 +2574,7 @@
 
 #if XNN_ARCH_ARM || XNN_ARCH_ARM64
 void xnn_init_qs8_add_minmax_neon_params(
-  union xnn_qs8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qs8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   int8_t a_zero_point,
   int8_t b_zero_point,
   int8_t output_zero_point,
@@ -2620,7 +2620,7 @@
 
 #if XNN_ARCH_WASMSIMD
 void xnn_init_qs8_add_minmax_wasmsimd_params(
-  union xnn_qs8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qs8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   int8_t a_zero_point,
   int8_t b_zero_point,
   int8_t output_zero_point,
@@ -2673,7 +2673,7 @@
 #endif  // XNN_ARCH_WASMSIMD
 
 void xnn_init_qs8_add_minmax_scalar_params(
-  union xnn_qs8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qs8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   int8_t a_zero_point,
   int8_t b_zero_point,
   int8_t output_zero_point,
diff --git a/src/qs8-vadd/avx2-mul32-ld64.c.in b/src/qs8-vadd/avx2-mul32-ld64.c.in
index 01c45dd..59981d6 100644
--- a/src/qs8-vadd/avx2-mul32-ld64.c.in
+++ b/src/qs8-vadd/avx2-mul32-ld64.c.in
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 $XINT8_T = {"QS8": "int8_t", "QU8": "uint8_t"}[DATATYPE]
@@ -25,7 +25,7 @@
     const ${XINT8_T}* input_a,
     const ${XINT8_T}* input_b,
     ${XINT8_T}* output,
-    const union xnn_${DATATYPE.lower()}_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_${DATATYPE.lower()}_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m256i vbias = _mm256_load_si256((const __m256i*) params->avx2.bias);
   const __m256i va_multiplier = _mm256_load_si256((const __m256i*) params->avx2.a_multiplier);
diff --git a/src/qs8-vadd/avx512skx-mul32-ld128.c.in b/src/qs8-vadd/avx512skx-mul32-ld128.c.in
index bacbf61..43a967d 100644
--- a/src/qs8-vadd/avx512skx-mul32-ld128.c.in
+++ b/src/qs8-vadd/avx512skx-mul32-ld128.c.in
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 $XINT8_T = {"QS8": "int8_t", "QU8": "uint8_t"}[DATATYPE]
@@ -28,7 +28,7 @@
     const ${XINT8_T}* input_a,
     const ${XINT8_T}* input_b,
     ${XINT8_T}* output,
-    const union xnn_${DATATYPE.lower()}_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_${DATATYPE.lower()}_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m512i vbias = _mm512_load_si512(params->avx512.bias);
   const __m512i va_multiplier = _mm512_load_si512(params->avx512.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-avx-mul16-ld64-x16.c b/src/qs8-vadd/gen/minmax-avx-mul16-ld64-x16.c
index 69142ff..4153780 100644
--- a/src/qs8-vadd/gen/minmax-avx-mul16-ld64-x16.c
+++ b/src/qs8-vadd/gen/minmax-avx-mul16-ld64-x16.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__avx_mul16_ld64_x16(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4_mul16.bias);
   const __m128i va_multiplier_lo = _mm_load_si128((const __m128i*) params->sse4_mul16.a_multiplier_lo);
diff --git a/src/qs8-vadd/gen/minmax-avx-mul16-ld64-x24.c b/src/qs8-vadd/gen/minmax-avx-mul16-ld64-x24.c
index 01ac080..3bf276f 100644
--- a/src/qs8-vadd/gen/minmax-avx-mul16-ld64-x24.c
+++ b/src/qs8-vadd/gen/minmax-avx-mul16-ld64-x24.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__avx_mul16_ld64_x24(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4_mul16.bias);
   const __m128i va_multiplier_lo = _mm_load_si128((const __m128i*) params->sse4_mul16.a_multiplier_lo);
diff --git a/src/qs8-vadd/gen/minmax-avx-mul16-ld64-x32.c b/src/qs8-vadd/gen/minmax-avx-mul16-ld64-x32.c
index e87c0b3..e765771 100644
--- a/src/qs8-vadd/gen/minmax-avx-mul16-ld64-x32.c
+++ b/src/qs8-vadd/gen/minmax-avx-mul16-ld64-x32.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__avx_mul16_ld64_x32(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4_mul16.bias);
   const __m128i va_multiplier_lo = _mm_load_si128((const __m128i*) params->sse4_mul16.a_multiplier_lo);
diff --git a/src/qs8-vadd/gen/minmax-avx-mul16-ld64-x8.c b/src/qs8-vadd/gen/minmax-avx-mul16-ld64-x8.c
index 739018d..1b9e90d 100644
--- a/src/qs8-vadd/gen/minmax-avx-mul16-ld64-x8.c
+++ b/src/qs8-vadd/gen/minmax-avx-mul16-ld64-x8.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__avx_mul16_ld64_x8(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4_mul16.bias);
   const __m128i va_multiplier_lo = _mm_load_si128((const __m128i*) params->sse4_mul16.a_multiplier_lo);
diff --git a/src/qs8-vadd/gen/minmax-avx-mul32-ld32-x16.c b/src/qs8-vadd/gen/minmax-avx-mul32-ld32-x16.c
index bb406d4..63ec6be 100644
--- a/src/qs8-vadd/gen/minmax-avx-mul32-ld32-x16.c
+++ b/src/qs8-vadd/gen/minmax-avx-mul32-ld32-x16.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__avx_mul32_ld32_x16(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4_mul32.bias);
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-avx-mul32-ld32-x24.c b/src/qs8-vadd/gen/minmax-avx-mul32-ld32-x24.c
index f6f0917..1c00a98 100644
--- a/src/qs8-vadd/gen/minmax-avx-mul32-ld32-x24.c
+++ b/src/qs8-vadd/gen/minmax-avx-mul32-ld32-x24.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__avx_mul32_ld32_x24(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4_mul32.bias);
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-avx-mul32-ld32-x32.c b/src/qs8-vadd/gen/minmax-avx-mul32-ld32-x32.c
index 3c31622..270e529 100644
--- a/src/qs8-vadd/gen/minmax-avx-mul32-ld32-x32.c
+++ b/src/qs8-vadd/gen/minmax-avx-mul32-ld32-x32.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__avx_mul32_ld32_x32(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4_mul32.bias);
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-avx-mul32-ld32-x8.c b/src/qs8-vadd/gen/minmax-avx-mul32-ld32-x8.c
index 2f91916..4088dae 100644
--- a/src/qs8-vadd/gen/minmax-avx-mul32-ld32-x8.c
+++ b/src/qs8-vadd/gen/minmax-avx-mul32-ld32-x8.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__avx_mul32_ld32_x8(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4_mul32.bias);
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-avx2-mul32-ld64-x16.c b/src/qs8-vadd/gen/minmax-avx2-mul32-ld64-x16.c
index a442a7f..2e189d1 100644
--- a/src/qs8-vadd/gen/minmax-avx2-mul32-ld64-x16.c
+++ b/src/qs8-vadd/gen/minmax-avx2-mul32-ld64-x16.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__avx2_mul32_ld64_x16(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m256i vbias = _mm256_load_si256((const __m256i*) params->avx2.bias);
   const __m256i va_multiplier = _mm256_load_si256((const __m256i*) params->avx2.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-avx2-mul32-ld64-x24.c b/src/qs8-vadd/gen/minmax-avx2-mul32-ld64-x24.c
index 7b9fa3f..983dcbe 100644
--- a/src/qs8-vadd/gen/minmax-avx2-mul32-ld64-x24.c
+++ b/src/qs8-vadd/gen/minmax-avx2-mul32-ld64-x24.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__avx2_mul32_ld64_x24(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m256i vbias = _mm256_load_si256((const __m256i*) params->avx2.bias);
   const __m256i va_multiplier = _mm256_load_si256((const __m256i*) params->avx2.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-avx2-mul32-ld64-x32.c b/src/qs8-vadd/gen/minmax-avx2-mul32-ld64-x32.c
index 5c881ef..2b7915d 100644
--- a/src/qs8-vadd/gen/minmax-avx2-mul32-ld64-x32.c
+++ b/src/qs8-vadd/gen/minmax-avx2-mul32-ld64-x32.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__avx2_mul32_ld64_x32(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m256i vbias = _mm256_load_si256((const __m256i*) params->avx2.bias);
   const __m256i va_multiplier = _mm256_load_si256((const __m256i*) params->avx2.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-avx2-mul32-ld64-x8.c b/src/qs8-vadd/gen/minmax-avx2-mul32-ld64-x8.c
index f47f48b..44131af 100644
--- a/src/qs8-vadd/gen/minmax-avx2-mul32-ld64-x8.c
+++ b/src/qs8-vadd/gen/minmax-avx2-mul32-ld64-x8.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__avx2_mul32_ld64_x8(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m256i vbias = _mm256_load_si256((const __m256i*) params->avx2.bias);
   const __m256i va_multiplier = _mm256_load_si256((const __m256i*) params->avx2.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-avx512skx-mul32-ld128-x16.c b/src/qs8-vadd/gen/minmax-avx512skx-mul32-ld128-x16.c
index 41f0c05..304ead7 100644
--- a/src/qs8-vadd/gen/minmax-avx512skx-mul32-ld128-x16.c
+++ b/src/qs8-vadd/gen/minmax-avx512skx-mul32-ld128-x16.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__avx512skx_mul32_ld128_x16(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m512i vbias = _mm512_load_si512(params->avx512.bias);
   const __m512i va_multiplier = _mm512_load_si512(params->avx512.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-avx512skx-mul32-ld128-x32.c b/src/qs8-vadd/gen/minmax-avx512skx-mul32-ld128-x32.c
index e51048d..2cf410c 100644
--- a/src/qs8-vadd/gen/minmax-avx512skx-mul32-ld128-x32.c
+++ b/src/qs8-vadd/gen/minmax-avx512skx-mul32-ld128-x32.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__avx512skx_mul32_ld128_x32(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m512i vbias = _mm512_load_si512(params->avx512.bias);
   const __m512i va_multiplier = _mm512_load_si512(params->avx512.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-neon-ld128-x16.c b/src/qs8-vadd/gen/minmax-neon-ld128-x16.c
index 6f1e411..3be4465 100644
--- a/src/qs8-vadd/gen/minmax-neon-ld128-x16.c
+++ b/src/qs8-vadd/gen/minmax-neon-ld128-x16.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__neon_ld128_x16(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   #if XNN_ARCH_ARM64
     const int8x16_t va_zero_point = vld1q_dup_s8(&params->neon.a_zero_point);
diff --git a/src/qs8-vadd/gen/minmax-neon-ld128-x32.c b/src/qs8-vadd/gen/minmax-neon-ld128-x32.c
index 83a3798a..54f6d69 100644
--- a/src/qs8-vadd/gen/minmax-neon-ld128-x32.c
+++ b/src/qs8-vadd/gen/minmax-neon-ld128-x32.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__neon_ld128_x32(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   #if XNN_ARCH_ARM64
     const int8x16_t va_zero_point = vld1q_dup_s8(&params->neon.a_zero_point);
diff --git a/src/qs8-vadd/gen/minmax-neon-ld64-x16.c b/src/qs8-vadd/gen/minmax-neon-ld64-x16.c
index 92ceba3..7d1903b 100644
--- a/src/qs8-vadd/gen/minmax-neon-ld64-x16.c
+++ b/src/qs8-vadd/gen/minmax-neon-ld64-x16.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__neon_ld64_x16(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const int8x8_t va_zero_point = vld1_dup_s8(&params->neon.a_zero_point);
   const int8x8_t vb_zero_point = vld1_dup_s8(&params->neon.b_zero_point);
diff --git a/src/qs8-vadd/gen/minmax-neon-ld64-x24.c b/src/qs8-vadd/gen/minmax-neon-ld64-x24.c
index 2fea004..ef0834e 100644
--- a/src/qs8-vadd/gen/minmax-neon-ld64-x24.c
+++ b/src/qs8-vadd/gen/minmax-neon-ld64-x24.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__neon_ld64_x24(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const int8x8_t va_zero_point = vld1_dup_s8(&params->neon.a_zero_point);
   const int8x8_t vb_zero_point = vld1_dup_s8(&params->neon.b_zero_point);
diff --git a/src/qs8-vadd/gen/minmax-neon-ld64-x32.c b/src/qs8-vadd/gen/minmax-neon-ld64-x32.c
index a2e1bd9..b9d903e 100644
--- a/src/qs8-vadd/gen/minmax-neon-ld64-x32.c
+++ b/src/qs8-vadd/gen/minmax-neon-ld64-x32.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__neon_ld64_x32(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const int8x8_t va_zero_point = vld1_dup_s8(&params->neon.a_zero_point);
   const int8x8_t vb_zero_point = vld1_dup_s8(&params->neon.b_zero_point);
diff --git a/src/qs8-vadd/gen/minmax-neon-ld64-x8.c b/src/qs8-vadd/gen/minmax-neon-ld64-x8.c
index ca26da7..78a7eb8 100644
--- a/src/qs8-vadd/gen/minmax-neon-ld64-x8.c
+++ b/src/qs8-vadd/gen/minmax-neon-ld64-x8.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__neon_ld64_x8(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const int8x8_t va_zero_point = vld1_dup_s8(&params->neon.a_zero_point);
   const int8x8_t vb_zero_point = vld1_dup_s8(&params->neon.b_zero_point);
diff --git a/src/qs8-vadd/gen/minmax-scalar-x1.c b/src/qs8-vadd/gen/minmax-scalar-x1.c
index dc08b0d..1ba3eb9 100644
--- a/src/qs8-vadd/gen/minmax-scalar-x1.c
+++ b/src/qs8-vadd/gen/minmax-scalar-x1.c
@@ -10,7 +10,7 @@
 #include <assert.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__scalar_x1(
@@ -18,7 +18,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
 {
   const int32_t vbias = params->scalar.bias;
   const int32_t va_multiplier = params->scalar.a_multiplier;
diff --git a/src/qs8-vadd/gen/minmax-scalar-x2.c b/src/qs8-vadd/gen/minmax-scalar-x2.c
index f8c6e48..9c4e1b1 100644
--- a/src/qs8-vadd/gen/minmax-scalar-x2.c
+++ b/src/qs8-vadd/gen/minmax-scalar-x2.c
@@ -10,7 +10,7 @@
 #include <assert.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__scalar_x2(
@@ -18,7 +18,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
 {
   const int32_t vbias = params->scalar.bias;
   const int32_t va_multiplier = params->scalar.a_multiplier;
diff --git a/src/qs8-vadd/gen/minmax-scalar-x4.c b/src/qs8-vadd/gen/minmax-scalar-x4.c
index b0e0c06..dfd231f 100644
--- a/src/qs8-vadd/gen/minmax-scalar-x4.c
+++ b/src/qs8-vadd/gen/minmax-scalar-x4.c
@@ -10,7 +10,7 @@
 #include <assert.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__scalar_x4(
@@ -18,7 +18,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
 {
   const int32_t vbias = params->scalar.bias;
   const int32_t va_multiplier = params->scalar.a_multiplier;
diff --git a/src/qs8-vadd/gen/minmax-sse2-mul16-ld64-x16.c b/src/qs8-vadd/gen/minmax-sse2-mul16-ld64-x16.c
index 1cc193c..dd507da 100644
--- a/src/qs8-vadd/gen/minmax-sse2-mul16-ld64-x16.c
+++ b/src/qs8-vadd/gen/minmax-sse2-mul16-ld64-x16.c
@@ -11,7 +11,7 @@
 
 #include <emmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__sse2_mul16_ld64_x16(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse2.bias);
   const __m128i va_multiplier_lo = _mm_load_si128((const __m128i*) params->sse2.a_multiplier_lo);
diff --git a/src/qs8-vadd/gen/minmax-sse2-mul16-ld64-x24.c b/src/qs8-vadd/gen/minmax-sse2-mul16-ld64-x24.c
index fdff664..f8107c2 100644
--- a/src/qs8-vadd/gen/minmax-sse2-mul16-ld64-x24.c
+++ b/src/qs8-vadd/gen/minmax-sse2-mul16-ld64-x24.c
@@ -11,7 +11,7 @@
 
 #include <emmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__sse2_mul16_ld64_x24(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse2.bias);
   const __m128i va_multiplier_lo = _mm_load_si128((const __m128i*) params->sse2.a_multiplier_lo);
diff --git a/src/qs8-vadd/gen/minmax-sse2-mul16-ld64-x32.c b/src/qs8-vadd/gen/minmax-sse2-mul16-ld64-x32.c
index bb8d504..90473a2 100644
--- a/src/qs8-vadd/gen/minmax-sse2-mul16-ld64-x32.c
+++ b/src/qs8-vadd/gen/minmax-sse2-mul16-ld64-x32.c
@@ -11,7 +11,7 @@
 
 #include <emmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__sse2_mul16_ld64_x32(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse2.bias);
   const __m128i va_multiplier_lo = _mm_load_si128((const __m128i*) params->sse2.a_multiplier_lo);
diff --git a/src/qs8-vadd/gen/minmax-sse2-mul16-ld64-x8.c b/src/qs8-vadd/gen/minmax-sse2-mul16-ld64-x8.c
index 2fd0437..f3eb883 100644
--- a/src/qs8-vadd/gen/minmax-sse2-mul16-ld64-x8.c
+++ b/src/qs8-vadd/gen/minmax-sse2-mul16-ld64-x8.c
@@ -11,7 +11,7 @@
 
 #include <emmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__sse2_mul16_ld64_x8(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse2.bias);
   const __m128i va_multiplier_lo = _mm_load_si128((const __m128i*) params->sse2.a_multiplier_lo);
diff --git a/src/qs8-vadd/gen/minmax-sse41-mul16-ld64-x16.c b/src/qs8-vadd/gen/minmax-sse41-mul16-ld64-x16.c
index 9bb66a7..fc41ff4 100644
--- a/src/qs8-vadd/gen/minmax-sse41-mul16-ld64-x16.c
+++ b/src/qs8-vadd/gen/minmax-sse41-mul16-ld64-x16.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__sse41_mul16_ld64_x16(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4_mul16.bias);
   const __m128i va_multiplier_lo = _mm_load_si128((const __m128i*) params->sse4_mul16.a_multiplier_lo);
diff --git a/src/qs8-vadd/gen/minmax-sse41-mul16-ld64-x24.c b/src/qs8-vadd/gen/minmax-sse41-mul16-ld64-x24.c
index ae7219a..181401e 100644
--- a/src/qs8-vadd/gen/minmax-sse41-mul16-ld64-x24.c
+++ b/src/qs8-vadd/gen/minmax-sse41-mul16-ld64-x24.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__sse41_mul16_ld64_x24(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4_mul16.bias);
   const __m128i va_multiplier_lo = _mm_load_si128((const __m128i*) params->sse4_mul16.a_multiplier_lo);
diff --git a/src/qs8-vadd/gen/minmax-sse41-mul16-ld64-x32.c b/src/qs8-vadd/gen/minmax-sse41-mul16-ld64-x32.c
index ef73908..3587ca3 100644
--- a/src/qs8-vadd/gen/minmax-sse41-mul16-ld64-x32.c
+++ b/src/qs8-vadd/gen/minmax-sse41-mul16-ld64-x32.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__sse41_mul16_ld64_x32(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4_mul16.bias);
   const __m128i va_multiplier_lo = _mm_load_si128((const __m128i*) params->sse4_mul16.a_multiplier_lo);
diff --git a/src/qs8-vadd/gen/minmax-sse41-mul16-ld64-x8.c b/src/qs8-vadd/gen/minmax-sse41-mul16-ld64-x8.c
index c0addcf..a0e0671 100644
--- a/src/qs8-vadd/gen/minmax-sse41-mul16-ld64-x8.c
+++ b/src/qs8-vadd/gen/minmax-sse41-mul16-ld64-x8.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__sse41_mul16_ld64_x8(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4_mul16.bias);
   const __m128i va_multiplier_lo = _mm_load_si128((const __m128i*) params->sse4_mul16.a_multiplier_lo);
diff --git a/src/qs8-vadd/gen/minmax-sse41-mul32-ld32-x16.c b/src/qs8-vadd/gen/minmax-sse41-mul32-ld32-x16.c
index 65d6bb2..e984174 100644
--- a/src/qs8-vadd/gen/minmax-sse41-mul32-ld32-x16.c
+++ b/src/qs8-vadd/gen/minmax-sse41-mul32-ld32-x16.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__sse41_mul32_ld32_x16(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4_mul32.bias);
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-sse41-mul32-ld32-x24.c b/src/qs8-vadd/gen/minmax-sse41-mul32-ld32-x24.c
index a77d65d..e272bf3 100644
--- a/src/qs8-vadd/gen/minmax-sse41-mul32-ld32-x24.c
+++ b/src/qs8-vadd/gen/minmax-sse41-mul32-ld32-x24.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__sse41_mul32_ld32_x24(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4_mul32.bias);
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-sse41-mul32-ld32-x32.c b/src/qs8-vadd/gen/minmax-sse41-mul32-ld32-x32.c
index 8973c9f..867efc1 100644
--- a/src/qs8-vadd/gen/minmax-sse41-mul32-ld32-x32.c
+++ b/src/qs8-vadd/gen/minmax-sse41-mul32-ld32-x32.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__sse41_mul32_ld32_x32(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4_mul32.bias);
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-sse41-mul32-ld32-x8.c b/src/qs8-vadd/gen/minmax-sse41-mul32-ld32-x8.c
index d0917fc..97f9661 100644
--- a/src/qs8-vadd/gen/minmax-sse41-mul32-ld32-x8.c
+++ b/src/qs8-vadd/gen/minmax-sse41-mul32-ld32-x8.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__sse41_mul32_ld32_x8(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4_mul32.bias);
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-wasmsimd-x16.c b/src/qs8-vadd/gen/minmax-wasmsimd-x16.c
index 7358b3c..a021ca1 100644
--- a/src/qs8-vadd/gen/minmax-wasmsimd-x16.c
+++ b/src/qs8-vadd/gen/minmax-wasmsimd-x16.c
@@ -11,7 +11,7 @@
 
 #include <wasm_simd128.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__wasmsimd_x16(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const v128_t vbias = wasm_v128_load(params->wasmsimd.bias);
   const v128_t va_multiplier = wasm_v128_load(params->wasmsimd.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-wasmsimd-x24.c b/src/qs8-vadd/gen/minmax-wasmsimd-x24.c
index 03d6f70..66ae0ce 100644
--- a/src/qs8-vadd/gen/minmax-wasmsimd-x24.c
+++ b/src/qs8-vadd/gen/minmax-wasmsimd-x24.c
@@ -11,7 +11,7 @@
 
 #include <wasm_simd128.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__wasmsimd_x24(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const v128_t vbias = wasm_v128_load(params->wasmsimd.bias);
   const v128_t va_multiplier = wasm_v128_load(params->wasmsimd.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-wasmsimd-x32.c b/src/qs8-vadd/gen/minmax-wasmsimd-x32.c
index c4a1624..81cfb2c 100644
--- a/src/qs8-vadd/gen/minmax-wasmsimd-x32.c
+++ b/src/qs8-vadd/gen/minmax-wasmsimd-x32.c
@@ -11,7 +11,7 @@
 
 #include <wasm_simd128.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__wasmsimd_x32(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const v128_t vbias = wasm_v128_load(params->wasmsimd.bias);
   const v128_t va_multiplier = wasm_v128_load(params->wasmsimd.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-wasmsimd-x8.c b/src/qs8-vadd/gen/minmax-wasmsimd-x8.c
index 1dfc656..72783d9 100644
--- a/src/qs8-vadd/gen/minmax-wasmsimd-x8.c
+++ b/src/qs8-vadd/gen/minmax-wasmsimd-x8.c
@@ -11,7 +11,7 @@
 
 #include <wasm_simd128.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__wasmsimd_x8(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const v128_t vbias = wasm_v128_load(params->wasmsimd.bias);
   const v128_t va_multiplier = wasm_v128_load(params->wasmsimd.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-xop-mul32-ld32-x16.c b/src/qs8-vadd/gen/minmax-xop-mul32-ld32-x16.c
index 04d46e3..9004722 100644
--- a/src/qs8-vadd/gen/minmax-xop-mul32-ld32-x16.c
+++ b/src/qs8-vadd/gen/minmax-xop-mul32-ld32-x16.c
@@ -17,7 +17,7 @@
 #endif
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__xop_mul32_ld32_x16(
@@ -25,7 +25,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4_mul32.bias);
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-xop-mul32-ld32-x24.c b/src/qs8-vadd/gen/minmax-xop-mul32-ld32-x24.c
index 12c3f69..c12b84f 100644
--- a/src/qs8-vadd/gen/minmax-xop-mul32-ld32-x24.c
+++ b/src/qs8-vadd/gen/minmax-xop-mul32-ld32-x24.c
@@ -17,7 +17,7 @@
 #endif
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__xop_mul32_ld32_x24(
@@ -25,7 +25,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4_mul32.bias);
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-xop-mul32-ld32-x32.c b/src/qs8-vadd/gen/minmax-xop-mul32-ld32-x32.c
index 051ac20..4e07a59 100644
--- a/src/qs8-vadd/gen/minmax-xop-mul32-ld32-x32.c
+++ b/src/qs8-vadd/gen/minmax-xop-mul32-ld32-x32.c
@@ -17,7 +17,7 @@
 #endif
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__xop_mul32_ld32_x32(
@@ -25,7 +25,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4_mul32.bias);
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
diff --git a/src/qs8-vadd/gen/minmax-xop-mul32-ld32-x8.c b/src/qs8-vadd/gen/minmax-xop-mul32-ld32-x8.c
index 7a8c597..10dffce 100644
--- a/src/qs8-vadd/gen/minmax-xop-mul32-ld32-x8.c
+++ b/src/qs8-vadd/gen/minmax-xop-mul32-ld32-x8.c
@@ -17,7 +17,7 @@
 #endif
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vadd_minmax_ukernel__xop_mul32_ld32_x8(
@@ -25,7 +25,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4_mul32.bias);
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
diff --git a/src/qs8-vadd/neon.c.in b/src/qs8-vadd/neon.c.in
index f6814f7..a365dec 100644
--- a/src/qs8-vadd/neon.c.in
+++ b/src/qs8-vadd/neon.c.in
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 $XINT8_T = {"QS8": "int8_t", "QU8": "uint8_t"}[DATATYPE]
@@ -39,7 +39,7 @@
     const ${XINT8_T}* input_a,
     const ${XINT8_T}* input_b,
     ${XINT8_T}* output,
-    const union xnn_${DATATYPE.lower()}_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_${DATATYPE.lower()}_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   $if LD128:
     #if XNN_ARCH_ARM64
diff --git a/src/qs8-vadd/scalar.c.in b/src/qs8-vadd/scalar.c.in
index bbae859..5d092b8 100644
--- a/src/qs8-vadd/scalar.c.in
+++ b/src/qs8-vadd/scalar.c.in
@@ -8,7 +8,7 @@
 #include <assert.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 $XINT8_T = {"QS8": "int8_t", "QU8": "uint8_t"}[DATATYPE]
@@ -17,7 +17,7 @@
     const ${XINT8_T}* input_a,
     const ${XINT8_T}* input_b,
     ${XINT8_T}* output,
-    const union xnn_${DATATYPE.lower()}_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
+    const union xnn_${DATATYPE.lower()}_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
 {
   const int32_t vbias = params->scalar.bias;
   const int32_t va_multiplier = params->scalar.a_multiplier;
diff --git a/src/qs8-vadd/sse-mul16-ld64.c.in b/src/qs8-vadd/sse-mul16-ld64.c.in
index 33e6baa..bf898ff 100644
--- a/src/qs8-vadd/sse-mul16-ld64.c.in
+++ b/src/qs8-vadd/sse-mul16-ld64.c.in
@@ -14,7 +14,7 @@
 
 #include <${SSE_HEADER}>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 $PARAMS_STRUCT = "sse4_mul16" if SSE == 4 and DATATYPE == "QS8" else "sse2"
@@ -29,7 +29,7 @@
     const ${XINT8_T}* input_a,
     const ${XINT8_T}* input_b,
     ${XINT8_T}* output,
-    const union xnn_${DATATYPE.lower()}_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_${DATATYPE.lower()}_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->${PARAMS_STRUCT}.bias);
   const __m128i va_multiplier_lo = _mm_load_si128((const __m128i*) params->${PARAMS_STRUCT}.a_multiplier_lo);
diff --git a/src/qs8-vadd/sse-mul32-ld32.c.in b/src/qs8-vadd/sse-mul32-ld32.c.in
index 23096ce..b8019cb 100644
--- a/src/qs8-vadd/sse-mul32-ld32.c.in
+++ b/src/qs8-vadd/sse-mul32-ld32.c.in
@@ -22,7 +22,7 @@
   #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 $PARAMS_STRUCT = {"QS8": "sse4_mul32", "QU8": "sse4"}[DATATYPE]
@@ -37,7 +37,7 @@
     const ${XINT8_T}* input_a,
     const ${XINT8_T}* input_b,
     ${XINT8_T}* output,
-    const union xnn_${DATATYPE.lower()}_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_${DATATYPE.lower()}_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->${PARAMS_STRUCT}.bias);
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->${PARAMS_STRUCT}.a_multiplier);
diff --git a/src/qs8-vadd/wasmsimd.c.in b/src/qs8-vadd/wasmsimd.c.in
index 8177f05..9c3b495 100644
--- a/src/qs8-vadd/wasmsimd.c.in
+++ b/src/qs8-vadd/wasmsimd.c.in
@@ -11,7 +11,7 @@
 
 #include <wasm_simd128.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 $XINT8_T = {"QS8": "int8_t", "QU8": "uint8_t"}[DATATYPE]
@@ -26,7 +26,7 @@
     const ${XINT8_T}* input_a,
     const ${XINT8_T}* input_b,
     ${XINT8_T}* output,
-    const union xnn_${DATATYPE.lower()}_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_${DATATYPE.lower()}_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const v128_t vbias = wasm_v128_load(params->wasmsimd.bias);
   const v128_t va_multiplier = wasm_v128_load(params->wasmsimd.a_multiplier);
diff --git a/src/qs8-vaddc/avx2-mul32-ld64.c.in b/src/qs8-vaddc/avx2-mul32-ld64.c.in
index 20d54a4..d880d59 100644
--- a/src/qs8-vaddc/avx2-mul32-ld64.c.in
+++ b/src/qs8-vaddc/avx2-mul32-ld64.c.in
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 $XINT8_T = {"QS8": "int8_t", "QU8": "uint8_t"}[DATATYPE]
@@ -25,7 +25,7 @@
     const ${XINT8_T}* input_a,
     const ${XINT8_T}* input_b,
     ${XINT8_T}* output,
-    const union xnn_${DATATYPE.lower()}_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_${DATATYPE.lower()}_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m256i va_multiplier = _mm256_load_si256((const __m256i*) params->avx2.a_multiplier);
   const __m256i vrounding = _mm256_load_si256((const __m256i*) params->avx2.rounding);
diff --git a/src/qs8-vaddc/avx512skx-mul32-ld128.c.in b/src/qs8-vaddc/avx512skx-mul32-ld128.c.in
index 8069fd6..6095515 100644
--- a/src/qs8-vaddc/avx512skx-mul32-ld128.c.in
+++ b/src/qs8-vaddc/avx512skx-mul32-ld128.c.in
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 $XINT8_T = {"QS8": "int8_t", "QU8": "uint8_t"}[DATATYPE]
@@ -28,7 +28,7 @@
     const ${XINT8_T}* input_a,
     const ${XINT8_T}* input_b,
     ${XINT8_T}* output,
-    const union xnn_${DATATYPE.lower()}_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_${DATATYPE.lower()}_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m512i va_multiplier = _mm512_load_si512(params->avx512.a_multiplier);
   const __m512i vrounding = _mm512_load_si512(params->avx512.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-avx-mul16-ld64-x16.c b/src/qs8-vaddc/gen/minmax-avx-mul16-ld64-x16.c
index 70fa146..30c9307 100644
--- a/src/qs8-vaddc/gen/minmax-avx-mul16-ld64-x16.c
+++ b/src/qs8-vaddc/gen/minmax-avx-mul16-ld64-x16.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__avx_mul16_ld64_x16(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_add_epi32(
     _mm_shuffle_epi32(_mm_cvtsi32_si128(params->sse4_mul16.b_multiplier * (int32_t) *input_b), _MM_SHUFFLE(0, 0, 0, 0)),
diff --git a/src/qs8-vaddc/gen/minmax-avx-mul16-ld64-x24.c b/src/qs8-vaddc/gen/minmax-avx-mul16-ld64-x24.c
index e3ab482..5da4de0 100644
--- a/src/qs8-vaddc/gen/minmax-avx-mul16-ld64-x24.c
+++ b/src/qs8-vaddc/gen/minmax-avx-mul16-ld64-x24.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__avx_mul16_ld64_x24(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_add_epi32(
     _mm_shuffle_epi32(_mm_cvtsi32_si128(params->sse4_mul16.b_multiplier * (int32_t) *input_b), _MM_SHUFFLE(0, 0, 0, 0)),
diff --git a/src/qs8-vaddc/gen/minmax-avx-mul16-ld64-x32.c b/src/qs8-vaddc/gen/minmax-avx-mul16-ld64-x32.c
index 0890958..2af9bab 100644
--- a/src/qs8-vaddc/gen/minmax-avx-mul16-ld64-x32.c
+++ b/src/qs8-vaddc/gen/minmax-avx-mul16-ld64-x32.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__avx_mul16_ld64_x32(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_add_epi32(
     _mm_shuffle_epi32(_mm_cvtsi32_si128(params->sse4_mul16.b_multiplier * (int32_t) *input_b), _MM_SHUFFLE(0, 0, 0, 0)),
diff --git a/src/qs8-vaddc/gen/minmax-avx-mul16-ld64-x8.c b/src/qs8-vaddc/gen/minmax-avx-mul16-ld64-x8.c
index 2f71494..dcee41c 100644
--- a/src/qs8-vaddc/gen/minmax-avx-mul16-ld64-x8.c
+++ b/src/qs8-vaddc/gen/minmax-avx-mul16-ld64-x8.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__avx_mul16_ld64_x8(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_add_epi32(
     _mm_shuffle_epi32(_mm_cvtsi32_si128(params->sse4_mul16.b_multiplier * (int32_t) *input_b), _MM_SHUFFLE(0, 0, 0, 0)),
diff --git a/src/qs8-vaddc/gen/minmax-avx-mul32-ld32-x16.c b/src/qs8-vaddc/gen/minmax-avx-mul32-ld32-x16.c
index a364f1d..b6a9ef9 100644
--- a/src/qs8-vaddc/gen/minmax-avx-mul32-ld32-x16.c
+++ b/src/qs8-vaddc/gen/minmax-avx-mul32-ld32-x16.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__avx_mul32_ld32_x16(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
   const __m128i vrounding = _mm_load_si128((const __m128i*) params->sse4_mul32.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-avx-mul32-ld32-x24.c b/src/qs8-vaddc/gen/minmax-avx-mul32-ld32-x24.c
index 9391563..e20cf5a 100644
--- a/src/qs8-vaddc/gen/minmax-avx-mul32-ld32-x24.c
+++ b/src/qs8-vaddc/gen/minmax-avx-mul32-ld32-x24.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__avx_mul32_ld32_x24(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
   const __m128i vrounding = _mm_load_si128((const __m128i*) params->sse4_mul32.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-avx-mul32-ld32-x32.c b/src/qs8-vaddc/gen/minmax-avx-mul32-ld32-x32.c
index 69c403a..221a53a 100644
--- a/src/qs8-vaddc/gen/minmax-avx-mul32-ld32-x32.c
+++ b/src/qs8-vaddc/gen/minmax-avx-mul32-ld32-x32.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__avx_mul32_ld32_x32(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
   const __m128i vrounding = _mm_load_si128((const __m128i*) params->sse4_mul32.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-avx-mul32-ld32-x8.c b/src/qs8-vaddc/gen/minmax-avx-mul32-ld32-x8.c
index 2f987c6..c1c652c 100644
--- a/src/qs8-vaddc/gen/minmax-avx-mul32-ld32-x8.c
+++ b/src/qs8-vaddc/gen/minmax-avx-mul32-ld32-x8.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__avx_mul32_ld32_x8(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
   const __m128i vrounding = _mm_load_si128((const __m128i*) params->sse4_mul32.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-avx2-mul32-ld64-x16.c b/src/qs8-vaddc/gen/minmax-avx2-mul32-ld64-x16.c
index 3fc7b8d..6b7407b 100644
--- a/src/qs8-vaddc/gen/minmax-avx2-mul32-ld64-x16.c
+++ b/src/qs8-vaddc/gen/minmax-avx2-mul32-ld64-x16.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__avx2_mul32_ld64_x16(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m256i va_multiplier = _mm256_load_si256((const __m256i*) params->avx2.a_multiplier);
   const __m256i vrounding = _mm256_load_si256((const __m256i*) params->avx2.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-avx2-mul32-ld64-x24.c b/src/qs8-vaddc/gen/minmax-avx2-mul32-ld64-x24.c
index 2462f56..a71fcc1 100644
--- a/src/qs8-vaddc/gen/minmax-avx2-mul32-ld64-x24.c
+++ b/src/qs8-vaddc/gen/minmax-avx2-mul32-ld64-x24.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__avx2_mul32_ld64_x24(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m256i va_multiplier = _mm256_load_si256((const __m256i*) params->avx2.a_multiplier);
   const __m256i vrounding = _mm256_load_si256((const __m256i*) params->avx2.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-avx2-mul32-ld64-x32.c b/src/qs8-vaddc/gen/minmax-avx2-mul32-ld64-x32.c
index 21d86a7..c51c26b 100644
--- a/src/qs8-vaddc/gen/minmax-avx2-mul32-ld64-x32.c
+++ b/src/qs8-vaddc/gen/minmax-avx2-mul32-ld64-x32.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__avx2_mul32_ld64_x32(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m256i va_multiplier = _mm256_load_si256((const __m256i*) params->avx2.a_multiplier);
   const __m256i vrounding = _mm256_load_si256((const __m256i*) params->avx2.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-avx2-mul32-ld64-x8.c b/src/qs8-vaddc/gen/minmax-avx2-mul32-ld64-x8.c
index fff4097..4c013e4 100644
--- a/src/qs8-vaddc/gen/minmax-avx2-mul32-ld64-x8.c
+++ b/src/qs8-vaddc/gen/minmax-avx2-mul32-ld64-x8.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__avx2_mul32_ld64_x8(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m256i va_multiplier = _mm256_load_si256((const __m256i*) params->avx2.a_multiplier);
   const __m256i vrounding = _mm256_load_si256((const __m256i*) params->avx2.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-avx512skx-mul32-ld128-x16.c b/src/qs8-vaddc/gen/minmax-avx512skx-mul32-ld128-x16.c
index b6418b8..5d50f70 100644
--- a/src/qs8-vaddc/gen/minmax-avx512skx-mul32-ld128-x16.c
+++ b/src/qs8-vaddc/gen/minmax-avx512skx-mul32-ld128-x16.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__avx512skx_mul32_ld128_x16(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m512i va_multiplier = _mm512_load_si512(params->avx512.a_multiplier);
   const __m512i vrounding = _mm512_load_si512(params->avx512.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-avx512skx-mul32-ld128-x32.c b/src/qs8-vaddc/gen/minmax-avx512skx-mul32-ld128-x32.c
index 9bda5a2..a3f4c75 100644
--- a/src/qs8-vaddc/gen/minmax-avx512skx-mul32-ld128-x32.c
+++ b/src/qs8-vaddc/gen/minmax-avx512skx-mul32-ld128-x32.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__avx512skx_mul32_ld128_x32(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m512i va_multiplier = _mm512_load_si512(params->avx512.a_multiplier);
   const __m512i vrounding = _mm512_load_si512(params->avx512.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-neon-ld128-x16.c b/src/qs8-vaddc/gen/minmax-neon-ld128-x16.c
index 519f079..f9a3d45 100644
--- a/src/qs8-vaddc/gen/minmax-neon-ld128-x16.c
+++ b/src/qs8-vaddc/gen/minmax-neon-ld128-x16.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__neon_ld128_x16(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   #if XNN_ARCH_ARM64
     const int8x16_t va_zero_point = vld1q_dup_s8(&params->neon.a_zero_point);
diff --git a/src/qs8-vaddc/gen/minmax-neon-ld128-x32.c b/src/qs8-vaddc/gen/minmax-neon-ld128-x32.c
index e8dbdd6..caa0394 100644
--- a/src/qs8-vaddc/gen/minmax-neon-ld128-x32.c
+++ b/src/qs8-vaddc/gen/minmax-neon-ld128-x32.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__neon_ld128_x32(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   #if XNN_ARCH_ARM64
     const int8x16_t va_zero_point = vld1q_dup_s8(&params->neon.a_zero_point);
diff --git a/src/qs8-vaddc/gen/minmax-neon-ld64-x16.c b/src/qs8-vaddc/gen/minmax-neon-ld64-x16.c
index 3da548e..25ff09f 100644
--- a/src/qs8-vaddc/gen/minmax-neon-ld64-x16.c
+++ b/src/qs8-vaddc/gen/minmax-neon-ld64-x16.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__neon_ld64_x16(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const int8x8_t va_zero_point = vld1_dup_s8(&params->neon.a_zero_point);
   const int32x4_t va_multiplier = vld1q_dup_s32(&params->neon.a_multiplier);
diff --git a/src/qs8-vaddc/gen/minmax-neon-ld64-x24.c b/src/qs8-vaddc/gen/minmax-neon-ld64-x24.c
index cdd09ff..26a7f24 100644
--- a/src/qs8-vaddc/gen/minmax-neon-ld64-x24.c
+++ b/src/qs8-vaddc/gen/minmax-neon-ld64-x24.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__neon_ld64_x24(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const int8x8_t va_zero_point = vld1_dup_s8(&params->neon.a_zero_point);
   const int32x4_t va_multiplier = vld1q_dup_s32(&params->neon.a_multiplier);
diff --git a/src/qs8-vaddc/gen/minmax-neon-ld64-x32.c b/src/qs8-vaddc/gen/minmax-neon-ld64-x32.c
index fb7e05a..25c1c88 100644
--- a/src/qs8-vaddc/gen/minmax-neon-ld64-x32.c
+++ b/src/qs8-vaddc/gen/minmax-neon-ld64-x32.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__neon_ld64_x32(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const int8x8_t va_zero_point = vld1_dup_s8(&params->neon.a_zero_point);
   const int32x4_t va_multiplier = vld1q_dup_s32(&params->neon.a_multiplier);
diff --git a/src/qs8-vaddc/gen/minmax-neon-ld64-x8.c b/src/qs8-vaddc/gen/minmax-neon-ld64-x8.c
index 487d41e..516851b 100644
--- a/src/qs8-vaddc/gen/minmax-neon-ld64-x8.c
+++ b/src/qs8-vaddc/gen/minmax-neon-ld64-x8.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__neon_ld64_x8(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const int8x8_t va_zero_point = vld1_dup_s8(&params->neon.a_zero_point);
   const int32x4_t va_multiplier = vld1q_dup_s32(&params->neon.a_multiplier);
diff --git a/src/qs8-vaddc/gen/minmax-scalar-x1.c b/src/qs8-vaddc/gen/minmax-scalar-x1.c
index db5598e..2807c3d 100644
--- a/src/qs8-vaddc/gen/minmax-scalar-x1.c
+++ b/src/qs8-vaddc/gen/minmax-scalar-x1.c
@@ -10,7 +10,7 @@
 #include <assert.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__scalar_x1(
@@ -18,7 +18,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
 {
   const int32_t vbias = params->scalar.bias + (int32_t) *input_b * params->scalar.b_multiplier;
   const int32_t va_multiplier = params->scalar.a_multiplier;
diff --git a/src/qs8-vaddc/gen/minmax-scalar-x2.c b/src/qs8-vaddc/gen/minmax-scalar-x2.c
index fb76ce6..3d9d054 100644
--- a/src/qs8-vaddc/gen/minmax-scalar-x2.c
+++ b/src/qs8-vaddc/gen/minmax-scalar-x2.c
@@ -10,7 +10,7 @@
 #include <assert.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__scalar_x2(
@@ -18,7 +18,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
 {
   const int32_t vbias = params->scalar.bias + (int32_t) *input_b * params->scalar.b_multiplier;
   const int32_t va_multiplier = params->scalar.a_multiplier;
diff --git a/src/qs8-vaddc/gen/minmax-scalar-x4.c b/src/qs8-vaddc/gen/minmax-scalar-x4.c
index fa8ce4a..d050dc0 100644
--- a/src/qs8-vaddc/gen/minmax-scalar-x4.c
+++ b/src/qs8-vaddc/gen/minmax-scalar-x4.c
@@ -10,7 +10,7 @@
 #include <assert.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__scalar_x4(
@@ -18,7 +18,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
 {
   const int32_t vbias = params->scalar.bias + (int32_t) *input_b * params->scalar.b_multiplier;
   const int32_t va_multiplier = params->scalar.a_multiplier;
diff --git a/src/qs8-vaddc/gen/minmax-sse2-mul16-ld64-x16.c b/src/qs8-vaddc/gen/minmax-sse2-mul16-ld64-x16.c
index 0ab0d0b..da38776 100644
--- a/src/qs8-vaddc/gen/minmax-sse2-mul16-ld64-x16.c
+++ b/src/qs8-vaddc/gen/minmax-sse2-mul16-ld64-x16.c
@@ -11,7 +11,7 @@
 
 #include <emmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__sse2_mul16_ld64_x16(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_add_epi32(
     _mm_shuffle_epi32(_mm_cvtsi32_si128(params->sse2.b_multiplier * (int32_t) *input_b), _MM_SHUFFLE(0, 0, 0, 0)),
diff --git a/src/qs8-vaddc/gen/minmax-sse2-mul16-ld64-x24.c b/src/qs8-vaddc/gen/minmax-sse2-mul16-ld64-x24.c
index beaf1e6..0c0fb5e 100644
--- a/src/qs8-vaddc/gen/minmax-sse2-mul16-ld64-x24.c
+++ b/src/qs8-vaddc/gen/minmax-sse2-mul16-ld64-x24.c
@@ -11,7 +11,7 @@
 
 #include <emmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__sse2_mul16_ld64_x24(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_add_epi32(
     _mm_shuffle_epi32(_mm_cvtsi32_si128(params->sse2.b_multiplier * (int32_t) *input_b), _MM_SHUFFLE(0, 0, 0, 0)),
diff --git a/src/qs8-vaddc/gen/minmax-sse2-mul16-ld64-x32.c b/src/qs8-vaddc/gen/minmax-sse2-mul16-ld64-x32.c
index 7fabe95..5c01aa8 100644
--- a/src/qs8-vaddc/gen/minmax-sse2-mul16-ld64-x32.c
+++ b/src/qs8-vaddc/gen/minmax-sse2-mul16-ld64-x32.c
@@ -11,7 +11,7 @@
 
 #include <emmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__sse2_mul16_ld64_x32(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_add_epi32(
     _mm_shuffle_epi32(_mm_cvtsi32_si128(params->sse2.b_multiplier * (int32_t) *input_b), _MM_SHUFFLE(0, 0, 0, 0)),
diff --git a/src/qs8-vaddc/gen/minmax-sse2-mul16-ld64-x8.c b/src/qs8-vaddc/gen/minmax-sse2-mul16-ld64-x8.c
index 5f24634..70fde70 100644
--- a/src/qs8-vaddc/gen/minmax-sse2-mul16-ld64-x8.c
+++ b/src/qs8-vaddc/gen/minmax-sse2-mul16-ld64-x8.c
@@ -11,7 +11,7 @@
 
 #include <emmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__sse2_mul16_ld64_x8(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_add_epi32(
     _mm_shuffle_epi32(_mm_cvtsi32_si128(params->sse2.b_multiplier * (int32_t) *input_b), _MM_SHUFFLE(0, 0, 0, 0)),
diff --git a/src/qs8-vaddc/gen/minmax-sse41-mul16-ld64-x16.c b/src/qs8-vaddc/gen/minmax-sse41-mul16-ld64-x16.c
index 953dcbd..75e4483 100644
--- a/src/qs8-vaddc/gen/minmax-sse41-mul16-ld64-x16.c
+++ b/src/qs8-vaddc/gen/minmax-sse41-mul16-ld64-x16.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__sse41_mul16_ld64_x16(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_add_epi32(
     _mm_shuffle_epi32(_mm_cvtsi32_si128(params->sse4_mul16.b_multiplier * (int32_t) *input_b), _MM_SHUFFLE(0, 0, 0, 0)),
diff --git a/src/qs8-vaddc/gen/minmax-sse41-mul16-ld64-x24.c b/src/qs8-vaddc/gen/minmax-sse41-mul16-ld64-x24.c
index ebbe57c..035a1d0 100644
--- a/src/qs8-vaddc/gen/minmax-sse41-mul16-ld64-x24.c
+++ b/src/qs8-vaddc/gen/minmax-sse41-mul16-ld64-x24.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__sse41_mul16_ld64_x24(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_add_epi32(
     _mm_shuffle_epi32(_mm_cvtsi32_si128(params->sse4_mul16.b_multiplier * (int32_t) *input_b), _MM_SHUFFLE(0, 0, 0, 0)),
diff --git a/src/qs8-vaddc/gen/minmax-sse41-mul16-ld64-x32.c b/src/qs8-vaddc/gen/minmax-sse41-mul16-ld64-x32.c
index e23ba02..6ee11e3 100644
--- a/src/qs8-vaddc/gen/minmax-sse41-mul16-ld64-x32.c
+++ b/src/qs8-vaddc/gen/minmax-sse41-mul16-ld64-x32.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__sse41_mul16_ld64_x32(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_add_epi32(
     _mm_shuffle_epi32(_mm_cvtsi32_si128(params->sse4_mul16.b_multiplier * (int32_t) *input_b), _MM_SHUFFLE(0, 0, 0, 0)),
diff --git a/src/qs8-vaddc/gen/minmax-sse41-mul16-ld64-x8.c b/src/qs8-vaddc/gen/minmax-sse41-mul16-ld64-x8.c
index f3c6a5a..d89d87e 100644
--- a/src/qs8-vaddc/gen/minmax-sse41-mul16-ld64-x8.c
+++ b/src/qs8-vaddc/gen/minmax-sse41-mul16-ld64-x8.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__sse41_mul16_ld64_x8(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_add_epi32(
     _mm_shuffle_epi32(_mm_cvtsi32_si128(params->sse4_mul16.b_multiplier * (int32_t) *input_b), _MM_SHUFFLE(0, 0, 0, 0)),
diff --git a/src/qs8-vaddc/gen/minmax-sse41-mul32-ld32-x16.c b/src/qs8-vaddc/gen/minmax-sse41-mul32-ld32-x16.c
index b387f24..2d4aaeb 100644
--- a/src/qs8-vaddc/gen/minmax-sse41-mul32-ld32-x16.c
+++ b/src/qs8-vaddc/gen/minmax-sse41-mul32-ld32-x16.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__sse41_mul32_ld32_x16(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
   const __m128i vrounding = _mm_load_si128((const __m128i*) params->sse4_mul32.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-sse41-mul32-ld32-x24.c b/src/qs8-vaddc/gen/minmax-sse41-mul32-ld32-x24.c
index 6e2aa6b..b748130 100644
--- a/src/qs8-vaddc/gen/minmax-sse41-mul32-ld32-x24.c
+++ b/src/qs8-vaddc/gen/minmax-sse41-mul32-ld32-x24.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__sse41_mul32_ld32_x24(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
   const __m128i vrounding = _mm_load_si128((const __m128i*) params->sse4_mul32.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-sse41-mul32-ld32-x32.c b/src/qs8-vaddc/gen/minmax-sse41-mul32-ld32-x32.c
index 0871e9a..7cfc51e 100644
--- a/src/qs8-vaddc/gen/minmax-sse41-mul32-ld32-x32.c
+++ b/src/qs8-vaddc/gen/minmax-sse41-mul32-ld32-x32.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__sse41_mul32_ld32_x32(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
   const __m128i vrounding = _mm_load_si128((const __m128i*) params->sse4_mul32.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-sse41-mul32-ld32-x8.c b/src/qs8-vaddc/gen/minmax-sse41-mul32-ld32-x8.c
index b80e4ed..b3e636a 100644
--- a/src/qs8-vaddc/gen/minmax-sse41-mul32-ld32-x8.c
+++ b/src/qs8-vaddc/gen/minmax-sse41-mul32-ld32-x8.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__sse41_mul32_ld32_x8(
@@ -20,7 +20,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
   const __m128i vrounding = _mm_load_si128((const __m128i*) params->sse4_mul32.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-wasmsimd-x16.c b/src/qs8-vaddc/gen/minmax-wasmsimd-x16.c
index 1344ff2..dd07539 100644
--- a/src/qs8-vaddc/gen/minmax-wasmsimd-x16.c
+++ b/src/qs8-vaddc/gen/minmax-wasmsimd-x16.c
@@ -11,7 +11,7 @@
 
 #include <wasm_simd128.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__wasmsimd_x16(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const v128_t va_multiplier = wasm_v128_load(params->wasmsimd.a_multiplier);
   const v128_t vrounding = wasm_v128_load(params->wasmsimd.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-wasmsimd-x24.c b/src/qs8-vaddc/gen/minmax-wasmsimd-x24.c
index 4cbf22d..24ec402 100644
--- a/src/qs8-vaddc/gen/minmax-wasmsimd-x24.c
+++ b/src/qs8-vaddc/gen/minmax-wasmsimd-x24.c
@@ -11,7 +11,7 @@
 
 #include <wasm_simd128.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__wasmsimd_x24(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const v128_t va_multiplier = wasm_v128_load(params->wasmsimd.a_multiplier);
   const v128_t vrounding = wasm_v128_load(params->wasmsimd.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-wasmsimd-x32.c b/src/qs8-vaddc/gen/minmax-wasmsimd-x32.c
index fef7a49..7c6c2c1 100644
--- a/src/qs8-vaddc/gen/minmax-wasmsimd-x32.c
+++ b/src/qs8-vaddc/gen/minmax-wasmsimd-x32.c
@@ -11,7 +11,7 @@
 
 #include <wasm_simd128.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__wasmsimd_x32(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const v128_t va_multiplier = wasm_v128_load(params->wasmsimd.a_multiplier);
   const v128_t vrounding = wasm_v128_load(params->wasmsimd.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-wasmsimd-x8.c b/src/qs8-vaddc/gen/minmax-wasmsimd-x8.c
index 7cc5dcb..eb541dc 100644
--- a/src/qs8-vaddc/gen/minmax-wasmsimd-x8.c
+++ b/src/qs8-vaddc/gen/minmax-wasmsimd-x8.c
@@ -11,7 +11,7 @@
 
 #include <wasm_simd128.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__wasmsimd_x8(
@@ -19,7 +19,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const v128_t va_multiplier = wasm_v128_load(params->wasmsimd.a_multiplier);
   const v128_t vrounding = wasm_v128_load(params->wasmsimd.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-xop-mul32-ld32-x16.c b/src/qs8-vaddc/gen/minmax-xop-mul32-ld32-x16.c
index f9113b8..f92fd6e 100644
--- a/src/qs8-vaddc/gen/minmax-xop-mul32-ld32-x16.c
+++ b/src/qs8-vaddc/gen/minmax-xop-mul32-ld32-x16.c
@@ -17,7 +17,7 @@
 #endif
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__xop_mul32_ld32_x16(
@@ -25,7 +25,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
   const __m128i vrounding = _mm_load_si128((const __m128i*) params->sse4_mul32.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-xop-mul32-ld32-x24.c b/src/qs8-vaddc/gen/minmax-xop-mul32-ld32-x24.c
index 3f33ead..af73d75 100644
--- a/src/qs8-vaddc/gen/minmax-xop-mul32-ld32-x24.c
+++ b/src/qs8-vaddc/gen/minmax-xop-mul32-ld32-x24.c
@@ -17,7 +17,7 @@
 #endif
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__xop_mul32_ld32_x24(
@@ -25,7 +25,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
   const __m128i vrounding = _mm_load_si128((const __m128i*) params->sse4_mul32.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-xop-mul32-ld32-x32.c b/src/qs8-vaddc/gen/minmax-xop-mul32-ld32-x32.c
index 3b89fc2..d59dcb3 100644
--- a/src/qs8-vaddc/gen/minmax-xop-mul32-ld32-x32.c
+++ b/src/qs8-vaddc/gen/minmax-xop-mul32-ld32-x32.c
@@ -17,7 +17,7 @@
 #endif
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__xop_mul32_ld32_x32(
@@ -25,7 +25,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
   const __m128i vrounding = _mm_load_si128((const __m128i*) params->sse4_mul32.rounding);
diff --git a/src/qs8-vaddc/gen/minmax-xop-mul32-ld32-x8.c b/src/qs8-vaddc/gen/minmax-xop-mul32-ld32-x8.c
index 71ed202..a4e3df3 100644
--- a/src/qs8-vaddc/gen/minmax-xop-mul32-ld32-x8.c
+++ b/src/qs8-vaddc/gen/minmax-xop-mul32-ld32-x8.c
@@ -17,7 +17,7 @@
 #endif
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qs8_vaddc_minmax_ukernel__xop_mul32_ld32_x8(
@@ -25,7 +25,7 @@
     const int8_t* input_a,
     const int8_t* input_b,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qs8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4_mul32.a_multiplier);
   const __m128i vrounding = _mm_load_si128((const __m128i*) params->sse4_mul32.rounding);
diff --git a/src/qs8-vaddc/neon.c.in b/src/qs8-vaddc/neon.c.in
index 2a391cc..8f0a762 100644
--- a/src/qs8-vaddc/neon.c.in
+++ b/src/qs8-vaddc/neon.c.in
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 $XINT8_T = {"QS8": "int8_t", "QU8": "uint8_t"}[DATATYPE]
@@ -39,7 +39,7 @@
     const ${XINT8_T}* input_a,
     const ${XINT8_T}* input_b,
     ${XINT8_T}* output,
-    const union xnn_${DATATYPE.lower()}_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_${DATATYPE.lower()}_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   $if LD128:
     #if XNN_ARCH_ARM64
diff --git a/src/qs8-vaddc/scalar.c.in b/src/qs8-vaddc/scalar.c.in
index 0b5b922..0dfcaca 100644
--- a/src/qs8-vaddc/scalar.c.in
+++ b/src/qs8-vaddc/scalar.c.in
@@ -8,7 +8,7 @@
 #include <assert.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 $XINT8_T = {"QS8": "int8_t", "QU8": "uint8_t"}[DATATYPE]
@@ -17,7 +17,7 @@
     const ${XINT8_T}* input_a,
     const ${XINT8_T}* input_b,
     ${XINT8_T}* output,
-    const union xnn_${DATATYPE.lower()}_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
+    const union xnn_${DATATYPE.lower()}_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
 {
   const int32_t vbias = params->scalar.bias + (int32_t) *input_b * params->scalar.b_multiplier;
   const int32_t va_multiplier = params->scalar.a_multiplier;
diff --git a/src/qs8-vaddc/sse-mul16-ld64.c.in b/src/qs8-vaddc/sse-mul16-ld64.c.in
index f01403a..6dc36dd 100644
--- a/src/qs8-vaddc/sse-mul16-ld64.c.in
+++ b/src/qs8-vaddc/sse-mul16-ld64.c.in
@@ -14,7 +14,7 @@
 
 #include <${SSE_HEADER}>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 $PARAMS_STRUCT = "sse4_mul16" if SSE == 4 and DATATYPE == "QS8" else "sse2"
@@ -29,7 +29,7 @@
     const ${XINT8_T}* input_a,
     const ${XINT8_T}* input_b,
     ${XINT8_T}* output,
-    const union xnn_${DATATYPE.lower()}_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_${DATATYPE.lower()}_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_add_epi32(
     _mm_shuffle_epi32(_mm_cvtsi32_si128(params->${PARAMS_STRUCT}.b_multiplier * (int32_t) *input_b), _MM_SHUFFLE(0, 0, 0, 0)),
diff --git a/src/qs8-vaddc/sse-mul32-ld32.c.in b/src/qs8-vaddc/sse-mul32-ld32.c.in
index f4d0cb4..ff1a22e 100644
--- a/src/qs8-vaddc/sse-mul32-ld32.c.in
+++ b/src/qs8-vaddc/sse-mul32-ld32.c.in
@@ -22,7 +22,7 @@
   #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 $PARAMS_STRUCT = {"QS8": "sse4_mul32", "QU8": "sse4"}[DATATYPE]
@@ -37,7 +37,7 @@
     const ${XINT8_T}* input_a,
     const ${XINT8_T}* input_b,
     ${XINT8_T}* output,
-    const union xnn_${DATATYPE.lower()}_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_${DATATYPE.lower()}_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->${PARAMS_STRUCT}.a_multiplier);
   const __m128i vrounding = _mm_load_si128((const __m128i*) params->${PARAMS_STRUCT}.rounding);
diff --git a/src/qs8-vaddc/wasmsimd.c.in b/src/qs8-vaddc/wasmsimd.c.in
index bbb5834..2018517 100644
--- a/src/qs8-vaddc/wasmsimd.c.in
+++ b/src/qs8-vaddc/wasmsimd.c.in
@@ -11,7 +11,7 @@
 
 #include <wasm_simd128.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 $XINT8_T = {"QS8": "int8_t", "QU8": "uint8_t"}[DATATYPE]
@@ -26,7 +26,7 @@
     const ${XINT8_T}* input_a,
     const ${XINT8_T}* input_b,
     ${XINT8_T}* output,
-    const union xnn_${DATATYPE.lower()}_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_${DATATYPE.lower()}_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const v128_t va_multiplier = wasm_v128_load(params->wasmsimd.a_multiplier);
   const v128_t vrounding = wasm_v128_load(params->wasmsimd.rounding);
diff --git a/src/qs8-vmul/gen/minmax-fp32-neon-ld128-x16.c b/src/qs8-vmul/gen/minmax-fp32-neon-ld128-x16.c
index 046276c..561b144 100644
--- a/src/qs8-vmul/gen/minmax-fp32-neon-ld128-x16.c
+++ b/src/qs8-vmul/gen/minmax-fp32-neon-ld128-x16.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qs8_vmul_minmax_fp32_ukernel__neon_ld128_x16(
diff --git a/src/qs8-vmul/gen/minmax-fp32-neon-ld64-x16.c b/src/qs8-vmul/gen/minmax-fp32-neon-ld64-x16.c
index c21332a..2deee94 100644
--- a/src/qs8-vmul/gen/minmax-fp32-neon-ld64-x16.c
+++ b/src/qs8-vmul/gen/minmax-fp32-neon-ld64-x16.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qs8_vmul_minmax_fp32_ukernel__neon_ld64_x16(
diff --git a/src/qs8-vmul/gen/minmax-fp32-neon-ld64-x8.c b/src/qs8-vmul/gen/minmax-fp32-neon-ld64-x8.c
index db11ce3..715579b 100644
--- a/src/qs8-vmul/gen/minmax-fp32-neon-ld64-x8.c
+++ b/src/qs8-vmul/gen/minmax-fp32-neon-ld64-x8.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qs8_vmul_minmax_fp32_ukernel__neon_ld64_x8(
diff --git a/src/qs8-vmul/gen/minmax-fp32-neonv8-ld128-x16.c b/src/qs8-vmul/gen/minmax-fp32-neonv8-ld128-x16.c
index 4076c0c..8425e15 100644
--- a/src/qs8-vmul/gen/minmax-fp32-neonv8-ld128-x16.c
+++ b/src/qs8-vmul/gen/minmax-fp32-neonv8-ld128-x16.c
@@ -12,7 +12,7 @@
 #include <arm_neon.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qs8_vmul_minmax_fp32_ukernel__neonv8_ld128_x16(
diff --git a/src/qs8-vmul/gen/minmax-fp32-neonv8-ld64-x16.c b/src/qs8-vmul/gen/minmax-fp32-neonv8-ld64-x16.c
index c0d6635..0841c77 100644
--- a/src/qs8-vmul/gen/minmax-fp32-neonv8-ld64-x16.c
+++ b/src/qs8-vmul/gen/minmax-fp32-neonv8-ld64-x16.c
@@ -12,7 +12,7 @@
 #include <arm_neon.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qs8_vmul_minmax_fp32_ukernel__neonv8_ld64_x16(
diff --git a/src/qs8-vmul/gen/minmax-fp32-neonv8-ld64-x8.c b/src/qs8-vmul/gen/minmax-fp32-neonv8-ld64-x8.c
index 3bca1fa..b730a7d 100644
--- a/src/qs8-vmul/gen/minmax-fp32-neonv8-ld64-x8.c
+++ b/src/qs8-vmul/gen/minmax-fp32-neonv8-ld64-x8.c
@@ -12,7 +12,7 @@
 #include <arm_neon.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qs8_vmul_minmax_fp32_ukernel__neonv8_ld64_x8(
diff --git a/src/qs8-vmul/gen/minmax-fp32-scalar-x1.c b/src/qs8-vmul/gen/minmax-fp32-scalar-x1.c
index 3319ff3..29e25bb 100644
--- a/src/qs8-vmul/gen/minmax-fp32-scalar-x1.c
+++ b/src/qs8-vmul/gen/minmax-fp32-scalar-x1.c
@@ -12,7 +12,7 @@
 #include <fp16.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qs8_vmul_minmax_fp32_ukernel__scalar_x1(
diff --git a/src/qs8-vmul/gen/minmax-fp32-scalar-x2.c b/src/qs8-vmul/gen/minmax-fp32-scalar-x2.c
index 1d3814e..160184b 100644
--- a/src/qs8-vmul/gen/minmax-fp32-scalar-x2.c
+++ b/src/qs8-vmul/gen/minmax-fp32-scalar-x2.c
@@ -12,7 +12,7 @@
 #include <fp16.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qs8_vmul_minmax_fp32_ukernel__scalar_x2(
diff --git a/src/qs8-vmul/gen/minmax-fp32-scalar-x4.c b/src/qs8-vmul/gen/minmax-fp32-scalar-x4.c
index 93027ed..e2397ea 100644
--- a/src/qs8-vmul/gen/minmax-fp32-scalar-x4.c
+++ b/src/qs8-vmul/gen/minmax-fp32-scalar-x4.c
@@ -12,7 +12,7 @@
 #include <fp16.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qs8_vmul_minmax_fp32_ukernel__scalar_x4(
diff --git a/src/qs8-vmul/neon.c.in b/src/qs8-vmul/neon.c.in
index fb36a9e..a919f6d 100644
--- a/src/qs8-vmul/neon.c.in
+++ b/src/qs8-vmul/neon.c.in
@@ -14,7 +14,7 @@
 
 $if REQUANTIZATION == "FP32" and ARMV8:
   #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 $PARAMS_STRUCT = REQUANTIZATION.lower() + "_" + ("neonv8" if ARMV8 else "neon")
diff --git a/src/qs8-vmul/scalar.c.in b/src/qs8-vmul/scalar.c.in
index 266815c..5fdee20 100644
--- a/src/qs8-vmul/scalar.c.in
+++ b/src/qs8-vmul/scalar.c.in
@@ -11,7 +11,7 @@
 #include <fp16.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 $XINT8_T = {"QS8": "int8_t", "QU8": "uint8_t"}[DATATYPE]
diff --git a/src/qs8-vmulc/gen/minmax-fp32-neon-ld128-x16.c b/src/qs8-vmulc/gen/minmax-fp32-neon-ld128-x16.c
index 85c76ef..01b89c1 100644
--- a/src/qs8-vmulc/gen/minmax-fp32-neon-ld128-x16.c
+++ b/src/qs8-vmulc/gen/minmax-fp32-neon-ld128-x16.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qs8_vmulc_minmax_fp32_ukernel__neon_ld128_x16(
diff --git a/src/qs8-vmulc/gen/minmax-fp32-neon-ld64-x16.c b/src/qs8-vmulc/gen/minmax-fp32-neon-ld64-x16.c
index 2f3bd15..a039b5c 100644
--- a/src/qs8-vmulc/gen/minmax-fp32-neon-ld64-x16.c
+++ b/src/qs8-vmulc/gen/minmax-fp32-neon-ld64-x16.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qs8_vmulc_minmax_fp32_ukernel__neon_ld64_x16(
diff --git a/src/qs8-vmulc/gen/minmax-fp32-neon-ld64-x8.c b/src/qs8-vmulc/gen/minmax-fp32-neon-ld64-x8.c
index e42ba5c..8ced891 100644
--- a/src/qs8-vmulc/gen/minmax-fp32-neon-ld64-x8.c
+++ b/src/qs8-vmulc/gen/minmax-fp32-neon-ld64-x8.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qs8_vmulc_minmax_fp32_ukernel__neon_ld64_x8(
diff --git a/src/qs8-vmulc/gen/minmax-fp32-neonv8-ld128-x16.c b/src/qs8-vmulc/gen/minmax-fp32-neonv8-ld128-x16.c
index 1f91230..62d23a8 100644
--- a/src/qs8-vmulc/gen/minmax-fp32-neonv8-ld128-x16.c
+++ b/src/qs8-vmulc/gen/minmax-fp32-neonv8-ld128-x16.c
@@ -12,7 +12,7 @@
 #include <arm_neon.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qs8_vmulc_minmax_fp32_ukernel__neonv8_ld128_x16(
diff --git a/src/qs8-vmulc/gen/minmax-fp32-neonv8-ld64-x16.c b/src/qs8-vmulc/gen/minmax-fp32-neonv8-ld64-x16.c
index 77647f2..3cfc2a3 100644
--- a/src/qs8-vmulc/gen/minmax-fp32-neonv8-ld64-x16.c
+++ b/src/qs8-vmulc/gen/minmax-fp32-neonv8-ld64-x16.c
@@ -12,7 +12,7 @@
 #include <arm_neon.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qs8_vmulc_minmax_fp32_ukernel__neonv8_ld64_x16(
diff --git a/src/qs8-vmulc/gen/minmax-fp32-neonv8-ld64-x8.c b/src/qs8-vmulc/gen/minmax-fp32-neonv8-ld64-x8.c
index a7bcc63..931c2db 100644
--- a/src/qs8-vmulc/gen/minmax-fp32-neonv8-ld64-x8.c
+++ b/src/qs8-vmulc/gen/minmax-fp32-neonv8-ld64-x8.c
@@ -12,7 +12,7 @@
 #include <arm_neon.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qs8_vmulc_minmax_fp32_ukernel__neonv8_ld64_x8(
diff --git a/src/qs8-vmulc/gen/minmax-fp32-scalar-x1.c b/src/qs8-vmulc/gen/minmax-fp32-scalar-x1.c
index 89f5392..64b8ec5 100644
--- a/src/qs8-vmulc/gen/minmax-fp32-scalar-x1.c
+++ b/src/qs8-vmulc/gen/minmax-fp32-scalar-x1.c
@@ -12,7 +12,7 @@
 #include <fp16.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qs8_vmulc_minmax_fp32_ukernel__scalar_x1(
diff --git a/src/qs8-vmulc/gen/minmax-fp32-scalar-x2.c b/src/qs8-vmulc/gen/minmax-fp32-scalar-x2.c
index 6d648c3..c5c0b64 100644
--- a/src/qs8-vmulc/gen/minmax-fp32-scalar-x2.c
+++ b/src/qs8-vmulc/gen/minmax-fp32-scalar-x2.c
@@ -12,7 +12,7 @@
 #include <fp16.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qs8_vmulc_minmax_fp32_ukernel__scalar_x2(
diff --git a/src/qs8-vmulc/gen/minmax-fp32-scalar-x4.c b/src/qs8-vmulc/gen/minmax-fp32-scalar-x4.c
index 8dd3bff..40aa316 100644
--- a/src/qs8-vmulc/gen/minmax-fp32-scalar-x4.c
+++ b/src/qs8-vmulc/gen/minmax-fp32-scalar-x4.c
@@ -12,7 +12,7 @@
 #include <fp16.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qs8_vmulc_minmax_fp32_ukernel__scalar_x4(
diff --git a/src/qs8-vmulc/neon.c.in b/src/qs8-vmulc/neon.c.in
index 4172773..b8eb01b 100644
--- a/src/qs8-vmulc/neon.c.in
+++ b/src/qs8-vmulc/neon.c.in
@@ -14,7 +14,7 @@
 
 $if REQUANTIZATION == "FP32" and ARMV8:
   #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 $PARAMS_STRUCT = REQUANTIZATION.lower() + "_" + ("neonv8" if ARMV8 else "neon")
diff --git a/src/qs8-vmulc/scalar.c.in b/src/qs8-vmulc/scalar.c.in
index adb6556..72162b4 100644
--- a/src/qs8-vmulc/scalar.c.in
+++ b/src/qs8-vmulc/scalar.c.in
@@ -11,7 +11,7 @@
 #include <fp16.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 $XINT8_T = {"QS8": "int8_t", "QU8": "uint8_t"}[DATATYPE]
diff --git a/src/qu8-vadd/gen/minmax-avx-mul16-ld64-x16.c b/src/qu8-vadd/gen/minmax-avx-mul16-ld64-x16.c
index d3d1c05..084fbde 100644
--- a/src/qu8-vadd/gen/minmax-avx-mul16-ld64-x16.c
+++ b/src/qu8-vadd/gen/minmax-avx-mul16-ld64-x16.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__avx_mul16_ld64_x16(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse2.bias);
   const __m128i va_multiplier_lo = _mm_load_si128((const __m128i*) params->sse2.a_multiplier_lo);
diff --git a/src/qu8-vadd/gen/minmax-avx-mul16-ld64-x8.c b/src/qu8-vadd/gen/minmax-avx-mul16-ld64-x8.c
index 2f8e08e..a76b598 100644
--- a/src/qu8-vadd/gen/minmax-avx-mul16-ld64-x8.c
+++ b/src/qu8-vadd/gen/minmax-avx-mul16-ld64-x8.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__avx_mul16_ld64_x8(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse2.bias);
   const __m128i va_multiplier_lo = _mm_load_si128((const __m128i*) params->sse2.a_multiplier_lo);
diff --git a/src/qu8-vadd/gen/minmax-avx-mul32-ld32-x16.c b/src/qu8-vadd/gen/minmax-avx-mul32-ld32-x16.c
index cc4b32a..398907e 100644
--- a/src/qu8-vadd/gen/minmax-avx-mul32-ld32-x16.c
+++ b/src/qu8-vadd/gen/minmax-avx-mul32-ld32-x16.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__avx_mul32_ld32_x16(
@@ -20,7 +20,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4.bias);
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4.a_multiplier);
diff --git a/src/qu8-vadd/gen/minmax-avx-mul32-ld32-x8.c b/src/qu8-vadd/gen/minmax-avx-mul32-ld32-x8.c
index dad1691..1aac429 100644
--- a/src/qu8-vadd/gen/minmax-avx-mul32-ld32-x8.c
+++ b/src/qu8-vadd/gen/minmax-avx-mul32-ld32-x8.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__avx_mul32_ld32_x8(
@@ -20,7 +20,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4.bias);
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4.a_multiplier);
diff --git a/src/qu8-vadd/gen/minmax-avx2-mul32-ld64-x16.c b/src/qu8-vadd/gen/minmax-avx2-mul32-ld64-x16.c
index 40c7550..e8e8512 100644
--- a/src/qu8-vadd/gen/minmax-avx2-mul32-ld64-x16.c
+++ b/src/qu8-vadd/gen/minmax-avx2-mul32-ld64-x16.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__avx2_mul32_ld64_x16(
@@ -20,7 +20,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m256i vbias = _mm256_load_si256((const __m256i*) params->avx2.bias);
   const __m256i va_multiplier = _mm256_load_si256((const __m256i*) params->avx2.a_multiplier);
diff --git a/src/qu8-vadd/gen/minmax-avx2-mul32-ld64-x8.c b/src/qu8-vadd/gen/minmax-avx2-mul32-ld64-x8.c
index 13ea608..5af1253 100644
--- a/src/qu8-vadd/gen/minmax-avx2-mul32-ld64-x8.c
+++ b/src/qu8-vadd/gen/minmax-avx2-mul32-ld64-x8.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__avx2_mul32_ld64_x8(
@@ -20,7 +20,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m256i vbias = _mm256_load_si256((const __m256i*) params->avx2.bias);
   const __m256i va_multiplier = _mm256_load_si256((const __m256i*) params->avx2.a_multiplier);
diff --git a/src/qu8-vadd/gen/minmax-avx512skx-mul32-ld128-x16.c b/src/qu8-vadd/gen/minmax-avx512skx-mul32-ld128-x16.c
index 0c52370..77b83b5 100644
--- a/src/qu8-vadd/gen/minmax-avx512skx-mul32-ld128-x16.c
+++ b/src/qu8-vadd/gen/minmax-avx512skx-mul32-ld128-x16.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__avx512skx_mul32_ld128_x16(
@@ -20,7 +20,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m512i vbias = _mm512_load_si512(params->avx512.bias);
   const __m512i va_multiplier = _mm512_load_si512(params->avx512.a_multiplier);
diff --git a/src/qu8-vadd/gen/minmax-avx512skx-mul32-ld128-x32.c b/src/qu8-vadd/gen/minmax-avx512skx-mul32-ld128-x32.c
index 49439a8..62485ed 100644
--- a/src/qu8-vadd/gen/minmax-avx512skx-mul32-ld128-x32.c
+++ b/src/qu8-vadd/gen/minmax-avx512skx-mul32-ld128-x32.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__avx512skx_mul32_ld128_x32(
@@ -20,7 +20,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m512i vbias = _mm512_load_si512(params->avx512.bias);
   const __m512i va_multiplier = _mm512_load_si512(params->avx512.a_multiplier);
diff --git a/src/qu8-vadd/gen/minmax-neon-ld128-x16.c b/src/qu8-vadd/gen/minmax-neon-ld128-x16.c
index 6049320..90cbacb 100644
--- a/src/qu8-vadd/gen/minmax-neon-ld128-x16.c
+++ b/src/qu8-vadd/gen/minmax-neon-ld128-x16.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__neon_ld128_x16(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   #if XNN_ARCH_ARM64
     const uint8x16_t va_zero_point = vld1q_dup_u8(&params->neon.a_zero_point);
diff --git a/src/qu8-vadd/gen/minmax-neon-ld64-x16.c b/src/qu8-vadd/gen/minmax-neon-ld64-x16.c
index 51bcdd2..dd8ea97 100644
--- a/src/qu8-vadd/gen/minmax-neon-ld64-x16.c
+++ b/src/qu8-vadd/gen/minmax-neon-ld64-x16.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__neon_ld64_x16(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const uint8x8_t va_zero_point = vld1_dup_u8(&params->neon.a_zero_point);
   const uint8x8_t vb_zero_point = vld1_dup_u8(&params->neon.b_zero_point);
diff --git a/src/qu8-vadd/gen/minmax-neon-ld64-x32.c b/src/qu8-vadd/gen/minmax-neon-ld64-x32.c
index f9a1997..0dc9c17 100644
--- a/src/qu8-vadd/gen/minmax-neon-ld64-x32.c
+++ b/src/qu8-vadd/gen/minmax-neon-ld64-x32.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__neon_ld64_x32(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const uint8x8_t va_zero_point = vld1_dup_u8(&params->neon.a_zero_point);
   const uint8x8_t vb_zero_point = vld1_dup_u8(&params->neon.b_zero_point);
diff --git a/src/qu8-vadd/gen/minmax-neon-ld64-x8.c b/src/qu8-vadd/gen/minmax-neon-ld64-x8.c
index 6c4ccbe..6f19714 100644
--- a/src/qu8-vadd/gen/minmax-neon-ld64-x8.c
+++ b/src/qu8-vadd/gen/minmax-neon-ld64-x8.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__neon_ld64_x8(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const uint8x8_t va_zero_point = vld1_dup_u8(&params->neon.a_zero_point);
   const uint8x8_t vb_zero_point = vld1_dup_u8(&params->neon.b_zero_point);
diff --git a/src/qu8-vadd/gen/minmax-scalar-x1.c b/src/qu8-vadd/gen/minmax-scalar-x1.c
index a2684e0..0bdc27d 100644
--- a/src/qu8-vadd/gen/minmax-scalar-x1.c
+++ b/src/qu8-vadd/gen/minmax-scalar-x1.c
@@ -10,7 +10,7 @@
 #include <assert.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__scalar_x1(
@@ -18,7 +18,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
 {
   const int32_t vbias = params->scalar.bias;
   const int32_t va_multiplier = params->scalar.a_multiplier;
diff --git a/src/qu8-vadd/gen/minmax-scalar-x2.c b/src/qu8-vadd/gen/minmax-scalar-x2.c
index 00fd437..d27e573 100644
--- a/src/qu8-vadd/gen/minmax-scalar-x2.c
+++ b/src/qu8-vadd/gen/minmax-scalar-x2.c
@@ -10,7 +10,7 @@
 #include <assert.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__scalar_x2(
@@ -18,7 +18,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
 {
   const int32_t vbias = params->scalar.bias;
   const int32_t va_multiplier = params->scalar.a_multiplier;
diff --git a/src/qu8-vadd/gen/minmax-scalar-x4.c b/src/qu8-vadd/gen/minmax-scalar-x4.c
index 5f9237e..5a0232c 100644
--- a/src/qu8-vadd/gen/minmax-scalar-x4.c
+++ b/src/qu8-vadd/gen/minmax-scalar-x4.c
@@ -10,7 +10,7 @@
 #include <assert.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__scalar_x4(
@@ -18,7 +18,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
 {
   const int32_t vbias = params->scalar.bias;
   const int32_t va_multiplier = params->scalar.a_multiplier;
diff --git a/src/qu8-vadd/gen/minmax-sse2-mul16-ld64-x16.c b/src/qu8-vadd/gen/minmax-sse2-mul16-ld64-x16.c
index c59bc57..6496f37 100644
--- a/src/qu8-vadd/gen/minmax-sse2-mul16-ld64-x16.c
+++ b/src/qu8-vadd/gen/minmax-sse2-mul16-ld64-x16.c
@@ -11,7 +11,7 @@
 
 #include <emmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__sse2_mul16_ld64_x16(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse2.bias);
   const __m128i va_multiplier_lo = _mm_load_si128((const __m128i*) params->sse2.a_multiplier_lo);
diff --git a/src/qu8-vadd/gen/minmax-sse2-mul16-ld64-x8.c b/src/qu8-vadd/gen/minmax-sse2-mul16-ld64-x8.c
index 68f1c8f..b80edde 100644
--- a/src/qu8-vadd/gen/minmax-sse2-mul16-ld64-x8.c
+++ b/src/qu8-vadd/gen/minmax-sse2-mul16-ld64-x8.c
@@ -11,7 +11,7 @@
 
 #include <emmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__sse2_mul16_ld64_x8(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse2.bias);
   const __m128i va_multiplier_lo = _mm_load_si128((const __m128i*) params->sse2.a_multiplier_lo);
diff --git a/src/qu8-vadd/gen/minmax-sse41-mul16-ld64-x16.c b/src/qu8-vadd/gen/minmax-sse41-mul16-ld64-x16.c
index 260ae6c..441d3c0 100644
--- a/src/qu8-vadd/gen/minmax-sse41-mul16-ld64-x16.c
+++ b/src/qu8-vadd/gen/minmax-sse41-mul16-ld64-x16.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__sse41_mul16_ld64_x16(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse2.bias);
   const __m128i va_multiplier_lo = _mm_load_si128((const __m128i*) params->sse2.a_multiplier_lo);
diff --git a/src/qu8-vadd/gen/minmax-sse41-mul16-ld64-x8.c b/src/qu8-vadd/gen/minmax-sse41-mul16-ld64-x8.c
index 70fcb29..19b9503 100644
--- a/src/qu8-vadd/gen/minmax-sse41-mul16-ld64-x8.c
+++ b/src/qu8-vadd/gen/minmax-sse41-mul16-ld64-x8.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__sse41_mul16_ld64_x8(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse2.bias);
   const __m128i va_multiplier_lo = _mm_load_si128((const __m128i*) params->sse2.a_multiplier_lo);
diff --git a/src/qu8-vadd/gen/minmax-sse41-mul32-ld32-x16.c b/src/qu8-vadd/gen/minmax-sse41-mul32-ld32-x16.c
index e7809a6..98a5d85 100644
--- a/src/qu8-vadd/gen/minmax-sse41-mul32-ld32-x16.c
+++ b/src/qu8-vadd/gen/minmax-sse41-mul32-ld32-x16.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__sse41_mul32_ld32_x16(
@@ -20,7 +20,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4.bias);
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4.a_multiplier);
diff --git a/src/qu8-vadd/gen/minmax-sse41-mul32-ld32-x8.c b/src/qu8-vadd/gen/minmax-sse41-mul32-ld32-x8.c
index 11fbc54..93901a4 100644
--- a/src/qu8-vadd/gen/minmax-sse41-mul32-ld32-x8.c
+++ b/src/qu8-vadd/gen/minmax-sse41-mul32-ld32-x8.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__sse41_mul32_ld32_x8(
@@ -20,7 +20,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4.bias);
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4.a_multiplier);
diff --git a/src/qu8-vadd/gen/minmax-wasmsimd-x16.c b/src/qu8-vadd/gen/minmax-wasmsimd-x16.c
index 5df5c39..e37866e 100644
--- a/src/qu8-vadd/gen/minmax-wasmsimd-x16.c
+++ b/src/qu8-vadd/gen/minmax-wasmsimd-x16.c
@@ -11,7 +11,7 @@
 
 #include <wasm_simd128.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__wasmsimd_x16(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const v128_t vbias = wasm_v128_load(params->wasmsimd.bias);
   const v128_t va_multiplier = wasm_v128_load(params->wasmsimd.a_multiplier);
diff --git a/src/qu8-vadd/gen/minmax-wasmsimd-x8.c b/src/qu8-vadd/gen/minmax-wasmsimd-x8.c
index 3fd1703..77dc684 100644
--- a/src/qu8-vadd/gen/minmax-wasmsimd-x8.c
+++ b/src/qu8-vadd/gen/minmax-wasmsimd-x8.c
@@ -11,7 +11,7 @@
 
 #include <wasm_simd128.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__wasmsimd_x8(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const v128_t vbias = wasm_v128_load(params->wasmsimd.bias);
   const v128_t va_multiplier = wasm_v128_load(params->wasmsimd.a_multiplier);
diff --git a/src/qu8-vadd/gen/minmax-xop-mul32-ld32-x16.c b/src/qu8-vadd/gen/minmax-xop-mul32-ld32-x16.c
index 7d60fab..1a128da 100644
--- a/src/qu8-vadd/gen/minmax-xop-mul32-ld32-x16.c
+++ b/src/qu8-vadd/gen/minmax-xop-mul32-ld32-x16.c
@@ -17,7 +17,7 @@
 #endif
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__xop_mul32_ld32_x16(
@@ -25,7 +25,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4.bias);
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4.a_multiplier);
diff --git a/src/qu8-vadd/gen/minmax-xop-mul32-ld32-x8.c b/src/qu8-vadd/gen/minmax-xop-mul32-ld32-x8.c
index 483db71..13a6999 100644
--- a/src/qu8-vadd/gen/minmax-xop-mul32-ld32-x8.c
+++ b/src/qu8-vadd/gen/minmax-xop-mul32-ld32-x8.c
@@ -17,7 +17,7 @@
 #endif
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vadd_minmax_ukernel__xop_mul32_ld32_x8(
@@ -25,7 +25,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_load_si128((const __m128i*) params->sse4.bias);
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4.a_multiplier);
diff --git a/src/qu8-vaddc/gen/minmax-avx-mul16-ld64-x16.c b/src/qu8-vaddc/gen/minmax-avx-mul16-ld64-x16.c
index 8be6ef0..9bfae04 100644
--- a/src/qu8-vaddc/gen/minmax-avx-mul16-ld64-x16.c
+++ b/src/qu8-vaddc/gen/minmax-avx-mul16-ld64-x16.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__avx_mul16_ld64_x16(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_add_epi32(
     _mm_shuffle_epi32(_mm_cvtsi32_si128(params->sse2.b_multiplier * (int32_t) *input_b), _MM_SHUFFLE(0, 0, 0, 0)),
diff --git a/src/qu8-vaddc/gen/minmax-avx-mul16-ld64-x8.c b/src/qu8-vaddc/gen/minmax-avx-mul16-ld64-x8.c
index d8d9f29..53894d3 100644
--- a/src/qu8-vaddc/gen/minmax-avx-mul16-ld64-x8.c
+++ b/src/qu8-vaddc/gen/minmax-avx-mul16-ld64-x8.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__avx_mul16_ld64_x8(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_add_epi32(
     _mm_shuffle_epi32(_mm_cvtsi32_si128(params->sse2.b_multiplier * (int32_t) *input_b), _MM_SHUFFLE(0, 0, 0, 0)),
diff --git a/src/qu8-vaddc/gen/minmax-avx-mul32-ld32-x16.c b/src/qu8-vaddc/gen/minmax-avx-mul32-ld32-x16.c
index 5dbaca2..3167bcc 100644
--- a/src/qu8-vaddc/gen/minmax-avx-mul32-ld32-x16.c
+++ b/src/qu8-vaddc/gen/minmax-avx-mul32-ld32-x16.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__avx_mul32_ld32_x16(
@@ -20,7 +20,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4.a_multiplier);
   const __m128i vrounding = _mm_load_si128((const __m128i*) params->sse4.rounding);
diff --git a/src/qu8-vaddc/gen/minmax-avx-mul32-ld32-x8.c b/src/qu8-vaddc/gen/minmax-avx-mul32-ld32-x8.c
index 8565698..c67836c 100644
--- a/src/qu8-vaddc/gen/minmax-avx-mul32-ld32-x8.c
+++ b/src/qu8-vaddc/gen/minmax-avx-mul32-ld32-x8.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__avx_mul32_ld32_x8(
@@ -20,7 +20,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4.a_multiplier);
   const __m128i vrounding = _mm_load_si128((const __m128i*) params->sse4.rounding);
diff --git a/src/qu8-vaddc/gen/minmax-avx2-mul32-ld64-x16.c b/src/qu8-vaddc/gen/minmax-avx2-mul32-ld64-x16.c
index 380bc77..b0ce301 100644
--- a/src/qu8-vaddc/gen/minmax-avx2-mul32-ld64-x16.c
+++ b/src/qu8-vaddc/gen/minmax-avx2-mul32-ld64-x16.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__avx2_mul32_ld64_x16(
@@ -20,7 +20,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m256i va_multiplier = _mm256_load_si256((const __m256i*) params->avx2.a_multiplier);
   const __m256i vrounding = _mm256_load_si256((const __m256i*) params->avx2.rounding);
diff --git a/src/qu8-vaddc/gen/minmax-avx2-mul32-ld64-x8.c b/src/qu8-vaddc/gen/minmax-avx2-mul32-ld64-x8.c
index 418e2f1..2af5f7b 100644
--- a/src/qu8-vaddc/gen/minmax-avx2-mul32-ld64-x8.c
+++ b/src/qu8-vaddc/gen/minmax-avx2-mul32-ld64-x8.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__avx2_mul32_ld64_x8(
@@ -20,7 +20,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m256i va_multiplier = _mm256_load_si256((const __m256i*) params->avx2.a_multiplier);
   const __m256i vrounding = _mm256_load_si256((const __m256i*) params->avx2.rounding);
diff --git a/src/qu8-vaddc/gen/minmax-avx512skx-mul32-ld128-x16.c b/src/qu8-vaddc/gen/minmax-avx512skx-mul32-ld128-x16.c
index 9f98f78..b444a19 100644
--- a/src/qu8-vaddc/gen/minmax-avx512skx-mul32-ld128-x16.c
+++ b/src/qu8-vaddc/gen/minmax-avx512skx-mul32-ld128-x16.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__avx512skx_mul32_ld128_x16(
@@ -20,7 +20,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m512i va_multiplier = _mm512_load_si512(params->avx512.a_multiplier);
   const __m512i vrounding = _mm512_load_si512(params->avx512.rounding);
diff --git a/src/qu8-vaddc/gen/minmax-avx512skx-mul32-ld128-x32.c b/src/qu8-vaddc/gen/minmax-avx512skx-mul32-ld128-x32.c
index 7b55384..1572762 100644
--- a/src/qu8-vaddc/gen/minmax-avx512skx-mul32-ld128-x32.c
+++ b/src/qu8-vaddc/gen/minmax-avx512skx-mul32-ld128-x32.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__avx512skx_mul32_ld128_x32(
@@ -20,7 +20,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m512i va_multiplier = _mm512_load_si512(params->avx512.a_multiplier);
   const __m512i vrounding = _mm512_load_si512(params->avx512.rounding);
diff --git a/src/qu8-vaddc/gen/minmax-neon-ld128-x16.c b/src/qu8-vaddc/gen/minmax-neon-ld128-x16.c
index 9073a5f..d72a239 100644
--- a/src/qu8-vaddc/gen/minmax-neon-ld128-x16.c
+++ b/src/qu8-vaddc/gen/minmax-neon-ld128-x16.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__neon_ld128_x16(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   #if XNN_ARCH_ARM64
     const uint8x16_t va_zero_point = vld1q_dup_u8(&params->neon.a_zero_point);
diff --git a/src/qu8-vaddc/gen/minmax-neon-ld64-x16.c b/src/qu8-vaddc/gen/minmax-neon-ld64-x16.c
index 943ceff..f0d25d1 100644
--- a/src/qu8-vaddc/gen/minmax-neon-ld64-x16.c
+++ b/src/qu8-vaddc/gen/minmax-neon-ld64-x16.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__neon_ld64_x16(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const uint8x8_t va_zero_point = vld1_dup_u8(&params->neon.a_zero_point);
   const int32x4_t va_multiplier = vld1q_dup_s32(&params->neon.a_multiplier);
diff --git a/src/qu8-vaddc/gen/minmax-neon-ld64-x32.c b/src/qu8-vaddc/gen/minmax-neon-ld64-x32.c
index ee637e2..d71c194 100644
--- a/src/qu8-vaddc/gen/minmax-neon-ld64-x32.c
+++ b/src/qu8-vaddc/gen/minmax-neon-ld64-x32.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__neon_ld64_x32(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const uint8x8_t va_zero_point = vld1_dup_u8(&params->neon.a_zero_point);
   const int32x4_t va_multiplier = vld1q_dup_s32(&params->neon.a_multiplier);
diff --git a/src/qu8-vaddc/gen/minmax-neon-ld64-x8.c b/src/qu8-vaddc/gen/minmax-neon-ld64-x8.c
index b63f5e4..a904b8a 100644
--- a/src/qu8-vaddc/gen/minmax-neon-ld64-x8.c
+++ b/src/qu8-vaddc/gen/minmax-neon-ld64-x8.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__neon_ld64_x8(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const uint8x8_t va_zero_point = vld1_dup_u8(&params->neon.a_zero_point);
   const int32x4_t va_multiplier = vld1q_dup_s32(&params->neon.a_multiplier);
diff --git a/src/qu8-vaddc/gen/minmax-scalar-x1.c b/src/qu8-vaddc/gen/minmax-scalar-x1.c
index d654728..410ad17 100644
--- a/src/qu8-vaddc/gen/minmax-scalar-x1.c
+++ b/src/qu8-vaddc/gen/minmax-scalar-x1.c
@@ -10,7 +10,7 @@
 #include <assert.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__scalar_x1(
@@ -18,7 +18,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
 {
   const int32_t vbias = params->scalar.bias + (int32_t) *input_b * params->scalar.b_multiplier;
   const int32_t va_multiplier = params->scalar.a_multiplier;
diff --git a/src/qu8-vaddc/gen/minmax-scalar-x2.c b/src/qu8-vaddc/gen/minmax-scalar-x2.c
index 9d8e4e0..2d1469c 100644
--- a/src/qu8-vaddc/gen/minmax-scalar-x2.c
+++ b/src/qu8-vaddc/gen/minmax-scalar-x2.c
@@ -10,7 +10,7 @@
 #include <assert.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__scalar_x2(
@@ -18,7 +18,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
 {
   const int32_t vbias = params->scalar.bias + (int32_t) *input_b * params->scalar.b_multiplier;
   const int32_t va_multiplier = params->scalar.a_multiplier;
diff --git a/src/qu8-vaddc/gen/minmax-scalar-x4.c b/src/qu8-vaddc/gen/minmax-scalar-x4.c
index d1a1d07..f122289 100644
--- a/src/qu8-vaddc/gen/minmax-scalar-x4.c
+++ b/src/qu8-vaddc/gen/minmax-scalar-x4.c
@@ -10,7 +10,7 @@
 #include <assert.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__scalar_x4(
@@ -18,7 +18,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN
 {
   const int32_t vbias = params->scalar.bias + (int32_t) *input_b * params->scalar.b_multiplier;
   const int32_t va_multiplier = params->scalar.a_multiplier;
diff --git a/src/qu8-vaddc/gen/minmax-sse2-mul16-ld64-x16.c b/src/qu8-vaddc/gen/minmax-sse2-mul16-ld64-x16.c
index 3fc0eab..04a5fec 100644
--- a/src/qu8-vaddc/gen/minmax-sse2-mul16-ld64-x16.c
+++ b/src/qu8-vaddc/gen/minmax-sse2-mul16-ld64-x16.c
@@ -11,7 +11,7 @@
 
 #include <emmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__sse2_mul16_ld64_x16(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_add_epi32(
     _mm_shuffle_epi32(_mm_cvtsi32_si128(params->sse2.b_multiplier * (int32_t) *input_b), _MM_SHUFFLE(0, 0, 0, 0)),
diff --git a/src/qu8-vaddc/gen/minmax-sse2-mul16-ld64-x8.c b/src/qu8-vaddc/gen/minmax-sse2-mul16-ld64-x8.c
index 2a9ade5..887b04a 100644
--- a/src/qu8-vaddc/gen/minmax-sse2-mul16-ld64-x8.c
+++ b/src/qu8-vaddc/gen/minmax-sse2-mul16-ld64-x8.c
@@ -11,7 +11,7 @@
 
 #include <emmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__sse2_mul16_ld64_x8(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_add_epi32(
     _mm_shuffle_epi32(_mm_cvtsi32_si128(params->sse2.b_multiplier * (int32_t) *input_b), _MM_SHUFFLE(0, 0, 0, 0)),
diff --git a/src/qu8-vaddc/gen/minmax-sse41-mul16-ld64-x16.c b/src/qu8-vaddc/gen/minmax-sse41-mul16-ld64-x16.c
index 50084ad..54ebfd3 100644
--- a/src/qu8-vaddc/gen/minmax-sse41-mul16-ld64-x16.c
+++ b/src/qu8-vaddc/gen/minmax-sse41-mul16-ld64-x16.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__sse41_mul16_ld64_x16(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_add_epi32(
     _mm_shuffle_epi32(_mm_cvtsi32_si128(params->sse2.b_multiplier * (int32_t) *input_b), _MM_SHUFFLE(0, 0, 0, 0)),
diff --git a/src/qu8-vaddc/gen/minmax-sse41-mul16-ld64-x8.c b/src/qu8-vaddc/gen/minmax-sse41-mul16-ld64-x8.c
index 062ab77..cd9ae9e 100644
--- a/src/qu8-vaddc/gen/minmax-sse41-mul16-ld64-x8.c
+++ b/src/qu8-vaddc/gen/minmax-sse41-mul16-ld64-x8.c
@@ -11,7 +11,7 @@
 
 #include <smmintrin.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__sse41_mul16_ld64_x8(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i vbias = _mm_add_epi32(
     _mm_shuffle_epi32(_mm_cvtsi32_si128(params->sse2.b_multiplier * (int32_t) *input_b), _MM_SHUFFLE(0, 0, 0, 0)),
diff --git a/src/qu8-vaddc/gen/minmax-sse41-mul32-ld32-x16.c b/src/qu8-vaddc/gen/minmax-sse41-mul32-ld32-x16.c
index c16b892..7d9adfa 100644
--- a/src/qu8-vaddc/gen/minmax-sse41-mul32-ld32-x16.c
+++ b/src/qu8-vaddc/gen/minmax-sse41-mul32-ld32-x16.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__sse41_mul32_ld32_x16(
@@ -20,7 +20,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4.a_multiplier);
   const __m128i vrounding = _mm_load_si128((const __m128i*) params->sse4.rounding);
diff --git a/src/qu8-vaddc/gen/minmax-sse41-mul32-ld32-x8.c b/src/qu8-vaddc/gen/minmax-sse41-mul32-ld32-x8.c
index 667db67..353ed6a 100644
--- a/src/qu8-vaddc/gen/minmax-sse41-mul32-ld32-x8.c
+++ b/src/qu8-vaddc/gen/minmax-sse41-mul32-ld32-x8.c
@@ -12,7 +12,7 @@
 #include <immintrin.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__sse41_mul32_ld32_x8(
@@ -20,7 +20,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4.a_multiplier);
   const __m128i vrounding = _mm_load_si128((const __m128i*) params->sse4.rounding);
diff --git a/src/qu8-vaddc/gen/minmax-wasmsimd-x16.c b/src/qu8-vaddc/gen/minmax-wasmsimd-x16.c
index 433e7f8..a49b3ef 100644
--- a/src/qu8-vaddc/gen/minmax-wasmsimd-x16.c
+++ b/src/qu8-vaddc/gen/minmax-wasmsimd-x16.c
@@ -11,7 +11,7 @@
 
 #include <wasm_simd128.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__wasmsimd_x16(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const v128_t va_multiplier = wasm_v128_load(params->wasmsimd.a_multiplier);
   const v128_t vrounding = wasm_v128_load(params->wasmsimd.rounding);
diff --git a/src/qu8-vaddc/gen/minmax-wasmsimd-x8.c b/src/qu8-vaddc/gen/minmax-wasmsimd-x8.c
index 6ad11e5..cd7797f 100644
--- a/src/qu8-vaddc/gen/minmax-wasmsimd-x8.c
+++ b/src/qu8-vaddc/gen/minmax-wasmsimd-x8.c
@@ -11,7 +11,7 @@
 
 #include <wasm_simd128.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__wasmsimd_x8(
@@ -19,7 +19,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const v128_t va_multiplier = wasm_v128_load(params->wasmsimd.a_multiplier);
   const v128_t vrounding = wasm_v128_load(params->wasmsimd.rounding);
diff --git a/src/qu8-vaddc/gen/minmax-xop-mul32-ld32-x16.c b/src/qu8-vaddc/gen/minmax-xop-mul32-ld32-x16.c
index 03a1082..e5b23f2 100644
--- a/src/qu8-vaddc/gen/minmax-xop-mul32-ld32-x16.c
+++ b/src/qu8-vaddc/gen/minmax-xop-mul32-ld32-x16.c
@@ -17,7 +17,7 @@
 #endif
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__xop_mul32_ld32_x16(
@@ -25,7 +25,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4.a_multiplier);
   const __m128i vrounding = _mm_load_si128((const __m128i*) params->sse4.rounding);
diff --git a/src/qu8-vaddc/gen/minmax-xop-mul32-ld32-x8.c b/src/qu8-vaddc/gen/minmax-xop-mul32-ld32-x8.c
index c77660c..a8477b7 100644
--- a/src/qu8-vaddc/gen/minmax-xop-mul32-ld32-x8.c
+++ b/src/qu8-vaddc/gen/minmax-xop-mul32-ld32-x8.c
@@ -17,7 +17,7 @@
 #endif
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vaddsub.h>
 
 
 void xnn_qu8_vaddc_minmax_ukernel__xop_mul32_ld32_x8(
@@ -25,7 +25,7 @@
     const uint8_t* input_a,
     const uint8_t* input_b,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
+    const union xnn_qu8_addsub_minmax_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_DISABLE_TSAN XNN_DISABLE_MSAN
 {
   const __m128i va_multiplier = _mm_load_si128((const __m128i*) params->sse4.a_multiplier);
   const __m128i vrounding = _mm_load_si128((const __m128i*) params->sse4.rounding);
diff --git a/src/qu8-vmul/gen/minmax-fp32-neon-ld128-x16.c b/src/qu8-vmul/gen/minmax-fp32-neon-ld128-x16.c
index 4705204..6698c28 100644
--- a/src/qu8-vmul/gen/minmax-fp32-neon-ld128-x16.c
+++ b/src/qu8-vmul/gen/minmax-fp32-neon-ld128-x16.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qu8_vmul_minmax_fp32_ukernel__neon_ld128_x16(
diff --git a/src/qu8-vmul/gen/minmax-fp32-neon-ld64-x16.c b/src/qu8-vmul/gen/minmax-fp32-neon-ld64-x16.c
index c48f5f9..2b2fb2b 100644
--- a/src/qu8-vmul/gen/minmax-fp32-neon-ld64-x16.c
+++ b/src/qu8-vmul/gen/minmax-fp32-neon-ld64-x16.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qu8_vmul_minmax_fp32_ukernel__neon_ld64_x16(
diff --git a/src/qu8-vmul/gen/minmax-fp32-neon-ld64-x8.c b/src/qu8-vmul/gen/minmax-fp32-neon-ld64-x8.c
index b7f714f..993ce53 100644
--- a/src/qu8-vmul/gen/minmax-fp32-neon-ld64-x8.c
+++ b/src/qu8-vmul/gen/minmax-fp32-neon-ld64-x8.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qu8_vmul_minmax_fp32_ukernel__neon_ld64_x8(
diff --git a/src/qu8-vmul/gen/minmax-fp32-neonv8-ld128-x16.c b/src/qu8-vmul/gen/minmax-fp32-neonv8-ld128-x16.c
index 59f9233..a2a9e46 100644
--- a/src/qu8-vmul/gen/minmax-fp32-neonv8-ld128-x16.c
+++ b/src/qu8-vmul/gen/minmax-fp32-neonv8-ld128-x16.c
@@ -12,7 +12,7 @@
 #include <arm_neon.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qu8_vmul_minmax_fp32_ukernel__neonv8_ld128_x16(
diff --git a/src/qu8-vmul/gen/minmax-fp32-neonv8-ld64-x16.c b/src/qu8-vmul/gen/minmax-fp32-neonv8-ld64-x16.c
index b473727..fd7d923 100644
--- a/src/qu8-vmul/gen/minmax-fp32-neonv8-ld64-x16.c
+++ b/src/qu8-vmul/gen/minmax-fp32-neonv8-ld64-x16.c
@@ -12,7 +12,7 @@
 #include <arm_neon.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qu8_vmul_minmax_fp32_ukernel__neonv8_ld64_x16(
diff --git a/src/qu8-vmul/gen/minmax-fp32-neonv8-ld64-x8.c b/src/qu8-vmul/gen/minmax-fp32-neonv8-ld64-x8.c
index 64df6f7..6c37c86 100644
--- a/src/qu8-vmul/gen/minmax-fp32-neonv8-ld64-x8.c
+++ b/src/qu8-vmul/gen/minmax-fp32-neonv8-ld64-x8.c
@@ -12,7 +12,7 @@
 #include <arm_neon.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qu8_vmul_minmax_fp32_ukernel__neonv8_ld64_x8(
diff --git a/src/qu8-vmul/gen/minmax-fp32-scalar-x1.c b/src/qu8-vmul/gen/minmax-fp32-scalar-x1.c
index e4bb341..a250ed9 100644
--- a/src/qu8-vmul/gen/minmax-fp32-scalar-x1.c
+++ b/src/qu8-vmul/gen/minmax-fp32-scalar-x1.c
@@ -12,7 +12,7 @@
 #include <fp16.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qu8_vmul_minmax_fp32_ukernel__scalar_x1(
diff --git a/src/qu8-vmul/gen/minmax-fp32-scalar-x2.c b/src/qu8-vmul/gen/minmax-fp32-scalar-x2.c
index 08ef985..210c279 100644
--- a/src/qu8-vmul/gen/minmax-fp32-scalar-x2.c
+++ b/src/qu8-vmul/gen/minmax-fp32-scalar-x2.c
@@ -12,7 +12,7 @@
 #include <fp16.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qu8_vmul_minmax_fp32_ukernel__scalar_x2(
diff --git a/src/qu8-vmul/gen/minmax-fp32-scalar-x4.c b/src/qu8-vmul/gen/minmax-fp32-scalar-x4.c
index f84d444..9b4d1f2 100644
--- a/src/qu8-vmul/gen/minmax-fp32-scalar-x4.c
+++ b/src/qu8-vmul/gen/minmax-fp32-scalar-x4.c
@@ -12,7 +12,7 @@
 #include <fp16.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qu8_vmul_minmax_fp32_ukernel__scalar_x4(
diff --git a/src/qu8-vmulc/gen/minmax-fp32-neon-ld128-x16.c b/src/qu8-vmulc/gen/minmax-fp32-neon-ld128-x16.c
index c3046ba..20b7e31 100644
--- a/src/qu8-vmulc/gen/minmax-fp32-neon-ld128-x16.c
+++ b/src/qu8-vmulc/gen/minmax-fp32-neon-ld128-x16.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qu8_vmulc_minmax_fp32_ukernel__neon_ld128_x16(
diff --git a/src/qu8-vmulc/gen/minmax-fp32-neon-ld64-x16.c b/src/qu8-vmulc/gen/minmax-fp32-neon-ld64-x16.c
index 9e1968d..76f2c8f 100644
--- a/src/qu8-vmulc/gen/minmax-fp32-neon-ld64-x16.c
+++ b/src/qu8-vmulc/gen/minmax-fp32-neon-ld64-x16.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qu8_vmulc_minmax_fp32_ukernel__neon_ld64_x16(
diff --git a/src/qu8-vmulc/gen/minmax-fp32-neon-ld64-x8.c b/src/qu8-vmulc/gen/minmax-fp32-neon-ld64-x8.c
index 3fe678d..144b98f 100644
--- a/src/qu8-vmulc/gen/minmax-fp32-neon-ld64-x8.c
+++ b/src/qu8-vmulc/gen/minmax-fp32-neon-ld64-x8.c
@@ -11,7 +11,7 @@
 
 #include <arm_neon.h>
 
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qu8_vmulc_minmax_fp32_ukernel__neon_ld64_x8(
diff --git a/src/qu8-vmulc/gen/minmax-fp32-neonv8-ld128-x16.c b/src/qu8-vmulc/gen/minmax-fp32-neonv8-ld128-x16.c
index a40a072..af6b402 100644
--- a/src/qu8-vmulc/gen/minmax-fp32-neonv8-ld128-x16.c
+++ b/src/qu8-vmulc/gen/minmax-fp32-neonv8-ld128-x16.c
@@ -12,7 +12,7 @@
 #include <arm_neon.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qu8_vmulc_minmax_fp32_ukernel__neonv8_ld128_x16(
diff --git a/src/qu8-vmulc/gen/minmax-fp32-neonv8-ld64-x16.c b/src/qu8-vmulc/gen/minmax-fp32-neonv8-ld64-x16.c
index 51ea3f8..e81c997 100644
--- a/src/qu8-vmulc/gen/minmax-fp32-neonv8-ld64-x16.c
+++ b/src/qu8-vmulc/gen/minmax-fp32-neonv8-ld64-x16.c
@@ -12,7 +12,7 @@
 #include <arm_neon.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qu8_vmulc_minmax_fp32_ukernel__neonv8_ld64_x16(
diff --git a/src/qu8-vmulc/gen/minmax-fp32-neonv8-ld64-x8.c b/src/qu8-vmulc/gen/minmax-fp32-neonv8-ld64-x8.c
index b81961b..3416c83 100644
--- a/src/qu8-vmulc/gen/minmax-fp32-neonv8-ld64-x8.c
+++ b/src/qu8-vmulc/gen/minmax-fp32-neonv8-ld64-x8.c
@@ -12,7 +12,7 @@
 #include <arm_neon.h>
 
 #include <xnnpack/intrinsics-polyfill.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qu8_vmulc_minmax_fp32_ukernel__neonv8_ld64_x8(
diff --git a/src/qu8-vmulc/gen/minmax-fp32-scalar-x1.c b/src/qu8-vmulc/gen/minmax-fp32-scalar-x1.c
index d5ca127..c93da69 100644
--- a/src/qu8-vmulc/gen/minmax-fp32-scalar-x1.c
+++ b/src/qu8-vmulc/gen/minmax-fp32-scalar-x1.c
@@ -12,7 +12,7 @@
 #include <fp16.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qu8_vmulc_minmax_fp32_ukernel__scalar_x1(
diff --git a/src/qu8-vmulc/gen/minmax-fp32-scalar-x2.c b/src/qu8-vmulc/gen/minmax-fp32-scalar-x2.c
index bcea182..fa7fa46 100644
--- a/src/qu8-vmulc/gen/minmax-fp32-scalar-x2.c
+++ b/src/qu8-vmulc/gen/minmax-fp32-scalar-x2.c
@@ -12,7 +12,7 @@
 #include <fp16.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qu8_vmulc_minmax_fp32_ukernel__scalar_x2(
diff --git a/src/qu8-vmulc/gen/minmax-fp32-scalar-x4.c b/src/qu8-vmulc/gen/minmax-fp32-scalar-x4.c
index 63c4c3c..8003dfd 100644
--- a/src/qu8-vmulc/gen/minmax-fp32-scalar-x4.c
+++ b/src/qu8-vmulc/gen/minmax-fp32-scalar-x4.c
@@ -12,7 +12,7 @@
 #include <fp16.h>
 
 #include <xnnpack/math.h>
-#include <xnnpack/vadd.h>
+#include <xnnpack/vmul.h>
 
 
 void xnn_qu8_vmulc_minmax_fp32_ukernel__scalar_x4(
diff --git a/src/xnnpack/compute.h b/src/xnnpack/compute.h
index 021fe80..07280d0 100644
--- a/src/xnnpack/compute.h
+++ b/src/xnnpack/compute.h
@@ -767,8 +767,10 @@
   size_t y_stride[XNN_MAX_TENSOR_DIMS - 1];
   size_t elements;
   union {
-    union xnn_qs8_add_minmax_params qs8;
-    union xnn_qu8_add_minmax_params qu8;
+    union xnn_qs8_addsub_minmax_params qs8_addsub;
+    union xnn_qu8_addsub_minmax_params qu8_addsub;
+    union xnn_qs8_mul_minmax_params qs8_mul;
+    union xnn_qu8_mul_minmax_params qu8_mul;
     struct xnn_f16_minmax_params f16;
     union xnn_f32_minmax_params f32;
   } params;
diff --git a/src/xnnpack/operator.h b/src/xnnpack/operator.h
index 60738e2..fe75dac 100644
--- a/src/xnnpack/operator.h
+++ b/src/xnnpack/operator.h
@@ -293,16 +293,16 @@
     };
     // Quantized Add parameters are sensitive to order of inputs, so we initialize an extra copy with the reversed order.
     struct {
-      union xnn_qs8_add_minmax_params qs8_add;
-      union xnn_qs8_add_minmax_params qs8_radd;
+      union xnn_qs8_addsub_minmax_params qs8_addsub;
+      union xnn_qs8_addsub_minmax_params qs8_raddsub;
     };
     struct {
       union xnn_qs8_mul_minmax_params qs8_mul;
       union xnn_qs8_mul_minmax_params qs8_rmul;
     };
     struct {
-      union xnn_qu8_add_minmax_params qu8_add;
-      union xnn_qu8_add_minmax_params qu8_radd;
+      union xnn_qu8_addsub_minmax_params qu8_addsub;
+      union xnn_qu8_addsub_minmax_params qu8_raddsub;
     };
     struct {
       union xnn_qu8_mul_minmax_params qu8_mul;
diff --git a/src/xnnpack/params-init.h b/src/xnnpack/params-init.h
index d0a1ed0..25e01ca 100644
--- a/src/xnnpack/params-init.h
+++ b/src/xnnpack/params-init.h
@@ -565,7 +565,7 @@
 
 #if XNN_ARCH_X86 || XNN_ARCH_X86_64
 XNN_INTERNAL void xnn_init_qu8_add_minmax_sse2_params(
-  union xnn_qu8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qu8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   uint8_t x_zero_point,
   uint8_t y_zero_point,
   uint8_t output_zero_point,
@@ -575,7 +575,7 @@
   uint8_t output_max);
 
 XNN_INTERNAL void xnn_init_qu8_add_minmax_sse4_params(
-  union xnn_qu8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qu8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   uint8_t x_zero_point,
   uint8_t y_zero_point,
   uint8_t output_zero_point,
@@ -585,7 +585,7 @@
   uint8_t output_max);
 
 XNN_INTERNAL void xnn_init_qu8_add_minmax_avx2_params(
-  union xnn_qu8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qu8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   uint8_t x_zero_point,
   uint8_t y_zero_point,
   uint8_t output_zero_point,
@@ -595,7 +595,7 @@
   uint8_t output_max);
 
 XNN_INTERNAL void xnn_init_qu8_add_minmax_avx512_params(
-  union xnn_qu8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qu8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   uint8_t x_zero_point,
   uint8_t y_zero_point,
   uint8_t output_zero_point,
@@ -607,7 +607,7 @@
 
 #if XNN_ARCH_ARM || XNN_ARCH_ARM64
 XNN_INTERNAL void xnn_init_qu8_add_minmax_neon_params(
-  union xnn_qu8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qu8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   uint8_t x_zero_point,
   uint8_t y_zero_point,
   uint8_t output_zero_point,
@@ -619,7 +619,7 @@
 
 #if XNN_ARCH_WASMSIMD
 XNN_INTERNAL void xnn_init_qu8_add_minmax_wasmsimd_params(
-  union xnn_qu8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qu8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   uint8_t x_zero_point,
   uint8_t y_zero_point,
   uint8_t output_zero_point,
@@ -630,7 +630,7 @@
 #endif  // XNN_ARCH_WASMSIMD
 
 XNN_INTERNAL void xnn_init_qu8_add_minmax_scalar_params(
-  union xnn_qu8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qu8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   uint8_t a_zero_point,
   uint8_t b_zero_point,
   uint8_t output_zero_point,
@@ -641,7 +641,7 @@
 
 #if XNN_ARCH_X86 || XNN_ARCH_X86_64
 XNN_INTERNAL void xnn_init_qs8_add_minmax_sse2_params(
-  union xnn_qs8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qs8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   int8_t x_zero_point,
   int8_t y_zero_point,
   int8_t output_zero_point,
@@ -651,7 +651,7 @@
   int8_t output_max);
 
 XNN_INTERNAL void xnn_init_qs8_add_minmax_sse4_mul16_params(
-  union xnn_qs8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qs8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   int8_t x_zero_point,
   int8_t y_zero_point,
   int8_t output_zero_point,
@@ -661,7 +661,7 @@
   int8_t output_max);
 
 XNN_INTERNAL void xnn_init_qs8_add_minmax_sse4_mul32_params(
-  union xnn_qs8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qs8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   int8_t x_zero_point,
   int8_t y_zero_point,
   int8_t output_zero_point,
@@ -671,7 +671,7 @@
   int8_t output_max);
 
 XNN_INTERNAL void xnn_init_qs8_add_minmax_avx2_params(
-  union xnn_qs8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qs8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   int8_t x_zero_point,
   int8_t y_zero_point,
   int8_t output_zero_point,
@@ -681,7 +681,7 @@
   int8_t output_max);
 
 XNN_INTERNAL void xnn_init_qs8_add_minmax_avx512_params(
-  union xnn_qs8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qs8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   int8_t x_zero_point,
   int8_t y_zero_point,
   int8_t output_zero_point,
@@ -693,7 +693,7 @@
 
 #if XNN_ARCH_ARM || XNN_ARCH_ARM64
 XNN_INTERNAL void xnn_init_qs8_add_minmax_neon_params(
-  union xnn_qs8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qs8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   int8_t x_zero_point,
   int8_t y_zero_point,
   int8_t output_zero_point,
@@ -705,7 +705,7 @@
 
 #if XNN_ARCH_WASMSIMD
 XNN_INTERNAL void xnn_init_qs8_add_minmax_wasmsimd_params(
-  union xnn_qs8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qs8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   int8_t x_zero_point,
   int8_t y_zero_point,
   int8_t output_zero_point,
@@ -716,7 +716,7 @@
 #endif  // XNN_ARCH_WASMSIMD
 
 XNN_INTERNAL void xnn_init_qs8_add_minmax_scalar_params(
-  union xnn_qs8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+  union xnn_qs8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   int8_t x_zero_point,
   int8_t y_zero_point,
   int8_t output_zero_point,
diff --git a/src/xnnpack/params.h b/src/xnnpack/params.h
index cd5a02c..5b78d30 100644
--- a/src/xnnpack/params.h
+++ b/src/xnnpack/params.h
@@ -594,7 +594,7 @@
 #endif  // XNN_ARCH_WASMSIMD
 };
 
-union xnn_qu8_add_minmax_params {
+union xnn_qu8_addsub_minmax_params {
   struct {
     int32_t bias;
     int32_t a_multiplier;
@@ -676,7 +676,7 @@
 #endif  // XNN_ARCH_WASMSIMD
 };
 
-union xnn_qs8_add_minmax_params {
+union xnn_qs8_addsub_minmax_params {
   struct {
     int32_t bias;
     int32_t a_multiplier;
@@ -2001,19 +2001,19 @@
     void* y,
     const void* params);
 
-typedef void (*xnn_qu8_vadd_minmax_ukernel_function)(
+typedef void (*xnn_qu8_vaddsub_minmax_ukernel_function)(
     size_t n,
     const uint8_t* input_x,
     const uint8_t* input_y,
     uint8_t* output,
-    const union xnn_qu8_add_minmax_params* params);
+    const union xnn_qu8_addsub_minmax_params* params);
 
-typedef void (*xnn_qs8_vadd_minmax_ukernel_function)(
+typedef void (*xnn_qs8_vaddsub_minmax_ukernel_function)(
     size_t n,
     const int8_t* input_x,
     const int8_t* input_y,
     int8_t* output,
-    const union xnn_qs8_add_minmax_params* params);
+    const union xnn_qs8_addsub_minmax_params* params);
 
 typedef void (*xnn_qu8_vmul_minmax_ukernel_function)(
     size_t n,
@@ -2231,8 +2231,8 @@
   uint8_t output_min,
   uint8_t output_max);
 
-typedef void (*xnn_init_qs8_add_minmax_params_fn)(
-  union xnn_qs8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+typedef void (*xnn_init_qs8_addsub_minmax_params_fn)(
+  union xnn_qs8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   int8_t a_zero_point,
   int8_t b_zero_point,
   int8_t output_zero_point,
@@ -2241,8 +2241,8 @@
   int8_t output_min,
   int8_t output_max);
 
-typedef void (*xnn_init_qu8_add_minmax_params_fn)(
-  union xnn_qu8_add_minmax_params params[XNN_MIN_ELEMENTS(1)],
+typedef void (*xnn_init_qu8_addsub_minmax_params_fn)(
+  union xnn_qu8_addsub_minmax_params params[XNN_MIN_ELEMENTS(1)],
   uint8_t a_zero_point,
   uint8_t b_zero_point,
   uint8_t output_zero_point,
@@ -2399,9 +2399,9 @@
   struct vbinary_fused_ukernels minmax;
   struct vbinary_fused_ukernels linear;
   union {
-    xnn_init_qs8_add_minmax_params_fn qs8_add;
+    xnn_init_qs8_addsub_minmax_params_fn qs8_addsub;
     xnn_init_qs8_mul_minmax_params_fn qs8_mul;
-    xnn_init_qu8_add_minmax_params_fn qu8_add;
+    xnn_init_qu8_addsub_minmax_params_fn qu8_addsub;
     xnn_init_qu8_mul_minmax_params_fn qu8_mul;
   } init;
   // Number of elements in a tile.
diff --git a/src/xnnpack/requantization.h b/src/xnnpack/requantization.h
index 8bb3ebe..9f776e4 100644
--- a/src/xnnpack/requantization.h
+++ b/src/xnnpack/requantization.h
@@ -450,7 +450,7 @@
 
 static inline uint8_t xnn_qu8_quantize_add(
   uint8_t a, uint8_t b,
-  union xnn_qu8_add_minmax_params params)
+  union xnn_qu8_addsub_minmax_params params)
 {
   // Multiply by factors and accumulate products.
   int32_t acc = params.scalar.bias + (int32_t) (uint32_t) a * params.scalar.a_multiplier + (int32_t) (uint32_t) b * params.scalar.b_multiplier;
@@ -466,7 +466,7 @@
 
 static inline int8_t xnn_qs8_quantize_add(
   int8_t a, int8_t b,
-  union xnn_qs8_add_minmax_params params)
+  union xnn_qs8_addsub_minmax_params params)
 {
   // Multiply by factors and accumulate products.
   int32_t acc = params.scalar.bias + (int32_t) a * params.scalar.a_multiplier + (int32_t) b * params.scalar.b_multiplier;
diff --git a/src/xnnpack/vadd.h b/src/xnnpack/vaddsub.h
similarity index 98%
rename from src/xnnpack/vadd.h
rename to src/xnnpack/vaddsub.h
index e2f1e73..e4415ec 100644
--- a/src/xnnpack/vadd.h
+++ b/src/xnnpack/vaddsub.h
@@ -25,7 +25,7 @@
       const uint8_t* input_a,                             \
       const uint8_t* input_b,                             \
       uint8_t* output,                                    \
-      const union xnn_qu8_add_minmax_params* params);
+      const union xnn_qu8_addsub_minmax_params* params);
 
 DECLARE_QU8_VADD_MINMAX_UKERNEL_FUNCTION(xnn_qu8_vadd_minmax_ukernel__neon_ld64_x8)
 DECLARE_QU8_VADD_MINMAX_UKERNEL_FUNCTION(xnn_qu8_vadd_minmax_ukernel__neon_ld64_x16)
@@ -108,7 +108,7 @@
       const int8_t* input_a,                              \
       const int8_t* input_b,                              \
       int8_t* output,                                     \
-      const union xnn_qs8_add_minmax_params* params);
+      const union xnn_qs8_addsub_minmax_params* params);
 
 DECLARE_QS8_VADD_MINMAX_UKERNEL_FUNCTION(xnn_qs8_vadd_minmax_ukernel__neon_ld64_x8)
 DECLARE_QS8_VADD_MINMAX_UKERNEL_FUNCTION(xnn_qs8_vadd_minmax_ukernel__neon_ld64_x16)