[llvm] 11438bc - [AArch64] Combine undef UZP and NVCAST away. (#204623)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 3 02:24:52 PDT 2026
Author: Gaƫtan Bossu
Date: 2026-07-03T10:24:47+01:00
New Revision: 11438bc8e31252be03e8a47773da3964ab2df215
URL: https://github.com/llvm/llvm-project/commit/11438bc8e31252be03e8a47773da3964ab2df215
DIFF: https://github.com/llvm/llvm-project/commit/11438bc8e31252be03e8a47773da3964ab2df215.diff
LOG: [AArch64] Combine undef UZP and NVCAST away. (#204623)
These are used to lower insert_subvec nodes quite early in SDAG. After
DAG combines run, it's possible that the inputs to these AArch64 nodes
become UNDEF.
Added:
Modified:
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
llvm/test/CodeGen/AArch64/sve-masked-gather-64b-unscaled.ll
llvm/test/CodeGen/AArch64/sve-masked-gather-legalize.ll
llvm/test/CodeGen/AArch64/sve-masked-gather.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index df8a29c175b47..d22d3ab16914b 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -25998,6 +25998,12 @@ static SDValue performUzpCombine(SDNode *N, SelectionDAG &DAG,
SDValue Op1 = N->getOperand(1);
EVT ResVT = N->getValueType(0);
+ // UZP is used to lower insert_subvector quite early. When later DAG combines
+ // run, it's possible to actually end up with an insert of UNDEF into UNDEF,
+ // i.e. UZP1 UNDEF, UNDEF.
+ if (Op0.isUndef() && Op1.isUndef())
+ return DAG.getUNDEF(ResVT);
+
// uzp(extract_lo(x), extract_hi(x)) -> extract_lo(uzp x, x)
if (Op0.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
Op1.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
@@ -29229,11 +29235,17 @@ static SDValue performDUPCombine(SDNode *N,
/// Get rid of unnecessary NVCASTs (that don't change the type).
static SDValue performNVCASTCombine(SDNode *N, SelectionDAG &DAG) {
- if (N->getValueType(0) == N->getOperand(0).getValueType())
- return N->getOperand(0);
- if (N->getOperand(0).getOpcode() == AArch64ISD::NVCAST)
- return DAG.getNode(AArch64ISD::NVCAST, SDLoc(N), N->getValueType(0),
- N->getOperand(0).getOperand(0));
+ EVT VT = N->getValueType(0);
+ SDValue Op = N->getOperand(0);
+
+ if (VT == Op.getValueType())
+ return Op;
+
+ if (Op.isUndef())
+ return DAG.getUNDEF(VT);
+
+ if (Op.getOpcode() == AArch64ISD::NVCAST)
+ return DAG.getNode(AArch64ISD::NVCAST, SDLoc(N), VT, Op.getOperand(0));
return SDValue();
}
diff --git a/llvm/test/CodeGen/AArch64/sve-masked-gather-64b-unscaled.ll b/llvm/test/CodeGen/AArch64/sve-masked-gather-64b-unscaled.ll
index 03c2194e91a2b..940a66c81ada6 100644
--- a/llvm/test/CodeGen/AArch64/sve-masked-gather-64b-unscaled.ll
+++ b/llvm/test/CodeGen/AArch64/sve-masked-gather-64b-unscaled.ll
@@ -134,10 +134,8 @@ define <vscale x 16 x i8> @masked_gather_nxv1i8(ptr %base, <vscale x 2 x i64> %w
; CHECK-NEXT: uzp1 p0.d, p0.d, p1.d
; CHECK-NEXT: ld1b { z0.d }, p0/z, [x0, z0.d]
; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
-; CHECK-NEXT: uzp1 z1.s, z0.s, z0.s
-; CHECK-NEXT: uzp1 z0.h, z0.h, z1.h
-; CHECK-NEXT: uzp1 z1.h, z1.h, z1.h
-; CHECK-NEXT: uzp1 z0.b, z0.b, z1.b
+; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
+; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b
; CHECK-NEXT: ret
%offsets = call <vscale x 1 x i64> @llvm.vector.extract.nxv1i64.nxv2i64(<vscale x 2 x i64> %wide.offsets, i64 0)
%ptrs = getelementptr i8, ptr %base, <vscale x 1 x i64> %offsets
@@ -153,8 +151,7 @@ define <vscale x 8 x i16> @masked_gather_nxv1i16(ptr %base, <vscale x 2 x i64> %
; CHECK-NEXT: uzp1 p0.d, p0.d, p1.d
; CHECK-NEXT: ld1h { z0.d }, p0/z, [x0, z0.d]
; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
-; CHECK-NEXT: uzp1 z1.s, z0.s, z0.s
-; CHECK-NEXT: uzp1 z0.h, z0.h, z1.h
+; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
; CHECK-NEXT: ret
%offsets = call <vscale x 1 x i64> @llvm.vector.extract.nxv1i64.nxv2i64(<vscale x 2 x i64> %wide.offsets, i64 0)
%ptrs = getelementptr i8, ptr %base, <vscale x 1 x i64> %offsets
diff --git a/llvm/test/CodeGen/AArch64/sve-masked-gather-legalize.ll b/llvm/test/CodeGen/AArch64/sve-masked-gather-legalize.ll
index d40aa5bc7f31f..606046b00ed59 100644
--- a/llvm/test/CodeGen/AArch64/sve-masked-gather-legalize.ll
+++ b/llvm/test/CodeGen/AArch64/sve-masked-gather-legalize.ll
@@ -210,8 +210,7 @@ define <vscale x 16 x i8> @masked_gather_nxv16i8_undef_hi_mask(ptr %base, <vscal
; CHECK-NEXT: sunpklo z0.s, z0.h
; CHECK-NEXT: ld1b { z0.s }, p0/z, [x0, z0.s, sxtw]
; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
-; CHECK-NEXT: uzp1 z1.h, z0.h, z0.h
-; CHECK-NEXT: uzp1 z0.b, z0.b, z1.b
+; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b
; CHECK-NEXT: ret
%ptrs = getelementptr i8, ptr %base, <vscale x 16 x i8> %indices
%mask.false.hi = call <vscale x 16 x i1> @llvm.vector.insert.nxv16i1.nxv4i1(<vscale x 16 x i1> splat (i1 false), <vscale x 4 x i1> %mask, i64 0)
diff --git a/llvm/test/CodeGen/AArch64/sve-masked-gather.ll b/llvm/test/CodeGen/AArch64/sve-masked-gather.ll
index 8ae74188ec939..2008a42aec6b8 100644
--- a/llvm/test/CodeGen/AArch64/sve-masked-gather.ll
+++ b/llvm/test/CodeGen/AArch64/sve-masked-gather.ll
@@ -103,10 +103,8 @@ define <vscale x 16 x i8> @masked_gather_nxv1i8(<vscale x 2 x ptr> %wide.ptrs, <
; CHECK-NEXT: uzp1 p0.d, p0.d, p1.d
; CHECK-NEXT: ld1b { z0.d }, p0/z, [z0.d]
; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
-; CHECK-NEXT: uzp1 z1.s, z0.s, z0.s
-; CHECK-NEXT: uzp1 z0.h, z0.h, z1.h
-; CHECK-NEXT: uzp1 z1.h, z1.h, z1.h
-; CHECK-NEXT: uzp1 z0.b, z0.b, z1.b
+; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
+; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b
; CHECK-NEXT: ret
%ptrs = call <vscale x 1 x ptr> @llvm.vector.extract.nxv1p0.nxv2p0(<vscale x 2 x ptr> %wide.ptrs, i64 0)
%r = call <vscale x 1 x i8> @llvm.masked.gather.nxv1i8(<vscale x 1 x ptr> align 1 %ptrs, <vscale x 1 x i1> %mask, <vscale x 1 x i8> poison)
@@ -121,8 +119,7 @@ define <vscale x 8 x i16> @masked_gather_nxv1i16(<vscale x 2 x ptr> %wide.ptrs,
; CHECK-NEXT: uzp1 p0.d, p0.d, p1.d
; CHECK-NEXT: ld1h { z0.d }, p0/z, [z0.d]
; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s
-; CHECK-NEXT: uzp1 z1.s, z0.s, z0.s
-; CHECK-NEXT: uzp1 z0.h, z0.h, z1.h
+; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h
; CHECK-NEXT: ret
%ptrs = call <vscale x 1 x ptr> @llvm.vector.extract.nxv1p0.nxv2p0(<vscale x 2 x ptr> %wide.ptrs, i64 0)
%r = call <vscale x 1 x i16> @llvm.masked.gather.nxv1i16(<vscale x 1 x ptr> align 2 %ptrs, <vscale x 1 x i1> %mask, <vscale x 1 x i16> poison)
More information about the llvm-commits
mailing list