[llvm] [AArch64] Address issue reported in PR#196029 (PR #199122)

Sushant Gokhale via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 3 03:52:32 PDT 2026


https://github.com/sushgokh updated https://github.com/llvm/llvm-project/pull/199122

>From 87cdfa17de8280a8ec54398d91618bd3ab391d6b Mon Sep 17 00:00:00 2001
From: sgokhale <sgokhale at nvidia.com>
Date: Thu, 21 May 2026 14:48:21 -0700
Subject: [PATCH 1/5] [AArch64] Address issue reported in PR#196029

For certain types of truncating stores, the lowering action is set to custom although no custom lowering exists for them.

Add  a guard to prevent such false entry.

Addresses issue reported in PR#196029
---
 .../lib/Target/AArch64/AArch64ISelLowering.cpp | 18 +++++++++++++-----
 .../AArch64/sve-fixed-length-trunc-stores.ll   | 13 +++++++++++++
 2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 9b36339e419fb..681f4ed5e569d 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -1774,11 +1774,19 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
     }
 
     // SVE supports truncating stores of 64 and 128-bit vectors
-    setTruncStoreAction(MVT::v2i64, MVT::v2i8, Custom);
-    setTruncStoreAction(MVT::v2i64, MVT::v2i16, Custom);
-    setTruncStoreAction(MVT::v2i64, MVT::v2i32, Custom);
-    setTruncStoreAction(MVT::v2i32, MVT::v2i8, Custom);
-    setTruncStoreAction(MVT::v2i32, MVT::v2i16, Custom);
+    auto UseSVE = [&](MVT VT) {
+      return useSVEForFixedLengthVectorVT(
+          VT, /*OverrideNEON=*/Subtarget->useSVEForFixedLengthVectors());
+    };
+    if (UseSVE(MVT::v2i64)) {
+      setTruncStoreAction(MVT::v2i64, MVT::v2i8, Custom);
+      setTruncStoreAction(MVT::v2i64, MVT::v2i16, Custom);
+      setTruncStoreAction(MVT::v2i64, MVT::v2i32, Custom);
+    }
+    if (UseSVE(MVT::v2i32)) {
+      setTruncStoreAction(MVT::v2i32, MVT::v2i8, Custom);
+      setTruncStoreAction(MVT::v2i32, MVT::v2i16, Custom);
+    }
 
     for (auto VT : {MVT::nxv2f16, MVT::nxv4f16, MVT::nxv8f16, MVT::nxv2f32,
                     MVT::nxv4f32, MVT::nxv2f64}) {
diff --git a/llvm/test/CodeGen/AArch64/sve-fixed-length-trunc-stores.ll b/llvm/test/CodeGen/AArch64/sve-fixed-length-trunc-stores.ll
index f4fc2ff121cd5..2436fd616895b 100644
--- a/llvm/test/CodeGen/AArch64/sve-fixed-length-trunc-stores.ll
+++ b/llvm/test/CodeGen/AArch64/sve-fixed-length-trunc-stores.ll
@@ -202,4 +202,17 @@ define void @store_trunc_v32i16i8(ptr %ap, ptr %dest) #0 {
   ret void
 }
 
+define void @store_trunc_v4i64i32(ptr %src, ptr %dest) vscale_range(1,0) "target-features"="+neon,+sve" {
+; CHECK-LABEL: store_trunc_v4i64i32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    ldp q1, q0, [x0]
+; CHECK-NEXT:    uzp1 v0.4s, v1.4s, v0.4s
+; CHECK-NEXT:    str q0, [x1]
+; CHECK-NEXT:    ret
+  %ld = load <4 x i64>, ptr %src, align 4
+  %trunc = trunc <4 x i64> %ld to <4 x i32>
+  store <4 x i32> %trunc, ptr %dest, align 8
+  ret void
+}
+
 attributes #0 = { "target-features"="+sve" }

>From 28f791d51f49a87aa4596b50a94a893251bdbd24 Mon Sep 17 00:00:00 2001
From: sgokhale <sgokhale at nvidia.com>
Date: Thu, 21 May 2026 23:15:54 -0700
Subject: [PATCH 2/5] Amend previous patch

---
 .../Target/AArch64/AArch64ISelLowering.cpp    | 22 ++++++++-----------
 .../AArch64/sve-fixed-length-trunc-stores.ll  | 18 +++++++++++++--
 2 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 681f4ed5e569d..42cdf7cac3ddb 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -1774,19 +1774,15 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
     }
 
     // SVE supports truncating stores of 64 and 128-bit vectors
-    auto UseSVE = [&](MVT VT) {
-      return useSVEForFixedLengthVectorVT(
-          VT, /*OverrideNEON=*/Subtarget->useSVEForFixedLengthVectors());
-    };
-    if (UseSVE(MVT::v2i64)) {
-      setTruncStoreAction(MVT::v2i64, MVT::v2i8, Custom);
-      setTruncStoreAction(MVT::v2i64, MVT::v2i16, Custom);
-      setTruncStoreAction(MVT::v2i64, MVT::v2i32, Custom);
-    }
-    if (UseSVE(MVT::v2i32)) {
-      setTruncStoreAction(MVT::v2i32, MVT::v2i8, Custom);
-      setTruncStoreAction(MVT::v2i32, MVT::v2i16, Custom);
-    }
+    auto VT = MVT::v2i64;
+    if (useSVEForFixedLengthVectorVT(
+            VT, /*OverrideNEON=*/Subtarget->useSVEForFixedLengthVectors()))
+      setTruncStoreAction(VT, MVT::v2i32, Custom);
+
+    setTruncStoreAction(MVT::v2i64, MVT::v2i8, Custom);
+    setTruncStoreAction(MVT::v2i64, MVT::v2i16, Custom);
+    setTruncStoreAction(MVT::v2i32, MVT::v2i8, Custom);
+    setTruncStoreAction(MVT::v2i32, MVT::v2i16, Custom);
 
     for (auto VT : {MVT::nxv2f16, MVT::nxv4f16, MVT::nxv8f16, MVT::nxv2f32,
                     MVT::nxv4f32, MVT::nxv2f64}) {
diff --git a/llvm/test/CodeGen/AArch64/sve-fixed-length-trunc-stores.ll b/llvm/test/CodeGen/AArch64/sve-fixed-length-trunc-stores.ll
index 2436fd616895b..e8a348453e332 100644
--- a/llvm/test/CodeGen/AArch64/sve-fixed-length-trunc-stores.ll
+++ b/llvm/test/CodeGen/AArch64/sve-fixed-length-trunc-stores.ll
@@ -202,8 +202,22 @@ define void @store_trunc_v32i16i8(ptr %ap, ptr %dest) #0 {
   ret void
 }
 
-define void @store_trunc_v4i64i32(ptr %src, ptr %dest) vscale_range(1,0) "target-features"="+neon,+sve" {
-; CHECK-LABEL: store_trunc_v4i64i32:
+define void @store_trunc_v4i64i32_neon_sve(ptr %src, ptr %dest) vscale_range(1,0) "target-features"="+neon,+sve" {
+; CHECK-LABEL: store_trunc_v4i64i32_neon_sve:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    ldp q1, q0, [x0]
+; CHECK-NEXT:    uzp1 v0.4s, v1.4s, v0.4s
+; CHECK-NEXT:    str q0, [x1]
+; CHECK-NEXT:    ret
+  %ld = load <4 x i64>, ptr %src, align 4
+  %trunc = trunc <4 x i64> %ld to <4 x i32>
+  store <4 x i32> %trunc, ptr %dest, align 8
+  ret void
+}
+
+
+define void @store_trunc_v4i64i32_sve_only(ptr %src, ptr %dest) vscale_range(1,0) #0 {
+; CHECK-LABEL: store_trunc_v4i64i32_sve_only:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    ldp q1, q0, [x0]
 ; CHECK-NEXT:    uzp1 v0.4s, v1.4s, v0.4s

>From acebdbd39d800ffb13b15b1ad28920e5280dd8a5 Mon Sep 17 00:00:00 2001
From: sgokhale <sgokhale at nvidia.com>
Date: Sat, 30 May 2026 14:47:32 -0700
Subject: [PATCH 3/5] address review comments

---
 .../AArch64/sve-fixed-length-trunc-stores.ll      | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/llvm/test/CodeGen/AArch64/sve-fixed-length-trunc-stores.ll b/llvm/test/CodeGen/AArch64/sve-fixed-length-trunc-stores.ll
index e8a348453e332..55298bb38fadd 100644
--- a/llvm/test/CodeGen/AArch64/sve-fixed-length-trunc-stores.ll
+++ b/llvm/test/CodeGen/AArch64/sve-fixed-length-trunc-stores.ll
@@ -202,8 +202,8 @@ define void @store_trunc_v32i16i8(ptr %ap, ptr %dest) #0 {
   ret void
 }
 
-define void @store_trunc_v4i64i32_neon_sve(ptr %src, ptr %dest) vscale_range(1,0) "target-features"="+neon,+sve" {
-; CHECK-LABEL: store_trunc_v4i64i32_neon_sve:
+define void @store_trunc_v4i64i32(ptr %src, ptr %dest) vscale_range(1,0) #0 {
+; CHECK-LABEL: store_trunc_v4i64i32:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    ldp q1, q0, [x0]
 ; CHECK-NEXT:    uzp1 v0.4s, v1.4s, v0.4s
@@ -216,12 +216,13 @@ define void @store_trunc_v4i64i32_neon_sve(ptr %src, ptr %dest) vscale_range(1,0
 }
 
 
-define void @store_trunc_v4i64i32_sve_only(ptr %src, ptr %dest) vscale_range(1,0) #0 {
-; CHECK-LABEL: store_trunc_v4i64i32_sve_only:
+define void @store_trunc_v4i64i32_sve_no_neon(ptr %src, ptr %dest) vscale_range(1,0) "target-features"="-neon,+sve" {
+; CHECK-LABEL: store_trunc_v4i64i32_sve_no_neon:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    ldp q1, q0, [x0]
-; CHECK-NEXT:    uzp1 v0.4s, v1.4s, v0.4s
-; CHECK-NEXT:    str q0, [x1]
+; CHECK-NEXT:    ldp x9, x8, [x0, #16]
+; CHECK-NEXT:    ldp x10, x11, [x0]
+; CHECK-NEXT:    stp w9, w8, [x1, #8]
+; CHECK-NEXT:    stp w10, w11, [x1]
 ; CHECK-NEXT:    ret
   %ld = load <4 x i64>, ptr %src, align 4
   %trunc = trunc <4 x i64> %ld to <4 x i32>

>From ccd0551a7da3c89d97911c074e62a9b0db8413e8 Mon Sep 17 00:00:00 2001
From: sgokhale <sgokhale at nvidia.com>
Date: Wed, 3 Jun 2026 03:49:06 -0700
Subject: [PATCH 4/5] address reviewer's comments

---
 llvm/lib/Target/AArch64/AArch64ISelLowering.cpp  |  6 ------
 .../AArch64/sve-fixed-length-trunc-stores.ll     | 16 +++++++---------
 2 files changed, 7 insertions(+), 15 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 42cdf7cac3ddb..ab4062a28d51f 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -1773,12 +1773,6 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
       setLoadExtAction(Op, MVT::nxv8i16, MVT::nxv8i8, Legal);
     }
 
-    // SVE supports truncating stores of 64 and 128-bit vectors
-    auto VT = MVT::v2i64;
-    if (useSVEForFixedLengthVectorVT(
-            VT, /*OverrideNEON=*/Subtarget->useSVEForFixedLengthVectors()))
-      setTruncStoreAction(VT, MVT::v2i32, Custom);
-
     setTruncStoreAction(MVT::v2i64, MVT::v2i8, Custom);
     setTruncStoreAction(MVT::v2i64, MVT::v2i16, Custom);
     setTruncStoreAction(MVT::v2i32, MVT::v2i8, Custom);
diff --git a/llvm/test/CodeGen/AArch64/sve-fixed-length-trunc-stores.ll b/llvm/test/CodeGen/AArch64/sve-fixed-length-trunc-stores.ll
index 55298bb38fadd..9e865e078ca24 100644
--- a/llvm/test/CodeGen/AArch64/sve-fixed-length-trunc-stores.ll
+++ b/llvm/test/CodeGen/AArch64/sve-fixed-length-trunc-stores.ll
@@ -202,8 +202,8 @@ define void @store_trunc_v32i16i8(ptr %ap, ptr %dest) #0 {
   ret void
 }
 
-define void @store_trunc_v4i64i32(ptr %src, ptr %dest) vscale_range(1,0) #0 {
-; CHECK-LABEL: store_trunc_v4i64i32:
+define void @store_trunc_v4i64i32_min_vscale_one(ptr %src, ptr %dest) vscale_range(1,0) #0 {
+; CHECK-LABEL: store_trunc_v4i64i32_min_vscale_one:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    ldp q1, q0, [x0]
 ; CHECK-NEXT:    uzp1 v0.4s, v1.4s, v0.4s
@@ -215,14 +215,12 @@ define void @store_trunc_v4i64i32(ptr %src, ptr %dest) vscale_range(1,0) #0 {
   ret void
 }
 
-
-define void @store_trunc_v4i64i32_sve_no_neon(ptr %src, ptr %dest) vscale_range(1,0) "target-features"="-neon,+sve" {
-; CHECK-LABEL: store_trunc_v4i64i32_sve_no_neon:
+define void @store_trunc_v4i64i32_min_vscale_two(ptr %src, ptr %dest) vscale_range(2,0) #0 {
+; CHECK-LABEL: store_trunc_v4i64i32_min_vscale_two:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    ldp x9, x8, [x0, #16]
-; CHECK-NEXT:    ldp x10, x11, [x0]
-; CHECK-NEXT:    stp w9, w8, [x1, #8]
-; CHECK-NEXT:    stp w10, w11, [x1]
+; CHECK-NEXT:    ptrue p0.d, vl4
+; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0]
+; CHECK-NEXT:    st1w { z0.d }, p0, [x1]
 ; CHECK-NEXT:    ret
   %ld = load <4 x i64>, ptr %src, align 4
   %trunc = trunc <4 x i64> %ld to <4 x i32>

>From 9bbdb1a1bb8273dd1b0dbe270d61f15cd20df845 Mon Sep 17 00:00:00 2001
From: sgokhale <sgokhale at nvidia.com>
Date: Wed, 3 Jun 2026 03:51:55 -0700
Subject: [PATCH 5/5] add existing comment back

---
 llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index ab4062a28d51f..cc6b10b5089b4 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -1773,6 +1773,7 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
       setLoadExtAction(Op, MVT::nxv8i16, MVT::nxv8i8, Legal);
     }
 
+    // SVE supports truncating stores of 64 and 128-bit vectors
     setTruncStoreAction(MVT::v2i64, MVT::v2i8, Custom);
     setTruncStoreAction(MVT::v2i64, MVT::v2i16, Custom);
     setTruncStoreAction(MVT::v2i32, MVT::v2i8, Custom);



More information about the llvm-commits mailing list