[llvm] 71cbaac - [AArch64] Combine truncate(buildvector) -> buildvector (#223787)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 28 04:47:21 PDT 2026
Author: David Green
Date: 2026-09-28T11:47:14Z
New Revision: 71cbaace075d39f87063afa9d0da165ee04345b3
URL: https://github.com/llvm/llvm-project/commit/71cbaace075d39f87063afa9d0da165ee04345b3
DIFF: https://github.com/llvm/llvm-project/commit/71cbaace075d39f87063afa9d0da165ee04345b3.diff
LOG: [AArch64] Combine truncate(buildvector) -> buildvector (#223787)
If late in the pipeline we are left with truncate(buildvector), we can
generate the buildvector directly. This helps remove the xtn and can
lead to other simplification.
Added:
Modified:
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
llvm/test/CodeGen/AArch64/binopshuffles.ll
llvm/test/CodeGen/AArch64/fp-intrinsics-vector.ll
llvm/test/CodeGen/AArch64/neon-truncstore.ll
llvm/test/CodeGen/AArch64/store.ll
llvm/test/CodeGen/AArch64/sve-extract-vector-to-predicate-store.ll
llvm/test/CodeGen/AArch64/vec3-loads-ext-trunc-stores.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index e159aea0868d5..99be309f6bc9d 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -23999,6 +23999,12 @@ static SDValue performTruncateCombine(SDNode *N, SelectionDAG &DAG,
return DAG.getExtractVectorElt(DL, VT, Op, ExtractIndex * 2);
}
+ // truncate(buildvector) -> buildvector if we have it late in the pipeline. We
+ // do not truncate the operand types as the buildvector implicitly truncates.
+ if (!DCI.isBeforeLegalizeOps() && N0.getOpcode() == ISD::BUILD_VECTOR &&
+ N0.hasOneUse() && (VT == MVT::v8i8 || VT == MVT::v4i16))
+ return DAG.getBuildVector(VT, DL, N0->ops());
+
return SDValue();
}
diff --git a/llvm/test/CodeGen/AArch64/binopshuffles.ll b/llvm/test/CodeGen/AArch64/binopshuffles.ll
index 3ee9df3165c98..0f2fe1cabe2b6 100644
--- a/llvm/test/CodeGen/AArch64/binopshuffles.ll
+++ b/llvm/test/CodeGen/AArch64/binopshuffles.ll
@@ -173,7 +173,7 @@ define void @noncanonical(ptr %p0, ptr %p1, ptr %p2) {
; CHECK-LABEL: noncanonical:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: ldr d0, [x1]
-; CHECK-NEXT: xtn v0.8b, v0.8h
+; CHECK-NEXT: uzp1 v0.8b, v0.8b, v0.8b
; CHECK-NEXT: str s0, [x2]
; CHECK-NEXT: ret
entry:
diff --git a/llvm/test/CodeGen/AArch64/fp-intrinsics-vector.ll b/llvm/test/CodeGen/AArch64/fp-intrinsics-vector.ll
index 0b05e00a1b0db..8e63ee39839be 100644
--- a/llvm/test/CodeGen/AArch64/fp-intrinsics-vector.ll
+++ b/llvm/test/CodeGen/AArch64/fp-intrinsics-vector.ll
@@ -345,22 +345,22 @@ define <4 x i1> @fcmp_v4f32(<4 x float> %x, <4 x float> %y) #0 {
; CHECK-NEXT: mov s2, v1.s[1]
; CHECK-NEXT: mov s3, v0.s[1]
; CHECK-NEXT: fcmp s0, s1
+; CHECK-NEXT: mov s4, v0.s[2]
+; CHECK-NEXT: mov s0, v0.s[3]
; CHECK-NEXT: csetm w8, eq
; CHECK-NEXT: fcmp s3, s2
-; CHECK-NEXT: mov s2, v1.s[2]
-; CHECK-NEXT: mov s3, v0.s[2]
-; CHECK-NEXT: fmov s4, w8
+; CHECK-NEXT: mov s3, v1.s[2]
+; CHECK-NEXT: fmov s2, w8
; CHECK-NEXT: mov s1, v1.s[3]
-; CHECK-NEXT: mov s0, v0.s[3]
; CHECK-NEXT: csetm w8, eq
-; CHECK-NEXT: mov v4.s[1], w8
-; CHECK-NEXT: fcmp s3, s2
+; CHECK-NEXT: mov v2.h[1], w8
+; CHECK-NEXT: fcmp s4, s3
; CHECK-NEXT: csetm w8, eq
; CHECK-NEXT: fcmp s0, s1
-; CHECK-NEXT: mov v4.s[2], w8
+; CHECK-NEXT: mov v2.h[2], w8
; CHECK-NEXT: csetm w8, eq
-; CHECK-NEXT: mov v4.s[3], w8
-; CHECK-NEXT: xtn v0.4h, v4.4s
+; CHECK-NEXT: mov v2.h[3], w8
+; CHECK-NEXT: fmov d0, d2
; CHECK-NEXT: ret
entry:
%val = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f64(<4 x float> %x, <4 x float> %y, metadata !"oeq", metadata !"fpexcept.strict")
@@ -373,22 +373,22 @@ define <4 x i1> @fcmps_v4f32(<4 x float> %x, <4 x float> %y) #0 {
; CHECK-NEXT: mov s2, v1.s[1]
; CHECK-NEXT: mov s3, v0.s[1]
; CHECK-NEXT: fcmpe s0, s1
+; CHECK-NEXT: mov s4, v0.s[2]
+; CHECK-NEXT: mov s0, v0.s[3]
; CHECK-NEXT: csetm w8, eq
; CHECK-NEXT: fcmpe s3, s2
-; CHECK-NEXT: mov s2, v1.s[2]
-; CHECK-NEXT: mov s3, v0.s[2]
-; CHECK-NEXT: fmov s4, w8
+; CHECK-NEXT: mov s3, v1.s[2]
+; CHECK-NEXT: fmov s2, w8
; CHECK-NEXT: mov s1, v1.s[3]
-; CHECK-NEXT: mov s0, v0.s[3]
; CHECK-NEXT: csetm w8, eq
-; CHECK-NEXT: mov v4.s[1], w8
-; CHECK-NEXT: fcmpe s3, s2
+; CHECK-NEXT: mov v2.h[1], w8
+; CHECK-NEXT: fcmpe s4, s3
; CHECK-NEXT: csetm w8, eq
; CHECK-NEXT: fcmpe s0, s1
-; CHECK-NEXT: mov v4.s[2], w8
+; CHECK-NEXT: mov v2.h[2], w8
; CHECK-NEXT: csetm w8, eq
-; CHECK-NEXT: mov v4.s[3], w8
-; CHECK-NEXT: xtn v0.4h, v4.4s
+; CHECK-NEXT: mov v2.h[3], w8
+; CHECK-NEXT: fmov d0, d2
; CHECK-NEXT: ret
entry:
%val = call <4 x i1> @llvm.experimental.constrained.fcmps.v4f32(<4 x float> %x, <4 x float> %y, metadata !"oeq", metadata !"fpexcept.strict")
diff --git a/llvm/test/CodeGen/AArch64/neon-truncstore.ll b/llvm/test/CodeGen/AArch64/neon-truncstore.ll
index 9666cd705cbf6..88e1deff375c1 100644
--- a/llvm/test/CodeGen/AArch64/neon-truncstore.ll
+++ b/llvm/test/CodeGen/AArch64/neon-truncstore.ll
@@ -262,8 +262,6 @@ define void @extract_v4i8_v8i8(<8 x i8> %a, ptr %p) {
; CHECK-LABEL: extract_v4i8_v8i8:
; CHECK: // %bb.0:
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
-; CHECK-NEXT: zip1 v0.16b, v0.16b, v0.16b
-; CHECK-NEXT: xtn v0.8b, v0.8h
; CHECK-NEXT: str s0, [x0]
; CHECK-NEXT: ret
%c = shufflevector <8 x i8> %a, <8 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
diff --git a/llvm/test/CodeGen/AArch64/store.ll b/llvm/test/CodeGen/AArch64/store.ll
index 72f1cb5a0b22f..5daf8c2317ca0 100644
--- a/llvm/test/CodeGen/AArch64/store.ll
+++ b/llvm/test/CodeGen/AArch64/store.ll
@@ -231,9 +231,8 @@ define void @store_v3i8(<3 x i8> %a, ptr %ptr){
; CHECK-SD-NEXT: .cfi_def_cfa_offset 16
; CHECK-SD-NEXT: fmov s0, w0
; CHECK-SD-NEXT: strb w2, [x3, #2]
-; CHECK-SD-NEXT: mov v0.h[1], w1
-; CHECK-SD-NEXT: mov v0.h[2], w2
-; CHECK-SD-NEXT: xtn v0.8b, v0.8h
+; CHECK-SD-NEXT: mov v0.b[1], w1
+; CHECK-SD-NEXT: mov v0.b[2], w2
; CHECK-SD-NEXT: ushll v0.4s, v0.4h, #0
; CHECK-SD-NEXT: str h0, [x3]
; CHECK-SD-NEXT: add sp, sp, #16
diff --git a/llvm/test/CodeGen/AArch64/sve-extract-vector-to-predicate-store.ll b/llvm/test/CodeGen/AArch64/sve-extract-vector-to-predicate-store.ll
index a432e9590ec3b..0c7849ad40b28 100644
--- a/llvm/test/CodeGen/AArch64/sve-extract-vector-to-predicate-store.ll
+++ b/llvm/test/CodeGen/AArch64/sve-extract-vector-to-predicate-store.ll
@@ -51,12 +51,11 @@ define void @pred_store_neg1(<vscale x 16 x i1> %pred, ptr %addr) #0 {
; CHECK-NEXT: mov w8, v0.s[2]
; CHECK-NEXT: mov z2.s, z0.s[4]
; CHECK-NEXT: mov z1.s, z0.s[6]
-; CHECK-NEXT: mov v0.h[1], w8
+; CHECK-NEXT: mov v0.b[1], w8
; CHECK-NEXT: fmov w8, s2
-; CHECK-NEXT: mov v0.h[2], w8
+; CHECK-NEXT: mov v0.b[2], w8
; CHECK-NEXT: fmov w8, s1
-; CHECK-NEXT: mov v0.h[3], w8
-; CHECK-NEXT: xtn v0.8b, v0.8h
+; CHECK-NEXT: mov v0.b[3], w8
; CHECK-NEXT: str s0, [x0]
; CHECK-NEXT: addvl sp, sp, #1
; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload
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 538dbf94608c7..b58af24483b25 100644
--- a/llvm/test/CodeGen/AArch64/vec3-loads-ext-trunc-stores.ll
+++ b/llvm/test/CodeGen/AArch64/vec3-loads-ext-trunc-stores.ll
@@ -897,11 +897,10 @@ define void @store_trunc_v3i64_to_v3i8(ptr %p, <3 x i64> %x) {
; 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.b 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: mov.b v0[2], v1[0]
+; CHECK-NEXT: mov.b v0[3], w8
; CHECK-NEXT: ushll.4s v0, v0, #0
; CHECK-NEXT: str h0, [x0]
; CHECK-NEXT: add sp, sp, #16
@@ -919,11 +918,10 @@ define void @store_trunc_v3i64_to_v3i8(ptr %p, <3 x i64> %x) {
; 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 v0.b[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: mov v0.b[2], v1.b[0]
+; BE-NEXT: mov v0.b[3], w8
; BE-NEXT: rev32 v0.16b, v0.16b
; BE-NEXT: rev32 v0.4h, v0.4h
; BE-NEXT: ushll v0.4s, v0.4h, #0
More information about the llvm-commits
mailing list