[llvm] [AArch64] Remove superfluous bitconvert from bfdot lane pattern (PR #221745)

David Green via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 7 07:06:46 PDT 2026


https://github.com/davemgreen created https://github.com/llvm/llvm-project/pull/221745

We don't need to detect the outermost bitconvert, and it might well have been optimised away. Fixes a regression since llvm 21.

>From fe557516a2b1596f7b2484b7e18233ea73ac6bc6 Mon Sep 17 00:00:00 2001
From: David Green <david.green at arm.com>
Date: Mon, 7 Sep 2026 14:54:44 +0100
Subject: [PATCH 1/2] Test!

---
 .../aarch64-bf16-dotprod-intrinsics.ll        | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/llvm/test/CodeGen/AArch64/aarch64-bf16-dotprod-intrinsics.ll b/llvm/test/CodeGen/AArch64/aarch64-bf16-dotprod-intrinsics.ll
index ca3cd6bbae549..e50c858851116 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-bf16-dotprod-intrinsics.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-bf16-dotprod-intrinsics.ll
@@ -182,6 +182,25 @@ entry:
   ret <2 x float> %vbfdotq
 }
 
+define <2 x float> @test_vbfdotq_lane_f32_v2f32_load(ptr %r_val_vals, ptr %a_val_vals, ptr %b_val_vals) {
+; CHECK-LABEL: test_vbfdotq_lane_f32_v2f32_load:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    ldr d0, [x2]
+; CHECK-NEXT:    ldr d2, [x1]
+; CHECK-NEXT:    dup v1.2s, v0.s[1]
+; CHECK-NEXT:    ldr d0, [x0]
+; CHECK-NEXT:    bfdot v0.2s, v2.4h, v1.4h
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <2 x float>, ptr %r_val_vals, align 4
+  %1 = load <4 x bfloat>, ptr %a_val_vals, align 2
+  %2 = load <4 x bfloat>, ptr %b_val_vals, align 2
+  %3 = shufflevector <4 x bfloat> %2, <4 x bfloat> poison, <4 x i32> <i32 2, i32 3, i32 2, i32 3>
+  %vbfdot3.i = tail call <2 x float> @llvm.aarch64.neon.bfdot.v2f32.v4bf16(<2 x float> %0, <4 x bfloat> %1, <4 x bfloat> %3)
+  ret <2 x float> %vbfdot3.i
+}
+
+
 declare <2 x float> @llvm.aarch64.neon.bfdot.v2f32.v4bf16(<2 x float>, <4 x bfloat>, <4 x bfloat>)
 declare <4 x float> @llvm.aarch64.neon.bfdot.v4f32.v8bf16(<4 x float>, <8 x bfloat>, <8 x bfloat>)
 declare <4 x float> @llvm.aarch64.neon.bfmmla(<4 x float>, <8 x bfloat>, <8 x bfloat>)

>From 89d320a6bec467e01047fc9aacf06a6f09fdf982 Mon Sep 17 00:00:00 2001
From: David Green <david.green at arm.com>
Date: Mon, 7 Sep 2026 14:57:44 +0100
Subject: [PATCH 2/2] [AArch64] Remove superfluous bitconvert from bfdot lane
 pattern

We don't need to detect the outermost bitconvert, and it might well have been
optimized away. Fixes a regression since llvm 21.
---
 llvm/lib/Target/AArch64/AArch64InstrFormats.td             | 4 ++--
 .../CodeGen/AArch64/aarch64-bf16-dotprod-intrinsics.ll     | 7 +++----
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index 68c80f5d112ae..705b2160ebc1e 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -9206,8 +9206,8 @@ multiclass BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm,
     def : Pat<(AccumType (int_aarch64_neon_bfdot
                 (AccumType RegType:$Rd), (InputType RegType:$Rn),
                 (InputType (bitconvert
-                  (DupTypes.VT0 (AArch64duplane32 (DupTypes.VT1
-                    (bitconvert (v8bf16 V128:$Rm))), VectorIndexS:$Idx)))))),
+                  (DupTypes.VT0 (AArch64duplane32 (DupTypes.VT1 V128:$Rm),
+                                                  VectorIndexS:$Idx)))))),
               (!cast<Instruction>(NAME) $Rd, $Rn, $Rm, VectorIndexS:$Idx)>;
   }
 }
diff --git a/llvm/test/CodeGen/AArch64/aarch64-bf16-dotprod-intrinsics.ll b/llvm/test/CodeGen/AArch64/aarch64-bf16-dotprod-intrinsics.ll
index e50c858851116..092816e2eadc8 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-bf16-dotprod-intrinsics.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-bf16-dotprod-intrinsics.ll
@@ -185,11 +185,10 @@ entry:
 define <2 x float> @test_vbfdotq_lane_f32_v2f32_load(ptr %r_val_vals, ptr %a_val_vals, ptr %b_val_vals) {
 ; CHECK-LABEL: test_vbfdotq_lane_f32_v2f32_load:
 ; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    ldr d0, [x2]
-; CHECK-NEXT:    ldr d2, [x1]
-; CHECK-NEXT:    dup v1.2s, v0.s[1]
 ; CHECK-NEXT:    ldr d0, [x0]
-; CHECK-NEXT:    bfdot v0.2s, v2.4h, v1.4h
+; CHECK-NEXT:    ldr d1, [x1]
+; CHECK-NEXT:    ldr d2, [x2]
+; CHECK-NEXT:    bfdot v0.2s, v1.4h, v2.2h[1]
 ; CHECK-NEXT:    ret
 entry:
   %0 = load <2 x float>, ptr %r_val_vals, align 4



More information about the llvm-commits mailing list