[llvm] [X86] Lower bf16 round-to-integer on AVX10.2 via vrndscalebf16 (PR #213276)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 7 03:16:09 PDT 2026
================
@@ -0,0 +1,370 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -verify-machineinstrs -mtriple=x86_64-unknown-unknown -mattr=+avx10.2 | FileCheck %s --check-prefixes=AVX10_2
+; RUN: llc < %s -verify-machineinstrs -mtriple=x86_64-unknown-unknown -mattr=+avx512bf16,+avx512vl | FileCheck %s --check-prefixes=AVX512BF16
+
+; AVX10.2 has packed bf16 round-to-integer instructions. The integral result of
+; floor/ceil/trunc/rint/nearbyint/roundeven is always representable in bf16, so
+; vrndscalebf16 gives the same answer as the AVX512BF16 sequence below (promote
+; each element to f32, round, convert back), but without scalarizing.
+
+define <8 x bfloat> @floor_v8bf16(<8 x bfloat> %a) {
+; AVX10_2-LABEL: floor_v8bf16:
+; AVX10_2: # %bb.0:
+; AVX10_2-NEXT: vrndscalebf16 $9, %xmm0, %xmm0
+; AVX10_2-NEXT: retq
+;
+; AVX512BF16-LABEL: floor_v8bf16:
+; AVX512BF16: # %bb.0:
+; AVX512BF16-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
+; AVX512BF16-NEXT: vpslld $16, %ymm0, %ymm0
+; AVX512BF16-NEXT: vroundps $9, %ymm0, %ymm0
+; AVX512BF16-NEXT: vcvtneps2bf16 %ymm0, %xmm0
+; AVX512BF16-NEXT: vzeroupper
+; AVX512BF16-NEXT: retq
+ %r = call <8 x bfloat> @llvm.floor.v8bf16(<8 x bfloat> %a)
+ ret <8 x bfloat> %r
+}
+
+define bfloat @floor_bf16(bfloat %a) {
+; AVX10_2-LABEL: floor_bf16:
+; AVX10_2: # %bb.0:
+; AVX10_2-NEXT: vrndscalebf16 $9, %xmm0, %xmm0
+; AVX10_2-NEXT: retq
+;
+; AVX512BF16-LABEL: floor_bf16:
+; AVX512BF16: # %bb.0:
+; AVX512BF16-NEXT: vpslld $16, %xmm0, %xmm0
+; AVX512BF16-NEXT: vroundss $9, %xmm0, %xmm0, %xmm0
+; AVX512BF16-NEXT: vcvtneps2bf16 %xmm0, %xmm0
+; AVX512BF16-NEXT: retq
+ %r = call bfloat @llvm.floor.bf16(bfloat %a)
+ ret bfloat %r
+}
+
+define <8 x bfloat> @ceil_v8bf16(<8 x bfloat> %a) {
+; AVX10_2-LABEL: ceil_v8bf16:
+; AVX10_2: # %bb.0:
+; AVX10_2-NEXT: vrndscalebf16 $10, %xmm0, %xmm0
+; AVX10_2-NEXT: retq
+;
+; AVX512BF16-LABEL: ceil_v8bf16:
+; AVX512BF16: # %bb.0:
+; AVX512BF16-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
+; AVX512BF16-NEXT: vpslld $16, %ymm0, %ymm0
+; AVX512BF16-NEXT: vroundps $10, %ymm0, %ymm0
+; AVX512BF16-NEXT: vcvtneps2bf16 %ymm0, %xmm0
+; AVX512BF16-NEXT: vzeroupper
+; AVX512BF16-NEXT: retq
+ %r = call <8 x bfloat> @llvm.ceil.v8bf16(<8 x bfloat> %a)
+ ret <8 x bfloat> %r
+}
+
+define bfloat @ceil_bf16(bfloat %a) {
+; AVX10_2-LABEL: ceil_bf16:
+; AVX10_2: # %bb.0:
+; AVX10_2-NEXT: vrndscalebf16 $10, %xmm0, %xmm0
+; AVX10_2-NEXT: retq
+;
+; AVX512BF16-LABEL: ceil_bf16:
+; AVX512BF16: # %bb.0:
+; AVX512BF16-NEXT: vpslld $16, %xmm0, %xmm0
+; AVX512BF16-NEXT: vroundss $10, %xmm0, %xmm0, %xmm0
+; AVX512BF16-NEXT: vcvtneps2bf16 %xmm0, %xmm0
+; AVX512BF16-NEXT: retq
+ %r = call bfloat @llvm.ceil.bf16(bfloat %a)
+ ret bfloat %r
+}
+
+define <8 x bfloat> @trunc_v8bf16(<8 x bfloat> %a) {
+; AVX10_2-LABEL: trunc_v8bf16:
+; AVX10_2: # %bb.0:
+; AVX10_2-NEXT: vrndscalebf16 $11, %xmm0, %xmm0
+; AVX10_2-NEXT: retq
+;
+; AVX512BF16-LABEL: trunc_v8bf16:
+; AVX512BF16: # %bb.0:
+; AVX512BF16-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
+; AVX512BF16-NEXT: vpslld $16, %ymm0, %ymm0
+; AVX512BF16-NEXT: vroundps $11, %ymm0, %ymm0
+; AVX512BF16-NEXT: vcvtneps2bf16 %ymm0, %xmm0
+; AVX512BF16-NEXT: vzeroupper
+; AVX512BF16-NEXT: retq
+ %r = call <8 x bfloat> @llvm.trunc.v8bf16(<8 x bfloat> %a)
+ ret <8 x bfloat> %r
+}
+
+define bfloat @trunc_bf16(bfloat %a) {
+; AVX10_2-LABEL: trunc_bf16:
+; AVX10_2: # %bb.0:
+; AVX10_2-NEXT: vrndscalebf16 $11, %xmm0, %xmm0
+; AVX10_2-NEXT: retq
+;
+; AVX512BF16-LABEL: trunc_bf16:
+; AVX512BF16: # %bb.0:
+; AVX512BF16-NEXT: vpslld $16, %xmm0, %xmm0
+; AVX512BF16-NEXT: vroundss $11, %xmm0, %xmm0, %xmm0
+; AVX512BF16-NEXT: vcvtneps2bf16 %xmm0, %xmm0
+; AVX512BF16-NEXT: retq
+ %r = call bfloat @llvm.trunc.bf16(bfloat %a)
+ ret bfloat %r
+}
+
+define <8 x bfloat> @rint_v8bf16(<8 x bfloat> %a) {
+; AVX10_2-LABEL: rint_v8bf16:
+; AVX10_2: # %bb.0:
+; AVX10_2-NEXT: vrndscalebf16 $4, %xmm0, %xmm0
+; AVX10_2-NEXT: retq
+;
+; AVX512BF16-LABEL: rint_v8bf16:
+; AVX512BF16: # %bb.0:
+; AVX512BF16-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
+; AVX512BF16-NEXT: vpslld $16, %ymm0, %ymm0
+; AVX512BF16-NEXT: vroundps $4, %ymm0, %ymm0
+; AVX512BF16-NEXT: vcvtneps2bf16 %ymm0, %xmm0
+; AVX512BF16-NEXT: vzeroupper
+; AVX512BF16-NEXT: retq
+ %r = call <8 x bfloat> @llvm.rint.v8bf16(<8 x bfloat> %a)
+ ret <8 x bfloat> %r
+}
+
+define bfloat @rint_bf16(bfloat %a) {
+; AVX10_2-LABEL: rint_bf16:
+; AVX10_2: # %bb.0:
+; AVX10_2-NEXT: vrndscalebf16 $4, %xmm0, %xmm0
+; AVX10_2-NEXT: retq
+;
+; AVX512BF16-LABEL: rint_bf16:
+; AVX512BF16: # %bb.0:
+; AVX512BF16-NEXT: vpslld $16, %xmm0, %xmm0
+; AVX512BF16-NEXT: vroundss $4, %xmm0, %xmm0, %xmm0
+; AVX512BF16-NEXT: vcvtneps2bf16 %xmm0, %xmm0
+; AVX512BF16-NEXT: retq
+ %r = call bfloat @llvm.rint.bf16(bfloat %a)
+ ret bfloat %r
+}
+
+define <8 x bfloat> @nearbyint_v8bf16(<8 x bfloat> %a) {
+; AVX10_2-LABEL: nearbyint_v8bf16:
+; AVX10_2: # %bb.0:
+; AVX10_2-NEXT: vrndscalebf16 $12, %xmm0, %xmm0
+; AVX10_2-NEXT: retq
+;
+; AVX512BF16-LABEL: nearbyint_v8bf16:
+; AVX512BF16: # %bb.0:
+; AVX512BF16-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
+; AVX512BF16-NEXT: vpslld $16, %ymm0, %ymm0
+; AVX512BF16-NEXT: vroundps $12, %ymm0, %ymm0
+; AVX512BF16-NEXT: vcvtneps2bf16 %ymm0, %xmm0
+; AVX512BF16-NEXT: vzeroupper
+; AVX512BF16-NEXT: retq
+ %r = call <8 x bfloat> @llvm.nearbyint.v8bf16(<8 x bfloat> %a)
+ ret <8 x bfloat> %r
+}
+
+define bfloat @nearbyint_bf16(bfloat %a) {
+; AVX10_2-LABEL: nearbyint_bf16:
+; AVX10_2: # %bb.0:
+; AVX10_2-NEXT: vrndscalebf16 $12, %xmm0, %xmm0
+; AVX10_2-NEXT: retq
+;
+; AVX512BF16-LABEL: nearbyint_bf16:
+; AVX512BF16: # %bb.0:
+; AVX512BF16-NEXT: vpslld $16, %xmm0, %xmm0
+; AVX512BF16-NEXT: vroundss $12, %xmm0, %xmm0, %xmm0
+; AVX512BF16-NEXT: vcvtneps2bf16 %xmm0, %xmm0
+; AVX512BF16-NEXT: retq
+ %r = call bfloat @llvm.nearbyint.bf16(bfloat %a)
+ ret bfloat %r
+}
+
+define <8 x bfloat> @roundeven_v8bf16(<8 x bfloat> %a) {
+; AVX10_2-LABEL: roundeven_v8bf16:
+; AVX10_2: # %bb.0:
+; AVX10_2-NEXT: vrndscalebf16 $8, %xmm0, %xmm0
+; AVX10_2-NEXT: retq
+;
+; AVX512BF16-LABEL: roundeven_v8bf16:
+; AVX512BF16: # %bb.0:
+; AVX512BF16-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
+; AVX512BF16-NEXT: vpslld $16, %ymm0, %ymm0
+; AVX512BF16-NEXT: vroundps $8, %ymm0, %ymm0
+; AVX512BF16-NEXT: vcvtneps2bf16 %ymm0, %xmm0
+; AVX512BF16-NEXT: vzeroupper
+; AVX512BF16-NEXT: retq
+ %r = call <8 x bfloat> @llvm.roundeven.v8bf16(<8 x bfloat> %a)
+ ret <8 x bfloat> %r
+}
+
+define bfloat @roundeven_bf16(bfloat %a) {
+; AVX10_2-LABEL: roundeven_bf16:
+; AVX10_2: # %bb.0:
+; AVX10_2-NEXT: vrndscalebf16 $8, %xmm0, %xmm0
+; AVX10_2-NEXT: retq
+;
+; AVX512BF16-LABEL: roundeven_bf16:
+; AVX512BF16: # %bb.0:
+; AVX512BF16-NEXT: vpslld $16, %xmm0, %xmm0
+; AVX512BF16-NEXT: vroundss $8, %xmm0, %xmm0, %xmm0
+; AVX512BF16-NEXT: vcvtneps2bf16 %xmm0, %xmm0
+; AVX512BF16-NEXT: retq
+ %r = call bfloat @llvm.roundeven.bf16(bfloat %a)
+ ret bfloat %r
+}
+
+; ymm and zmm come from separate setOperationAction entries than the xmm ones.
+define <16 x bfloat> @floor_v16bf16(<16 x bfloat> %a) {
+; AVX10_2-LABEL: floor_v16bf16:
+; AVX10_2: # %bb.0:
+; AVX10_2-NEXT: vrndscalebf16 $9, %ymm0, %ymm0
+; AVX10_2-NEXT: retq
+;
+; AVX512BF16-LABEL: floor_v16bf16:
+; AVX512BF16: # %bb.0:
+; AVX512BF16-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero
+; AVX512BF16-NEXT: vpslld $16, %zmm0, %zmm0
+; AVX512BF16-NEXT: vrndscaleps $9, %zmm0, %zmm0
+; AVX512BF16-NEXT: vcvtneps2bf16 %zmm0, %ymm0
+; AVX512BF16-NEXT: retq
+ %r = call <16 x bfloat> @llvm.floor.v16bf16(<16 x bfloat> %a)
+ ret <16 x bfloat> %r
+}
+
+define <32 x bfloat> @floor_v32bf16(<32 x bfloat> %a) {
+; AVX10_2-LABEL: floor_v32bf16:
+; AVX10_2: # %bb.0:
+; AVX10_2-NEXT: vrndscalebf16 $9, %zmm0, %zmm0
+; AVX10_2-NEXT: retq
+;
+; AVX512BF16-LABEL: floor_v32bf16:
+; AVX512BF16: # %bb.0:
+; AVX512BF16-NEXT: vpmovzxwd {{.*#+}} zmm1 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero
+; AVX512BF16-NEXT: vpslld $16, %zmm1, %zmm1
+; AVX512BF16-NEXT: vrndscaleps $9, %zmm1, %zmm1
+; AVX512BF16-NEXT: vcvtneps2bf16 %zmm1, %ymm1
+; AVX512BF16-NEXT: vextracti64x4 $1, %zmm0, %ymm0
+; AVX512BF16-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero
+; AVX512BF16-NEXT: vpslld $16, %zmm0, %zmm0
+; AVX512BF16-NEXT: vrndscaleps $9, %zmm0, %zmm0
+; AVX512BF16-NEXT: vcvtneps2bf16 %zmm0, %ymm0
+; AVX512BF16-NEXT: vinsertf64x4 $1, %ymm0, %zmm1, %zmm0
+; AVX512BF16-NEXT: retq
+ %r = call <32 x bfloat> @llvm.floor.v32bf16(<32 x bfloat> %a)
+ ret <32 x bfloat> %r
+}
+
+; Narrower than a full vector register: widened, not scalarized.
+define <2 x bfloat> @floor_v2bf16(<2 x bfloat> %a) {
+; AVX10_2-LABEL: floor_v2bf16:
+; AVX10_2: # %bb.0:
+; AVX10_2-NEXT: vrndscalebf16 $9, %xmm0, %xmm0
+; AVX10_2-NEXT: retq
+;
+; AVX512BF16-LABEL: floor_v2bf16:
+; AVX512BF16: # %bb.0:
+; AVX512BF16-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
+; AVX512BF16-NEXT: vpslld $16, %ymm0, %ymm0
+; AVX512BF16-NEXT: vroundps $9, %ymm0, %ymm0
+; AVX512BF16-NEXT: vcvtneps2bf16 %ymm0, %xmm0
+; AVX512BF16-NEXT: vzeroupper
+; AVX512BF16-NEXT: retq
+ %r = call <2 x bfloat> @llvm.floor.v2bf16(<2 x bfloat> %a)
+ ret <2 x bfloat> %r
+}
+
+; Folded load operand.
+define <8 x bfloat> @floor_v8bf16_load(ptr %p) {
+; AVX10_2-LABEL: floor_v8bf16_load:
+; AVX10_2: # %bb.0:
+; AVX10_2-NEXT: vrndscalebf16 $9, (%rdi), %xmm0
+; AVX10_2-NEXT: retq
+;
+; AVX512BF16-LABEL: floor_v8bf16_load:
+; AVX512BF16: # %bb.0:
+; AVX512BF16-NEXT: vpmovzxwd {{.*#+}} ymm0 = mem[0],zero,mem[1],zero,mem[2],zero,mem[3],zero,mem[4],zero,mem[5],zero,mem[6],zero,mem[7],zero
+; AVX512BF16-NEXT: vpslld $16, %ymm0, %ymm0
+; AVX512BF16-NEXT: vroundps $9, %ymm0, %ymm0
+; AVX512BF16-NEXT: vcvtneps2bf16 %ymm0, %xmm0
+; AVX512BF16-NEXT: vzeroupper
+; AVX512BF16-NEXT: retq
+ %a = load <8 x bfloat>, ptr %p
+ %r = call <8 x bfloat> @llvm.floor.v8bf16(<8 x bfloat> %a)
+ ret <8 x bfloat> %r
+}
+
+; Masked forms, exercising the AVX512_maskable patterns.
+define <8 x bfloat> @floor_v8bf16_mask(<8 x bfloat> %a, <8 x bfloat> %src, i8 %msk) {
+; AVX10_2-LABEL: floor_v8bf16_mask:
+; AVX10_2: # %bb.0:
+; AVX10_2-NEXT: kmovd %edi, %k1
+; AVX10_2-NEXT: vrndscalebf16 $9, %xmm0, %xmm1 {%k1}
+; AVX10_2-NEXT: vmovdqa %xmm1, %xmm0
+; AVX10_2-NEXT: retq
+;
+; AVX512BF16-LABEL: floor_v8bf16_mask:
+; AVX512BF16: # %bb.0:
+; AVX512BF16-NEXT: kmovd %edi, %k1
+; AVX512BF16-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
+; AVX512BF16-NEXT: vpslld $16, %ymm0, %ymm0
+; AVX512BF16-NEXT: vroundps $9, %ymm0, %ymm0
+; AVX512BF16-NEXT: vcvtneps2bf16 %ymm0, %xmm0
+; AVX512BF16-NEXT: vpblendmw %xmm0, %xmm1, %xmm0 {%k1}
+; AVX512BF16-NEXT: vzeroupper
+; AVX512BF16-NEXT: retq
+ %mask = bitcast i8 %msk to <8 x i1>
+ %r = call <8 x bfloat> @llvm.floor.v8bf16(<8 x bfloat> %a)
+ %res = select <8 x i1> %mask, <8 x bfloat> %r, <8 x bfloat> %src
+ ret <8 x bfloat> %res
+}
+
+define <8 x bfloat> @floor_v8bf16_maskz(<8 x bfloat> %a, i8 %msk) {
+; AVX10_2-LABEL: floor_v8bf16_maskz:
+; AVX10_2: # %bb.0:
+; AVX10_2-NEXT: kmovd %edi, %k1
+; AVX10_2-NEXT: vrndscalebf16 $9, %xmm0, %xmm0 {%k1} {z}
+; AVX10_2-NEXT: retq
+;
+; AVX512BF16-LABEL: floor_v8bf16_maskz:
+; AVX512BF16: # %bb.0:
+; AVX512BF16-NEXT: kmovd %edi, %k1
+; AVX512BF16-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
+; AVX512BF16-NEXT: vpslld $16, %ymm0, %ymm0
+; AVX512BF16-NEXT: vroundps $9, %ymm0, %ymm0
+; AVX512BF16-NEXT: vcvtneps2bf16 %ymm0, %xmm0
+; AVX512BF16-NEXT: vmovdqu16 %xmm0, %xmm0 {%k1} {z}
+; AVX512BF16-NEXT: vzeroupper
+; AVX512BF16-NEXT: retq
+ %mask = bitcast i8 %msk to <8 x i1>
+ %r = call <8 x bfloat> @llvm.floor.v8bf16(<8 x bfloat> %a)
+ %res = select <8 x i1> %mask, <8 x bfloat> %r, <8 x bfloat> zeroinitializer
+ ret <8 x bfloat> %res
+}
+
+; llvm.round is round-half-away-from-zero, which vrndscale cannot encode, so it
+; must stay scalarized rather than becoming a vrndscalebf16.
+define <8 x bfloat> @round_v8bf16(<8 x bfloat> %a) {
+; AVX10_2-LABEL: round_v8bf16:
+; AVX10_2: # %bb.0:
+; AVX10_2-NEXT: vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
+; AVX10_2-NEXT: vpslld $16, %ymm0, %ymm0
+; AVX10_2-NEXT: vpbroadcastd {{.*#+}} ymm1 = [4.9999997E-1,4.9999997E-1,4.9999997E-1,4.9999997E-1,4.9999997E-1,4.9999997E-1,4.9999997E-1,4.9999997E-1]
+; AVX10_2-NEXT: vpternlogd {{.*#+}} ymm1 = ymm1 | (ymm0 & m32bcst)
+; AVX10_2-NEXT: vaddps %ymm1, %ymm0, %ymm0
+; AVX10_2-NEXT: vroundps $11, %ymm0, %ymm0
----------------
tfzee wrote:
Maybe theres a possibility with some different tricks.
But the inherent problem here is llvm.round wants RNA rounding mode.
vrndscalebf16 only does round-to-nearest-even while the fp32 path can do the current trick where it emulates the rounding mode by first adding 0.5 and then truncating.
https://github.com/llvm/llvm-project/pull/213276
More information about the llvm-commits
mailing list