Author: Joshua Rodriguez
Date: 2026-06-03T14:00:37+01:00
New Revision: 799af5d80d6335cd10de91506b6beb7c043278eb
URL: https://github.com/llvm/llvm-project/commit/799af5d80d6335cd10de91506b6beb7c043278eb
DIFF: https://github.com/llvm/llvm-project/commit/799af5d80d6335cd10de91506b6beb7c043278eb.diff
LOG: [AArch64][GlobalISel] Add handling for cls intrinsic (#200440)
Neon intrinsic neon.cls wasn't linked to the generic node G_CTLS.
Add in this link in Legalisation (LegalizeIntrinsic), to allow the intrinsic to properly lower.
Added:
Modified:
llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
llvm/test/CodeGen/AArch64/arm64-vcnt.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index 6092f63fcde72..78c2268aac986 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -2106,6 +2106,8 @@ bool AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
return LowerUnaryOp(TargetOpcode::G_FPTOUI_SAT);
case Intrinsic::aarch64_neon_fcvtzs:
return LowerUnaryOp(TargetOpcode::G_FPTOSI_SAT);
+ case Intrinsic::aarch64_neon_cls:
+ return LowerUnaryOp(TargetOpcode::G_CTLS);
case Intrinsic::vector_reverse:
// TODO: Add support for vector_reverse
diff --git a/llvm/test/CodeGen/AArch64/arm64-vcnt.ll b/llvm/test/CodeGen/AArch64/arm64-vcnt.ll
index f2113d45589b3..0bd34eb91079b 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vcnt.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vcnt.ll
@@ -1,48 +1,68 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
; RUN: llc < %s -mtriple=arm64-eabi -aarch64-neon-syntax=apple | FileCheck %s
+; RUN: llc < %s -mtriple=arm64-eabi -aarch64-neon-syntax=apple -global-isel | FileCheck %s
define <8 x i8> @cls_8b(ptr %A) nounwind {
-;CHECK-LABEL: cls_8b:
-;CHECK: cls.8b
+; CHECK-LABEL: cls_8b:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ldr d0, [x0]
+; CHECK-NEXT: cls.8b v0, v0
+; CHECK-NEXT: ret
%tmp1 = load <8 x i8>, ptr %A
%tmp3 = call <8 x i8> @llvm.aarch64.neon.cls.v8i8(<8 x i8> %tmp1)
ret <8 x i8> %tmp3
}
define <16 x i8> @cls_16b(ptr %A) nounwind {
-;CHECK-LABEL: cls_16b:
-;CHECK: cls.16b
+; CHECK-LABEL: cls_16b:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ldr q0, [x0]
+; CHECK-NEXT: cls.16b v0, v0
+; CHECK-NEXT: ret
%tmp1 = load <16 x i8>, ptr %A
%tmp3 = call <16 x i8> @llvm.aarch64.neon.cls.v16i8(<16 x i8> %tmp1)
ret <16 x i8> %tmp3
}
define <4 x i16> @cls_4h(ptr %A) nounwind {
-;CHECK-LABEL: cls_4h:
-;CHECK: cls.4h
+; CHECK-LABEL: cls_4h:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ldr d0, [x0]
+; CHECK-NEXT: cls.4h v0, v0
+; CHECK-NEXT: ret
%tmp1 = load <4 x i16>, ptr %A
%tmp3 = call <4 x i16> @llvm.aarch64.neon.cls.v4i16(<4 x i16> %tmp1)
ret <4 x i16> %tmp3
}
define <8 x i16> @cls_8h(ptr %A) nounwind {
-;CHECK-LABEL: cls_8h:
-;CHECK: cls.8h
+; CHECK-LABEL: cls_8h:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ldr q0, [x0]
+; CHECK-NEXT: cls.8h v0, v0
+; CHECK-NEXT: ret
%tmp1 = load <8 x i16>, ptr %A
%tmp3 = call <8 x i16> @llvm.aarch64.neon.cls.v8i16(<8 x i16> %tmp1)
ret <8 x i16> %tmp3
}
define <2 x i32> @cls_2s(ptr %A) nounwind {
-;CHECK-LABEL: cls_2s:
-;CHECK: cls.2s
+; CHECK-LABEL: cls_2s:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ldr d0, [x0]
+; CHECK-NEXT: cls.2s v0, v0
+; CHECK-NEXT: ret
%tmp1 = load <2 x i32>, ptr %A
%tmp3 = call <2 x i32> @llvm.aarch64.neon.cls.v2i32(<2 x i32> %tmp1)
ret <2 x i32> %tmp3
}
define <4 x i32> @cls_4s(ptr %A) nounwind {
-;CHECK-LABEL: cls_4s:
-;CHECK: cls.4s
+; CHECK-LABEL: cls_4s:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ldr q0, [x0]
+; CHECK-NEXT: cls.4s v0, v0
+; CHECK-NEXT: ret
%tmp1 = load <4 x i32>, ptr %A
%tmp3 = call <4 x i32> @llvm.aarch64.neon.cls.v4i32(<4 x i32> %tmp1)
ret <4 x i32> %tmp3