Additional NEON/NEONFMA DWCONV microkernels

Faster 2x2 and 5x5 depthwise convolution

PiperOrigin-RevId: 308216337
diff --git a/test/f32-dwconv-minmax.cc b/test/f32-dwconv-minmax.cc
index 7758a7e..cc9cff2 100644
--- a/test/f32-dwconv-minmax.cc
+++ b/test/f32-dwconv-minmax.cc
@@ -348,6 +348,642 @@
 
 
 #if XNN_ARCH_ARM || XNN_ARCH_ARM64
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA, c_eq_4) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    DWConvMicrokernelTester()
+      .cr(4)
+      .kr(25)
+      .channels(4)
+      .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma);
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA, c_div_4) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA, c_div_4_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA, c_div_4_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA, c_lt_4) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 1; channels < 4; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA, c_gt_4) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA, c_gt_4_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA, c_gt_4_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA, multipixel) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA, multipixel_with_step) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      for (size_t step = 2; step <= 25; step++) {
+        DWConvMicrokernelTester()
+          .cr(4)
+          .kr(25)
+          .channels(channels)
+          .width(3)
+          .step(step)
+          .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma);
+      }
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA, multipixel_with_output_stride) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(4)
+        .width(5)
+        .output_stride(23)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA, multipixel_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA, multipixel_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma);
+    }
+  }
+#endif  // XNN_ARCH_ARM || XNN_ARCH_ARM64
+
+
+#if XNN_ARCH_ARM || XNN_ARCH_ARM64
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA_ACC2, c_eq_4) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    DWConvMicrokernelTester()
+      .cr(4)
+      .kr(25)
+      .channels(4)
+      .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma_acc2);
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA_ACC2, c_div_4) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA_ACC2, c_div_4_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA_ACC2, c_div_4_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA_ACC2, c_lt_4) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 1; channels < 4; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA_ACC2, c_gt_4) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA_ACC2, c_gt_4_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA_ACC2, c_gt_4_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA_ACC2, multipixel) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA_ACC2, multipixel_with_step) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      for (size_t step = 2; step <= 25; step++) {
+        DWConvMicrokernelTester()
+          .cr(4)
+          .kr(25)
+          .channels(channels)
+          .width(3)
+          .step(step)
+          .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma_acc2);
+      }
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA_ACC2, multipixel_with_output_stride) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(4)
+        .width(5)
+        .output_stride(23)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA_ACC2, multipixel_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEONFMA_ACC2, multipixel_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neonfma_acc2);
+    }
+  }
+#endif  // XNN_ARCH_ARM || XNN_ARCH_ARM64
+
+
+#if XNN_ARCH_ARM || XNN_ARCH_ARM64
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA, c_eq_8) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    DWConvMicrokernelTester()
+      .cr(8)
+      .kr(25)
+      .channels(8)
+      .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma);
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA, c_div_8) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA, c_div_8_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA, c_div_8_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA, c_lt_8) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 1; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA, c_gt_8) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA, c_gt_8_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA, c_gt_8_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA, multipixel) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA, multipixel_with_step) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      for (size_t step = 2; step <= 25; step++) {
+        DWConvMicrokernelTester()
+          .cr(8)
+          .kr(25)
+          .channels(channels)
+          .width(3)
+          .step(step)
+          .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma);
+      }
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA, multipixel_with_output_stride) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(8)
+        .width(5)
+        .output_stride(43)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA, multipixel_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA, multipixel_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma);
+    }
+  }
+#endif  // XNN_ARCH_ARM || XNN_ARCH_ARM64
+
+
+#if XNN_ARCH_ARM || XNN_ARCH_ARM64
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA_ACC2, c_eq_8) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    DWConvMicrokernelTester()
+      .cr(8)
+      .kr(25)
+      .channels(8)
+      .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma_acc2);
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA_ACC2, c_div_8) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA_ACC2, c_div_8_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA_ACC2, c_div_8_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA_ACC2, c_lt_8) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 1; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA_ACC2, c_gt_8) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA_ACC2, c_gt_8_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA_ACC2, c_gt_8_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA_ACC2, multipixel) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA_ACC2, multipixel_with_step) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      for (size_t step = 2; step <= 25; step++) {
+        DWConvMicrokernelTester()
+          .cr(8)
+          .kr(25)
+          .channels(channels)
+          .width(3)
+          .step(step)
+          .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma_acc2);
+      }
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA_ACC2, multipixel_with_output_stride) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(8)
+        .width(5)
+        .output_stride(43)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA_ACC2, multipixel_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEONFMA_ACC2, multipixel_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neonfma_acc2);
+    }
+  }
+#endif  // XNN_ARCH_ARM || XNN_ARCH_ARM64
+
+
+#if XNN_ARCH_ARM || XNN_ARCH_ARM64
   TEST(F32_DWCONV_MINMAX_UP4X9__NEONFMA, c_eq_4) {
     TEST_REQUIRES_ARM_NEON_FMA;
     DWConvMicrokernelTester()
@@ -984,6 +1620,1278 @@
 
 
 #if XNN_ARCH_ARM || XNN_ARCH_ARM64
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA, c_eq_4) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    DWConvMicrokernelTester()
+      .cr(4)
+      .kr(4)
+      .channels(4)
+      .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma);
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA, c_div_4) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA, c_div_4_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA, c_div_4_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA, c_lt_4) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 1; channels < 4; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA, c_gt_4) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA, c_gt_4_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA, c_gt_4_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA, multipixel) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA, multipixel_with_step) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      for (size_t step = 2; step <= 4; step++) {
+        DWConvMicrokernelTester()
+          .cr(4)
+          .kr(4)
+          .channels(channels)
+          .width(3)
+          .step(step)
+          .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma);
+      }
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA, multipixel_with_output_stride) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(4)
+        .width(5)
+        .output_stride(23)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA, multipixel_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA, multipixel_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma);
+    }
+  }
+#endif  // XNN_ARCH_ARM || XNN_ARCH_ARM64
+
+
+#if XNN_ARCH_ARM || XNN_ARCH_ARM64
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA_ACC2, c_eq_4) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    DWConvMicrokernelTester()
+      .cr(4)
+      .kr(4)
+      .channels(4)
+      .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma_acc2);
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA_ACC2, c_div_4) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA_ACC2, c_div_4_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA_ACC2, c_div_4_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA_ACC2, c_lt_4) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 1; channels < 4; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA_ACC2, c_gt_4) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA_ACC2, c_gt_4_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA_ACC2, c_gt_4_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA_ACC2, multipixel) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA_ACC2, multipixel_with_step) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      for (size_t step = 2; step <= 4; step++) {
+        DWConvMicrokernelTester()
+          .cr(4)
+          .kr(4)
+          .channels(channels)
+          .width(3)
+          .step(step)
+          .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma_acc2);
+      }
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA_ACC2, multipixel_with_output_stride) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(4)
+        .width(5)
+        .output_stride(23)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA_ACC2, multipixel_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEONFMA_ACC2, multipixel_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neonfma_acc2);
+    }
+  }
+#endif  // XNN_ARCH_ARM || XNN_ARCH_ARM64
+
+
+#if XNN_ARCH_ARM || XNN_ARCH_ARM64
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA, c_eq_8) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    DWConvMicrokernelTester()
+      .cr(8)
+      .kr(4)
+      .channels(8)
+      .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma);
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA, c_div_8) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA, c_div_8_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA, c_div_8_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA, c_lt_8) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 1; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA, c_gt_8) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA, c_gt_8_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA, c_gt_8_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA, multipixel) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA, multipixel_with_step) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      for (size_t step = 2; step <= 4; step++) {
+        DWConvMicrokernelTester()
+          .cr(8)
+          .kr(4)
+          .channels(channels)
+          .width(3)
+          .step(step)
+          .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma);
+      }
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA, multipixel_with_output_stride) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(8)
+        .width(5)
+        .output_stride(43)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA, multipixel_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA, multipixel_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma);
+    }
+  }
+#endif  // XNN_ARCH_ARM || XNN_ARCH_ARM64
+
+
+#if XNN_ARCH_ARM || XNN_ARCH_ARM64
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA_ACC2, c_eq_8) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    DWConvMicrokernelTester()
+      .cr(8)
+      .kr(4)
+      .channels(8)
+      .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma_acc2);
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA_ACC2, c_div_8) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA_ACC2, c_div_8_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA_ACC2, c_div_8_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA_ACC2, c_lt_8) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 1; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA_ACC2, c_gt_8) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA_ACC2, c_gt_8_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA_ACC2, c_gt_8_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA_ACC2, multipixel) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA_ACC2, multipixel_with_step) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      for (size_t step = 2; step <= 4; step++) {
+        DWConvMicrokernelTester()
+          .cr(8)
+          .kr(4)
+          .channels(channels)
+          .width(3)
+          .step(step)
+          .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma_acc2);
+      }
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA_ACC2, multipixel_with_output_stride) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(8)
+        .width(5)
+        .output_stride(43)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA_ACC2, multipixel_with_qmin) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEONFMA_ACC2, multipixel_with_qmax) {
+    TEST_REQUIRES_ARM_NEON_FMA;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neonfma_acc2);
+    }
+  }
+#endif  // XNN_ARCH_ARM || XNN_ARCH_ARM64
+
+
+#if XNN_ARCH_ARM || XNN_ARCH_ARM64
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON, c_eq_4) {
+    TEST_REQUIRES_ARM_NEON;
+    DWConvMicrokernelTester()
+      .cr(4)
+      .kr(25)
+      .channels(4)
+      .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon);
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON, c_div_4) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON, c_div_4_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON, c_div_4_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON, c_lt_4) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 1; channels < 4; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON, c_gt_4) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON, c_gt_4_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON, c_gt_4_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON, multipixel) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON, multipixel_with_step) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      for (size_t step = 2; step <= 25; step++) {
+        DWConvMicrokernelTester()
+          .cr(4)
+          .kr(25)
+          .channels(channels)
+          .width(3)
+          .step(step)
+          .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon);
+      }
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON, multipixel_with_output_stride) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(4)
+        .width(5)
+        .output_stride(23)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON, multipixel_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON, multipixel_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon);
+    }
+  }
+#endif  // XNN_ARCH_ARM || XNN_ARCH_ARM64
+
+
+#if XNN_ARCH_ARM || XNN_ARCH_ARM64
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON_ACC2, c_eq_4) {
+    TEST_REQUIRES_ARM_NEON;
+    DWConvMicrokernelTester()
+      .cr(4)
+      .kr(25)
+      .channels(4)
+      .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon_acc2);
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON_ACC2, c_div_4) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON_ACC2, c_div_4_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON_ACC2, c_div_4_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON_ACC2, c_lt_4) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 1; channels < 4; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON_ACC2, c_gt_4) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON_ACC2, c_gt_4_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON_ACC2, c_gt_4_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON_ACC2, multipixel) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON_ACC2, multipixel_with_step) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      for (size_t step = 2; step <= 25; step++) {
+        DWConvMicrokernelTester()
+          .cr(4)
+          .kr(25)
+          .channels(channels)
+          .width(3)
+          .step(step)
+          .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon_acc2);
+      }
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON_ACC2, multipixel_with_output_stride) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(4)
+        .width(5)
+        .output_stride(23)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON_ACC2, multipixel_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X25__NEON_ACC2, multipixel_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x25__neon_acc2);
+    }
+  }
+#endif  // XNN_ARCH_ARM || XNN_ARCH_ARM64
+
+
+#if XNN_ARCH_ARM || XNN_ARCH_ARM64
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON, c_eq_8) {
+    TEST_REQUIRES_ARM_NEON;
+    DWConvMicrokernelTester()
+      .cr(8)
+      .kr(25)
+      .channels(8)
+      .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon);
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON, c_div_8) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON, c_div_8_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON, c_div_8_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON, c_lt_8) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 1; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON, c_gt_8) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON, c_gt_8_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON, c_gt_8_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON, multipixel) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON, multipixel_with_step) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      for (size_t step = 2; step <= 25; step++) {
+        DWConvMicrokernelTester()
+          .cr(8)
+          .kr(25)
+          .channels(channels)
+          .width(3)
+          .step(step)
+          .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon);
+      }
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON, multipixel_with_output_stride) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(8)
+        .width(5)
+        .output_stride(43)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON, multipixel_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON, multipixel_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon);
+    }
+  }
+#endif  // XNN_ARCH_ARM || XNN_ARCH_ARM64
+
+
+#if XNN_ARCH_ARM || XNN_ARCH_ARM64
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON_ACC2, c_eq_8) {
+    TEST_REQUIRES_ARM_NEON;
+    DWConvMicrokernelTester()
+      .cr(8)
+      .kr(25)
+      .channels(8)
+      .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon_acc2);
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON_ACC2, c_div_8) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON_ACC2, c_div_8_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON_ACC2, c_div_8_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON_ACC2, c_lt_8) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 1; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON_ACC2, c_gt_8) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON_ACC2, c_gt_8_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON_ACC2, c_gt_8_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON_ACC2, multipixel) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON_ACC2, multipixel_with_step) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      for (size_t step = 2; step <= 25; step++) {
+        DWConvMicrokernelTester()
+          .cr(8)
+          .kr(25)
+          .channels(channels)
+          .width(3)
+          .step(step)
+          .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon_acc2);
+      }
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON_ACC2, multipixel_with_output_stride) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(8)
+        .width(5)
+        .output_stride(43)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON_ACC2, multipixel_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X25__NEON_ACC2, multipixel_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(25)
+        .channels(channels)
+        .width(3)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x25__neon_acc2);
+    }
+  }
+#endif  // XNN_ARCH_ARM || XNN_ARCH_ARM64
+
+
+#if XNN_ARCH_ARM || XNN_ARCH_ARM64
   TEST(F32_DWCONV_MINMAX_UP4X9__NEON, c_eq_4) {
     TEST_REQUIRES_ARM_NEON;
     DWConvMicrokernelTester()
@@ -1619,6 +3527,642 @@
 #endif  // XNN_ARCH_ARM || XNN_ARCH_ARM64
 
 
+#if XNN_ARCH_ARM || XNN_ARCH_ARM64
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON, c_eq_4) {
+    TEST_REQUIRES_ARM_NEON;
+    DWConvMicrokernelTester()
+      .cr(4)
+      .kr(4)
+      .channels(4)
+      .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon);
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON, c_div_4) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON, c_div_4_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON, c_div_4_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON, c_lt_4) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 1; channels < 4; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON, c_gt_4) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON, c_gt_4_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON, c_gt_4_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON, multipixel) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON, multipixel_with_step) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      for (size_t step = 2; step <= 4; step++) {
+        DWConvMicrokernelTester()
+          .cr(4)
+          .kr(4)
+          .channels(channels)
+          .width(3)
+          .step(step)
+          .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon);
+      }
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON, multipixel_with_output_stride) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(4)
+        .width(5)
+        .output_stride(23)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON, multipixel_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON, multipixel_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon);
+    }
+  }
+#endif  // XNN_ARCH_ARM || XNN_ARCH_ARM64
+
+
+#if XNN_ARCH_ARM || XNN_ARCH_ARM64
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON_ACC2, c_eq_4) {
+    TEST_REQUIRES_ARM_NEON;
+    DWConvMicrokernelTester()
+      .cr(4)
+      .kr(4)
+      .channels(4)
+      .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon_acc2);
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON_ACC2, c_div_4) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON_ACC2, c_div_4_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON_ACC2, c_div_4_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 8; channels < 64; channels += 12) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON_ACC2, c_lt_4) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 1; channels < 4; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON_ACC2, c_gt_4) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON_ACC2, c_gt_4_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON_ACC2, c_gt_4_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 5; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON_ACC2, multipixel) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON_ACC2, multipixel_with_step) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      for (size_t step = 2; step <= 4; step++) {
+        DWConvMicrokernelTester()
+          .cr(4)
+          .kr(4)
+          .channels(channels)
+          .width(3)
+          .step(step)
+          .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon_acc2);
+      }
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON_ACC2, multipixel_with_output_stride) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(4)
+        .width(5)
+        .output_stride(23)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON_ACC2, multipixel_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP4X4__NEON_ACC2, multipixel_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 20; channels += 3) {
+      DWConvMicrokernelTester()
+        .cr(4)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up4x4__neon_acc2);
+    }
+  }
+#endif  // XNN_ARCH_ARM || XNN_ARCH_ARM64
+
+
+#if XNN_ARCH_ARM || XNN_ARCH_ARM64
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON, c_eq_8) {
+    TEST_REQUIRES_ARM_NEON;
+    DWConvMicrokernelTester()
+      .cr(8)
+      .kr(4)
+      .channels(8)
+      .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon);
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON, c_div_8) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON, c_div_8_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON, c_div_8_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON, c_lt_8) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 1; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON, c_gt_8) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON, c_gt_8_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON, c_gt_8_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON, multipixel) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON, multipixel_with_step) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      for (size_t step = 2; step <= 4; step++) {
+        DWConvMicrokernelTester()
+          .cr(8)
+          .kr(4)
+          .channels(channels)
+          .width(3)
+          .step(step)
+          .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon);
+      }
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON, multipixel_with_output_stride) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(8)
+        .width(5)
+        .output_stride(43)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON, multipixel_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON, multipixel_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon);
+    }
+  }
+#endif  // XNN_ARCH_ARM || XNN_ARCH_ARM64
+
+
+#if XNN_ARCH_ARM || XNN_ARCH_ARM64
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON_ACC2, c_eq_8) {
+    TEST_REQUIRES_ARM_NEON;
+    DWConvMicrokernelTester()
+      .cr(8)
+      .kr(4)
+      .channels(8)
+      .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon_acc2);
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON_ACC2, c_div_8) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON_ACC2, c_div_8_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON_ACC2, c_div_8_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 16; channels < 128; channels += 24) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON_ACC2, c_lt_8) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 1; channels < 8; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON_ACC2, c_gt_8) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON_ACC2, c_gt_8_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON_ACC2, c_gt_8_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (uint32_t channels = 9; channels < 16; channels++) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON_ACC2, multipixel) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON_ACC2, multipixel_with_step) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      for (size_t step = 2; step <= 4; step++) {
+        DWConvMicrokernelTester()
+          .cr(8)
+          .kr(4)
+          .channels(channels)
+          .width(3)
+          .step(step)
+          .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon_acc2);
+      }
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON_ACC2, multipixel_with_output_stride) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(8)
+        .width(5)
+        .output_stride(43)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON_ACC2, multipixel_with_qmin) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .qmin(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon_acc2);
+    }
+  }
+
+  TEST(F32_DWCONV_MINMAX_UP8X4__NEON_ACC2, multipixel_with_qmax) {
+    TEST_REQUIRES_ARM_NEON;
+    for (size_t channels = 1; channels <= 40; channels += 7) {
+      DWConvMicrokernelTester()
+        .cr(8)
+        .kr(4)
+        .channels(channels)
+        .width(3)
+        .qmax(128)
+        .Test(xnn_f32_dwconv_minmax_ukernel_up8x4__neon_acc2);
+    }
+  }
+#endif  // XNN_ARCH_ARM || XNN_ARCH_ARM64
+
+
 #if XNN_ARCH_X86 || XNN_ARCH_X86_64
   TEST(F32_DWCONV_MINMAX_UP4X25__SSE, c_eq_4) {
     TEST_REQUIRES_X86_SSE;