[llvm] [AArch64] Protect against v3i64->v3i8 truncates in combineI8TruncStore (PR #202039)
David Green via llvm-commits
llvm-commits at lists.llvm.org
Sat Jun 6 06:14:55 PDT 2026
https://github.com/davemgreen created https://github.com/llvm/llvm-project/pull/202039
We were previously creating invalid bitcasts, protect against that by making
sure that the type is legal.
>From 63f4b57c341591ed570758ecd579da42d1d5aee4 Mon Sep 17 00:00:00 2001
From: David Green <david.green at arm.com>
Date: Sat, 6 Jun 2026 14:14:45 +0100
Subject: [PATCH] [AArch64] Protect against v3i64->v3i8 truncates in
combineI8TruncStore
We were previously creating invalid bitcasts, protect against that by making
sure that the type is legal.
---
.../Target/AArch64/AArch64ISelLowering.cpp | 4 +-
.../AArch64/vec3-loads-ext-trunc-stores.ll | 52 +++++++++++++++++++
2 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index b0690aac98ec2..217b0fddd247d 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -26348,9 +26348,11 @@ static SDValue combineI8TruncStore(StoreSDNode *ST, SelectionDAG &DAG,
assert(ST->getOffset().isUndef() && "undef offset expected");
SDLoc DL(ST);
- auto WideVT = EVT::getVectorVT(
+ EVT WideVT = EVT::getVectorVT(
*DAG.getContext(),
Value->getOperand(0).getValueType().getVectorElementType(), 4);
+ if (!DAG.getTargetLoweringInfo().isTypeLegal(WideVT))
+ return SDValue();
SDValue PoisonVector = DAG.getPOISON(WideVT);
SDValue WideTrunc = DAG.getNode(
ISD::INSERT_SUBVECTOR, DL, WideVT,
diff --git a/llvm/test/CodeGen/AArch64/vec3-loads-ext-trunc-stores.ll b/llvm/test/CodeGen/AArch64/vec3-loads-ext-trunc-stores.ll
index 60414adba75fc..85af93eeadbdf 100644
--- a/llvm/test/CodeGen/AArch64/vec3-loads-ext-trunc-stores.ll
+++ b/llvm/test/CodeGen/AArch64/vec3-loads-ext-trunc-stores.ll
@@ -897,3 +897,55 @@ define void @load_v3i8_sext_to_3xi32_add_trunc_store(ptr %src) {
store <3 x i8> %t, ptr %src
ret void
}
+
+define void @store_trunc_v3i64_to_v3i8(ptr %p, <3 x i64> %x) {
+; CHECK-LABEL: store_trunc_v3i64_to_v3i8:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub sp, sp, #16
+; CHECK-NEXT: .cfi_def_cfa_offset 16
+; CHECK-NEXT: ; kill: def $d0 killed $d0 def $q0
+; CHECK-NEXT: ; kill: def $d1 killed $d1 def $q1
+; CHECK-NEXT: ; kill: def $d2 killed $d2 def $q2
+; CHECK-NEXT: mov.d v0[1], v1[0]
+; CHECK-NEXT: xtn.2s v1, v2
+; CHECK-NEXT: xtn.2s v0, v0
+; CHECK-NEXT: stur b1, [x0, #2]
+; CHECK-NEXT: mov.s w8, v0[1]
+; CHECK-NEXT: mov.h v0[1], w8
+; CHECK-NEXT: mov.s w8, v1[1]
+; CHECK-NEXT: mov.h v0[2], v1[0]
+; CHECK-NEXT: mov.h v0[3], w8
+; CHECK-NEXT: xtn.8b v0, v0
+; CHECK-NEXT: ushll.4s v0, v0, #0
+; CHECK-NEXT: str h0, [x0]
+; CHECK-NEXT: add sp, sp, #16
+; CHECK-NEXT: ret
+;
+; BE-LABEL: store_trunc_v3i64_to_v3i8:
+; BE: // %bb.0: // %entry
+; BE-NEXT: sub sp, sp, #16
+; BE-NEXT: .cfi_def_cfa_offset 16
+; BE-NEXT: // kill: def $d0 killed $d0 def $q0
+; BE-NEXT: // kill: def $d1 killed $d1 def $q1
+; BE-NEXT: // kill: def $d2 killed $d2 def $q2
+; BE-NEXT: mov v0.d[1], v1.d[0]
+; BE-NEXT: xtn v1.2s, v2.2d
+; BE-NEXT: xtn v0.2s, v0.2d
+; BE-NEXT: stur b1, [x0, #2]
+; BE-NEXT: mov w8, v0.s[1]
+; BE-NEXT: mov v0.h[1], w8
+; BE-NEXT: mov w8, v1.s[1]
+; BE-NEXT: mov v0.h[2], v1.h[0]
+; BE-NEXT: mov v0.h[3], w8
+; BE-NEXT: xtn v0.8b, v0.8h
+; BE-NEXT: rev32 v0.16b, v0.16b
+; BE-NEXT: rev32 v0.4h, v0.4h
+; BE-NEXT: ushll v0.4s, v0.4h, #0
+; BE-NEXT: str h0, [x0]
+; BE-NEXT: add sp, sp, #16
+; BE-NEXT: ret
+entry:
+ %t = trunc <3 x i64> %x to <3 x i8>
+ store <3 x i8> %t, ptr %p, align 1
+ ret void
+}
More information about the llvm-commits
mailing list