[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