[llvm] [AArch64] Add support for custom MOVI and MVN (PR #148698)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 14 11:34:37 PDT 2025
https://github.com/aabhinavg1 created https://github.com/llvm/llvm-project/pull/148698
- Implemented custom pattern matching for MOVI and MVNI vector instructions.
- Added tests to verify MOVI.16b, MOVI.4s, MVNI.4s with shift and without shift.
- Ensured correct codegen for specific immediate constants using AArch64 ISel lowering.
Fixes #148634
>From 1259e7378e51e9c6f3d2af71a9270895c9a9a7ef Mon Sep 17 00:00:00 2001
From: aabhinavg1 <tiwariabhinavak at gmail.com>
Date: Mon, 14 Jul 2025 23:59:41 +0530
Subject: [PATCH] [AArch64] Add support for custom MOVI and MVN
- Implemented custom pattern matching for MOVI and MVNI vector instructions.
- Added tests to verify MOVI.16b, MOVI.4s, MVNI.4s with shift and without shift.
- Ensured correct codegen for specific immediate constants using AArch64 ISel lowering.
---
.../Target/AArch64/AArch64ISelLowering.cpp | 40 +++++++++++++++++--
llvm/test/CodeGen/AArch64/movi-custom.ll | 30 ++++++++++++++
2 files changed, 67 insertions(+), 3 deletions(-)
create mode 100644 llvm/test/CodeGen/AArch64/movi-custom.ll
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 55601e6327e98..43e5ed6c53f61 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -2599,6 +2599,36 @@ void AArch64TargetLowering::computeKnownBitsForTargetNode(
Known = KnownBits::makeConstant(
APInt(Known.getBitWidth(), Op->getConstantOperandVal(0)));
break;
+ }
+ case AArch64ISD::MOVIedit: {
+ if (Op.getNumOperands() < 2 || !isa<ConstantSDNode>(Op.getOperand(0)) ||
+ !isa<ConstantSDNode>(Op.getOperand(1))) {
+ break; // Or assert, or return
+ }
+ uint64_t Val = Op->getConstantOperandVal(0);
+ uint64_t Mask = Op->getConstantOperandVal(1);
+ Known = KnownBits::makeConstant(APInt(Known.getBitWidth(), Val | Mask));
+ break;
+ }
+ case AArch64ISD::MOVImsl: {
+ uint64_t Val = Op->getConstantOperandVal(0);
+ uint64_t Shift = Op->getConstantOperandVal(1);
+ Known = KnownBits::makeConstant(
+ APInt(Known.getBitWidth(), Val * (1ULL << Shift)));
+ break;
+ }
+ case AArch64ISD::MVNIshift: {
+ uint64_t Val = Op->getConstantOperandVal(0);
+ uint64_t Shift = Op->getConstantOperandVal(1);
+ Known = KnownBits::makeConstant(~APInt(Known.getBitWidth(), Val << Shift));
+ break;
+ }
+ case AArch64ISD::MVNImsl: {
+ uint64_t Val = Op->getConstantOperandVal(0);
+ uint64_t Shift = Op->getConstantOperandVal(1);
+ Known = KnownBits::makeConstant(
+ ~APInt(Known.getBitWidth(), Val * (1ULL << Shift)));
+ break;
}
case AArch64ISD::LOADgot:
case AArch64ISD::ADDlow: {
@@ -30285,13 +30315,17 @@ bool AArch64TargetLowering::SimplifyDemandedBitsForTargetNode(
}
bool AArch64TargetLowering::isTargetCanonicalConstantNode(SDValue Op) const {
- return Op.getOpcode() == AArch64ISD::DUP ||
- Op.getOpcode() == AArch64ISD::MOVI ||
- (Op.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
+ unsigned Opc = Op.getOpcode();
+ return Opc == AArch64ISD::DUP || Opc == AArch64ISD::MOVI ||
+ Opc == AArch64ISD::MOVIshift || Opc == AArch64ISD::MOVIedit ||
+ Opc == AArch64ISD::MOVImsl || Opc == AArch64ISD::MVNIshift ||
+ Opc == AArch64ISD::MVNImsl ||
+ (Opc == ISD::EXTRACT_SUBVECTOR &&
Op.getOperand(0).getOpcode() == AArch64ISD::DUP) ||
TargetLowering::isTargetCanonicalConstantNode(Op);
}
+
bool AArch64TargetLowering::isComplexDeinterleavingSupported() const {
return Subtarget->hasSVE() || Subtarget->hasSVE2() ||
Subtarget->hasComplxNum();
diff --git a/llvm/test/CodeGen/AArch64/movi-custom.ll b/llvm/test/CodeGen/AArch64/movi-custom.ll
new file mode 100644
index 0000000000000..14c8fd5c994d9
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/movi-custom.ll
@@ -0,0 +1,30 @@
+; RUN: llc -mtriple=aarch64-linux-gnu < %s -o - | FileCheck %s
+
+; Test 1: AArch64ISD::MOVIedit
+define <16 x i8> @test_movi_edit() {
+; CHECK-LABEL: test_movi_edit:
+; CHECK: movi v0.16b, #63
+ ret <16 x i8> <i8 63, i8 63, i8 63, i8 63, i8 63, i8 63, i8 63, i8 63,
+ i8 63, i8 63, i8 63, i8 63, i8 63, i8 63, i8 63, i8 63>
+}
+
+; Test 2: AArch64ISD::MOVImsl
+define <4 x i32> @test_movi_msl() {
+; CHECK-LABEL: test_movi_msl:
+; CHECK: movi v0.4s, #64
+ ret <4 x i32> <i32 64, i32 64, i32 64, i32 64>
+}
+
+; Test 3: AArch64ISD::MVNIshift
+define <4 x i32> @test_mvni_shift() {
+; CHECK-LABEL: test_mvni_shift:
+; CHECK: movi v0.2d, #0xffff00ffffff00ff
+ ret <4 x i32> <i32 -65281, i32 -65281, i32 -65281, i32 -65281>
+}
+
+; Test 4: AArch64ISD::MVNImsl
+define <4 x i32> @test_mvnimsl() {
+; CHECK-LABEL: test_mvnimsl:
+; CHECK: mvni v0.4s, #64
+ ret <4 x i32> <i32 -65, i32 -65, i32 -65, i32 -65>
+}
More information about the llvm-commits
mailing list