[llvm] [AArch64][SVE] Add more MOVPRFX pseudos for SVE immediate instructions. (PR #192491)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 16 10:23:50 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64
Author: Ricardo Jesus (rj-jesus)
<details>
<summary>Changes</summary>
This patchs adds MOVPRFX pseudos for the following instructions:
* AND (immediate)
* ORR (immediate)
* EOR (immediate)
* MUL (immediate)
* SMAX (immediate)
* SMIN (immediate)
* UMAX (immediate)
* UMIN (immediate)
---
Patch is 204.19 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/192491.diff
19 Files Affected:
- (modified) llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp (+8)
- (modified) llvm/lib/Target/AArch64/AArch64InstrFormats.td (+2)
- (modified) llvm/lib/Target/AArch64/AArch64InstrInfo.h (+1)
- (modified) llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp (+1)
- (modified) llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td (+7-7)
- (modified) llvm/lib/Target/AArch64/AArch64SchedNeoverseV1.td (+1-1)
- (modified) llvm/lib/Target/AArch64/AArch64SchedOlympus.td (+4-4)
- (modified) llvm/lib/Target/AArch64/SVEInstrFormats.td (+41-24)
- (modified) llvm/test/CodeGen/AArch64/aarch64-smull.ll (+10-6)
- (modified) llvm/test/CodeGen/AArch64/clmul-scalable.ll (+1539-1502)
- (modified) llvm/test/CodeGen/AArch64/complex-deinterleaving-add-mull-scalable-contract.ll (+15-14)
- (modified) llvm/test/CodeGen/AArch64/llvm-ir-to-intrinsic.ll (+10-9)
- (modified) llvm/test/CodeGen/AArch64/sme-pstate-sm-changing-call-disable-coalescing.ll (+2-2)
- (modified) llvm/test/CodeGen/AArch64/sve-gather-scatter-dag-combine.ll (+6-4)
- (modified) llvm/test/CodeGen/AArch64/sve-ldst-sext.ll (+18-18)
- (modified) llvm/test/CodeGen/AArch64/sve-ldst-zext.ll (+13-13)
- (modified) llvm/test/CodeGen/AArch64/sve-masked-gather-legalize.ll (+4-3)
- (modified) llvm/test/CodeGen/AArch64/sve-sext-zext.ll (+12-12)
- (modified) llvm/test/CodeGen/AArch64/sve2-histcnt.ll (+2-2)
``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
index f3aea26b3bbad..86cfffd3f17a3 100644
--- a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
@@ -537,6 +537,9 @@ bool AArch64ExpandPseudoImpl::expand_DestructiveOp(
// ==> MOVPRFX Zd Zs; EXT_ZZI Zd, Zd, Zs, Imm
std::tie(DOPIdx, SrcIdx, Src2Idx) = std::make_tuple(1, 1, 2);
break;
+ case AArch64::DestructiveBinaryImmUnpred:
+ std::tie(DOPIdx, SrcIdx) = std::make_tuple(1, 2);
+ break;
case AArch64::DestructiveBinaryShImmUnpred:
std::tie(DOPIdx, SrcIdx, Src2Idx) = std::make_tuple(1, 2, 3);
break;
@@ -560,6 +563,7 @@ bool AArch64ExpandPseudoImpl::expand_DestructiveOp(
break;
case AArch64::DestructiveUnaryPassthru:
case AArch64::DestructiveBinaryImm:
+ case AArch64::DestructiveBinaryImmUnpred:
case AArch64::DestructiveBinaryShImmUnpred:
case AArch64::Destructive2xRegImmUnpred:
DOPRegIsUnique = true;
@@ -688,6 +692,10 @@ bool AArch64ExpandPseudoImpl::expand_DestructiveOp(
.add(MI.getOperand(SrcIdx))
.add(MI.getOperand(Src2Idx));
break;
+ case AArch64::DestructiveBinaryImmUnpred:
+ DOP.addReg(MI.getOperand(DOPIdx).getReg(), DOPRegState)
+ .add(MI.getOperand(SrcIdx));
+ break;
case AArch64::DestructiveBinaryShImmUnpred:
case AArch64::Destructive2xRegImmUnpred:
DOP.addReg(MI.getOperand(DOPIdx).getReg(), DOPRegState)
diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index 406ac2fa62df2..a1ad3196aae83 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -60,6 +60,8 @@ def DestructiveUnaryPassthru : DestructiveInstTypeEnum<10>;
// from the governing predicate.
def DestructivePredicate : DestructiveInstTypeEnum<11>;
+def DestructiveBinaryImmUnpred : DestructiveInstTypeEnum<12>;
+
class FalseLanesEnum<bits<2> val> {
bits<2> Value = val;
}
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.h b/llvm/lib/Target/AArch64/AArch64InstrInfo.h
index 52bd8e3f9580c..60a8182fa163b 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.h
@@ -878,6 +878,7 @@ enum DestructiveInstType {
Destructive2xRegImmUnpred = TSFLAG_DESTRUCTIVE_INST_TYPE(0x9),
DestructiveUnaryPassthru = TSFLAG_DESTRUCTIVE_INST_TYPE(0xa),
DestructivePredicate = TSFLAG_DESTRUCTIVE_INST_TYPE(0xb),
+ DestructiveBinaryImmUnpred = TSFLAG_DESTRUCTIVE_INST_TYPE(0xc),
};
enum FalseLaneType {
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
index 51ef14f4ee1fa..8a0ce28852b31 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
@@ -1246,6 +1246,7 @@ bool AArch64RegisterInfo::getRegAllocationHints(
case AArch64::DestructiveUnaryPassthru:
AddHintIfSuitable(R, Def.getOperand(3));
break;
+ case AArch64::DestructiveBinaryImmUnpred:
case AArch64::DestructiveBinaryShImmUnpred:
AddHintIfSuitable(R, Def.getOperand(1));
break;
diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index 436f50fe451be..5eb005691fac7 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -4588,9 +4588,9 @@ class PromoteNEONToSVEImmWithShift
let Predicates = [HasSVE_or_SME] in {
foreach VT = [v2i64, v4i32, v8i16, v16i8] in {
// Logical operations
- def : PromoteNEONToSVEImm<and, VT, NEONSplatOfSVELogicalImmPat, AND_ZI, i64>;
- def : PromoteNEONToSVEImm<xor, VT, NEONSplatOfSVELogicalImmPat, EOR_ZI, i64>;
- def : PromoteNEONToSVEImm< or, VT, NEONSplatOfSVELogicalImmPat, ORR_ZI, i64>;
+ def : PromoteNEONToSVEImm<and, VT, NEONSplatOfSVELogicalImmPat, AND_ZI_PSEUDO, i64>;
+ def : PromoteNEONToSVEImm<xor, VT, NEONSplatOfSVELogicalImmPat, EOR_ZI_PSEUDO, i64>;
+ def : PromoteNEONToSVEImm< or, VT, NEONSplatOfSVELogicalImmPat, ORR_ZI_PSEUDO, i64>;
}
// Arith operations: ADD
@@ -4606,10 +4606,10 @@ let Predicates = [HasSVE_or_SME] in {
def : PromoteNEONToSVEImmWithShift<sub, v16i8, NEONSplatOfSVEAddSubImm, SUB_ZI_B_PSEUDO>;
// Arith operations: MUL
- def : PromoteNEONToSVEImm<mul, v2i64, NEONSplatOfSVEAddSubImm, MUL_ZI_D, i32>;
- def : PromoteNEONToSVEImm<mul, v4i32, NEONSplatOfSVEArithSImm, MUL_ZI_S, i32>;
- def : PromoteNEONToSVEImm<mul, v8i16, NEONSplatOfSVEArithSImm, MUL_ZI_H, i32>;
- def : PromoteNEONToSVEImm<mul, v16i8, NEONSplatOfSVEArithSImm, MUL_ZI_B, i32>;
+ def : PromoteNEONToSVEImm<mul, v2i64, NEONSplatOfSVEAddSubImm, MUL_ZI_D_PSEUDO, i32>;
+ def : PromoteNEONToSVEImm<mul, v4i32, NEONSplatOfSVEArithSImm, MUL_ZI_S_PSEUDO, i32>;
+ def : PromoteNEONToSVEImm<mul, v8i16, NEONSplatOfSVEArithSImm, MUL_ZI_H_PSEUDO, i32>;
+ def : PromoteNEONToSVEImm<mul, v16i8, NEONSplatOfSVEArithSImm, MUL_ZI_B_PSEUDO, i32>;
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AArch64SchedNeoverseV1.td b/llvm/lib/Target/AArch64/AArch64SchedNeoverseV1.td
index d333dfcc50d33..6c40304e7cd6b 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedNeoverseV1.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedNeoverseV1.td
@@ -1506,7 +1506,7 @@ def : InstRW<[V1Write_2c_1V01],
"^[SU](MAX|MIN)_Z(I|P[mZ]Z)_[BHSD]",
"^[SU]Q(ADD|SUB)_Z(I|ZZ)_[BHSD]",
"^SUBR_Z(I|P[mZ]Z)_[BHSD]",
- "^(AND|EOR|ORR)_ZI$",
+ "^(AND|EOR|ORR)_ZI",
"^(AND|BIC|EOR|EOR(BT|TB)?|ORR)_ZP?ZZ",
"^EOR(BT|TB)_ZZZ_[BHSD]$",
"^(AND|BIC|EOR|NOT|ORR)_ZPmZ_[BHSD]")>;
diff --git a/llvm/lib/Target/AArch64/AArch64SchedOlympus.td b/llvm/lib/Target/AArch64/AArch64SchedOlympus.td
index 7798096c10dc2..9d843a9490618 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedOlympus.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedOlympus.td
@@ -2385,7 +2385,7 @@ def : InstRW<[OlympusWrite_2c_1V], (instregex "^ADR_LSL_ZZZ_[SD]_[0123]",
// AND (vectors, predicated)
def : InstRW<[OlympusWrite_2c_1V], (instregex "^AND_ZP[mZ]Z_[BHSD]")>;
// AND (immediate)
-def : InstRW<[OlympusWrite_2c_1V], (instrs AND_ZI)>;
+def : InstRW<[OlympusWrite_2c_1V], (instregex "^AND_ZI")>;
// AND (vectors, unpredicated)
def : InstRW<[OlympusWrite_2c_1V], (instrs AND_ZZZ)>;
// ASR (immediate, predicated)
@@ -2435,7 +2435,7 @@ def : InstRW<[OlympusWrite_2c_1V], (instrs DUPM_ZI)>;
// EOR (vectors, predicated)
def : InstRW<[OlympusWrite_2c_1V], (instregex "^EOR_ZP[mZ]Z_[BHSD]")>;
// EOR (immediate)
-def : InstRW<[OlympusWrite_2c_1V], (instrs EOR_ZI)>;
+def : InstRW<[OlympusWrite_2c_1V], (instregex "^EOR_ZI")>;
// EOR (vectors, unpredicated)
def : InstRW<[OlympusWrite_2c_1V], (instrs EOR_ZZZ)>;
// EORBT
@@ -2494,7 +2494,7 @@ def : InstRW<[OlympusWrite_2c_1V], (instregex "^NOT_ZPmZ_[BHSD]")>;
// ORR (vectors, predicated)
def : InstRW<[OlympusWrite_2c_1V], (instregex "^ORR_ZP[mZ]Z_[BHSD]")>;
// ORR (immediate)
-def : InstRW<[OlympusWrite_2c_1V], (instrs ORR_ZI)>;
+def : InstRW<[OlympusWrite_2c_1V], (instregex "^ORR_ZI")>;
// ORR (vectors, unpredicated)
def : InstRW<[OlympusWrite_2c_1V], (instrs ORR_ZZZ)>;
// PMUL
@@ -2860,7 +2860,7 @@ def : InstRW<[OlympusWrite_5c_1V0123_2], (instrs SQRDMULH_ZZZ_D)>;
// UMULH (unpredicated)
def : InstRW<[OlympusWrite_5c_1V0123_2], (instrs UMULH_ZZZ_D)>;
// MUL (immediate)
-def : InstRW<[OlympusWrite_5c_1V0123_2], (instrs MUL_ZI_D)>;
+def : InstRW<[OlympusWrite_5c_1V0123_2], (instregex "^MUL_ZI_D")>;
// SQDMULH (indexed)
def : InstRW<[OlympusWrite_5c_1V0123_2], (instrs SQDMULH_ZZZI_D)>;
// SQRDMULH (indexed)
diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td
index 72434fa86e04c..f05de6ed9840b 100644
--- a/llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -2074,7 +2074,7 @@ multiclass sve_int_pred_log_v2<bits<4> opc, string asm, SDPatternOperator op,
class sve_int_log_imm<bits<2> opc, string asm>
: I<(outs ZPR64:$Zdn), (ins ZPR64:$_Zdn, logical_imm64:$imms13),
asm, "\t$Zdn, $_Zdn, $imms13",
- "", []>, Sched<[]> {
+ "", []>, SVEPseudo2Instr<NAME, 1>, Sched<[]> {
bits<5> Zdn;
bits<13> imms13;
let Inst{31-24} = 0b00000101;
@@ -2085,7 +2085,7 @@ class sve_int_log_imm<bits<2> opc, string asm>
let Constraints = "$Zdn = $_Zdn";
let DecoderMethod = "DecodeSVELogicalImmInstruction";
- let DestructiveInstType = DestructiveOther;
+ let DestructiveInstType = DestructiveBinaryImmUnpred;
let ElementSize = ElementSizeNone;
let hasSideEffects = 0;
}
@@ -2093,10 +2093,12 @@ class sve_int_log_imm<bits<2> opc, string asm>
multiclass sve_int_log_imm<bits<2> opc, string asm, string alias, SDPatternOperator op> {
def NAME : sve_int_log_imm<opc, asm>;
- def : SVE_1_Op_Imm_Log_Pat<nxv16i8, op, ZPR8, i32, SVELogicalImm8Pat, !cast<Instruction>(NAME)>;
- def : SVE_1_Op_Imm_Log_Pat<nxv8i16, op, ZPR16, i32, SVELogicalImm16Pat, !cast<Instruction>(NAME)>;
- def : SVE_1_Op_Imm_Log_Pat<nxv4i32, op, ZPR32, i32, SVELogicalImm32Pat, !cast<Instruction>(NAME)>;
- def : SVE_1_Op_Imm_Log_Pat<nxv2i64, op, ZPR64, i64, SVELogicalImm64Pat, !cast<Instruction>(NAME)>;
+ def _PSEUDO : UnpredTwoOpImmPseudo<NAME, ZPR64, logical_imm64>;
+
+ def : SVE_1_Op_Imm_Log_Pat<nxv16i8, op, ZPR8, i32, SVELogicalImm8Pat, !cast<Pseudo>(NAME # _PSEUDO)>;
+ def : SVE_1_Op_Imm_Log_Pat<nxv8i16, op, ZPR16, i32, SVELogicalImm16Pat, !cast<Pseudo>(NAME # _PSEUDO)>;
+ def : SVE_1_Op_Imm_Log_Pat<nxv4i32, op, ZPR32, i32, SVELogicalImm32Pat, !cast<Pseudo>(NAME # _PSEUDO)>;
+ def : SVE_1_Op_Imm_Log_Pat<nxv2i64, op, ZPR64, i64, SVELogicalImm64Pat, !cast<Pseudo>(NAME # _PSEUDO)>;
def : InstAlias<asm # "\t$Zdn, $Zdn, $imm",
(!cast<Instruction>(NAME) ZPR8:$Zdn, sve_logical_imm8:$imm), 4>;
@@ -2116,10 +2118,10 @@ multiclass sve_int_log_imm<bits<2> opc, string asm, string alias, SDPatternOpera
}
multiclass sve_int_log_imm_bic<SDPatternOperator op> {
- def : SVE_1_Op_Imm_Log_Pat<nxv16i8, op, ZPR8, i32, SVELogicalImm8NotPat, !cast<Instruction>("AND_ZI")>;
- def : SVE_1_Op_Imm_Log_Pat<nxv8i16, op, ZPR16, i32, SVELogicalImm16NotPat, !cast<Instruction>("AND_ZI")>;
- def : SVE_1_Op_Imm_Log_Pat<nxv4i32, op, ZPR32, i32, SVELogicalImm32NotPat, !cast<Instruction>("AND_ZI")>;
- def : SVE_1_Op_Imm_Log_Pat<nxv2i64, op, ZPR64, i64, SVELogicalImm64NotPat, !cast<Instruction>("AND_ZI")>;
+ def : SVE_1_Op_Imm_Log_Pat<nxv16i8, op, ZPR8, i32, SVELogicalImm8NotPat, !cast<Pseudo>("AND_ZI_PSEUDO")>;
+ def : SVE_1_Op_Imm_Log_Pat<nxv8i16, op, ZPR16, i32, SVELogicalImm16NotPat, !cast<Pseudo>("AND_ZI_PSEUDO")>;
+ def : SVE_1_Op_Imm_Log_Pat<nxv4i32, op, ZPR32, i32, SVELogicalImm32NotPat, !cast<Pseudo>("AND_ZI_PSEUDO")>;
+ def : SVE_1_Op_Imm_Log_Pat<nxv2i64, op, ZPR64, i64, SVELogicalImm64NotPat, !cast<Pseudo>("AND_ZI_PSEUDO")>;
}
class sve_int_dup_mask_imm<string asm>
@@ -5354,7 +5356,7 @@ class sve_int_arith_imm<bits<2> sz8_64, bits<6> opc, string asm,
: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, immtype:$imm),
asm, "\t$Zdn, $_Zdn, $imm",
"",
- []>, Sched<[]> {
+ []>, SVEPseudo2Instr<NAME, 1>, Sched<[]> {
bits<5> Zdn;
bits<8> imm;
let Inst{31-24} = 0b00100101;
@@ -5365,7 +5367,7 @@ class sve_int_arith_imm<bits<2> sz8_64, bits<6> opc, string asm,
let Inst{4-0} = Zdn;
let Constraints = "$Zdn = $_Zdn";
- let DestructiveInstType = DestructiveOther;
+ let DestructiveInstType = DestructiveBinaryImmUnpred;
let ElementSize = ElementSizeNone;
let hasSideEffects = 0;
}
@@ -5376,10 +5378,15 @@ multiclass sve_int_arith_imm1<bits<2> opc, string asm, SDPatternOperator op> {
def _S : sve_int_arith_imm<0b10, { 0b1010, opc }, asm, ZPR32, simm8_32b>;
def _D : sve_int_arith_imm<0b11, { 0b1010, opc }, asm, ZPR64, simm8_32b>;
- def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _B)>;
- def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _H)>;
- def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _S)>;
- def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithSImmPat64, !cast<Instruction>(NAME # _D)>;
+ def _B_PSEUDO : UnpredTwoOpImmPseudo<NAME # _B, ZPR8, simm8_32b>;
+ def _H_PSEUDO : UnpredTwoOpImmPseudo<NAME # _H, ZPR16, simm8_32b>;
+ def _S_PSEUDO : UnpredTwoOpImmPseudo<NAME # _S, ZPR32, simm8_32b>;
+ def _D_PSEUDO : UnpredTwoOpImmPseudo<NAME # _D, ZPR64, simm8_32b>;
+
+ def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithSImmPat32, !cast<Pseudo>(NAME # _B_PSEUDO)>;
+ def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithSImmPat32, !cast<Pseudo>(NAME # _H_PSEUDO)>;
+ def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithSImmPat32, !cast<Pseudo>(NAME # _S_PSEUDO)>;
+ def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithSImmPat64, !cast<Pseudo>(NAME # _D_PSEUDO)>;
}
multiclass sve_int_arith_imm1_unsigned<bits<2> opc, string asm, SDPatternOperator op> {
@@ -5388,10 +5395,15 @@ multiclass sve_int_arith_imm1_unsigned<bits<2> opc, string asm, SDPatternOperato
def _S : sve_int_arith_imm<0b10, { 0b1010, opc }, asm, ZPR32, imm0_255>;
def _D : sve_int_arith_imm<0b11, { 0b1010, opc }, asm, ZPR64, imm0_255>;
- def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithUImm8Pat, !cast<Instruction>(NAME # _B)>;
- def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithUImm16Pat, !cast<Instruction>(NAME # _H)>;
- def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithUImm32Pat, !cast<Instruction>(NAME # _S)>;
- def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithUImm64Pat, !cast<Instruction>(NAME # _D)>;
+ def _B_PSEUDO : UnpredTwoOpImmPseudo<NAME # _B, ZPR8, imm0_255>;
+ def _H_PSEUDO : UnpredTwoOpImmPseudo<NAME # _H, ZPR16, imm0_255>;
+ def _S_PSEUDO : UnpredTwoOpImmPseudo<NAME # _S, ZPR32, imm0_255>;
+ def _D_PSEUDO : UnpredTwoOpImmPseudo<NAME # _D, ZPR64, imm0_255>;
+
+ def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithUImm8Pat, !cast<Pseudo>(NAME # _B_PSEUDO)>;
+ def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithUImm16Pat, !cast<Pseudo>(NAME # _H_PSEUDO)>;
+ def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithUImm32Pat, !cast<Pseudo>(NAME # _S_PSEUDO)>;
+ def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithUImm64Pat, !cast<Pseudo>(NAME # _D_PSEUDO)>;
}
multiclass sve_int_arith_imm2<string asm, SDPatternOperator op> {
@@ -5400,10 +5412,15 @@ multiclass sve_int_arith_imm2<string asm, SDPatternOperator op> {
def _S : sve_int_arith_imm<0b10, 0b110000, asm, ZPR32, simm8_32b>;
def _D : sve_int_arith_imm<0b11, 0b110000, asm, ZPR64, simm8_32b>;
- def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _B)>;
- def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _H)>;
- def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _S)>;
- def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithSImmPat64, !cast<Instruction>(NAME # _D)>;
+ def _B_PSEUDO : UnpredTwoOpImmPseudo<NAME # _B, ZPR8, simm8_32b>;
+ def _H_PSEUDO : UnpredTwoOpImmPseudo<NAME # _H, ZPR16, simm8_32b>;
+ def _S_PSEUDO : UnpredTwoOpImmPseudo<NAME # _S, ZPR32, simm8_32b>;
+ def _D_PSEUDO : UnpredTwoOpImmPseudo<NAME # _D, ZPR64, simm8_32b>;
+
+ def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _B_PSEUDO)>;
+ def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _H_PSEUDO)>;
+ def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _S_PSEUDO)>;
+ def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithSImmPat64, !cast<Instruction>(NAME # _D_PSEUDO)>;
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/test/CodeGen/AArch64/aarch64-smull.ll b/llvm/test/CodeGen/AArch64/aarch64-smull.ll
index ca7f40d560afd..5896b408be49c 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-smull.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-smull.ll
@@ -1458,11 +1458,13 @@ define <8 x i32> @amull2_i16(<8 x i16> %arg1, <8 x i16> %arg2) {
; CHECK-SVE-LABEL: amull2_i16:
; CHECK-SVE: // %bb.0:
; CHECK-SVE-NEXT: smull v2.4s, v0.4h, v1.4h
-; CHECK-SVE-NEXT: smull2 v1.4s, v0.8h, v1.8h
-; CHECK-SVE-NEXT: and z2.s, z2.s, #0xffff
+; CHECK-SVE-NEXT: smull2 v0.4s, v0.8h, v1.8h
+; CHECK-SVE-NEXT: movprfx z1, z0
; CHECK-SVE-NEXT: and z1.s, z1.s, #0xffff
+; CHECK-SVE-NEXT: movprfx z0, z2
+; CHECK-SVE-NEXT: and z0.s, z0.s, #0xffff
+; CHECK-SVE-NEXT: // kill: def $q0 killed $q0 killed $z0
; CHECK-SVE-NEXT: // kill: def $q1 killed $q1 killed $z1
-; CHECK-SVE-NEXT: mov v0.16b, v2.16b
; CHECK-SVE-NEXT: ret
;
; CHECK-GI-LABEL: amull2_i16:
@@ -1493,11 +1495,13 @@ define <4 x i64> @amull2_i32(<4 x i32> %arg1, <4 x i32> %arg2) {
; CHECK-SVE-LABEL: amull2_i32:
; CHECK-SVE: // %bb.0:
; CHECK-SVE-NEXT: smull v2.2d, v0.2s, v1.2s
-; CHECK-SVE-NEXT: smull2 v1.2d, v0.4s, v1.4s
-; CHECK-SVE-NEXT: and z2.d, z2.d, #0xffffffff
+; CHECK-SVE-NEXT: smull2 v0.2d, v0.4s, v1.4s
+; CHECK-SVE-NEXT: movprfx z1, z0
; CHECK-SVE-NEXT: and z1.d, z1.d, #0xffffffff
+; CHECK-SVE-NEXT: movprfx z0, z2
+; CHECK-SVE-NEXT: and z0.d, z0.d, #0xffffffff
+; CHECK-SVE-NEXT: // kill: def $q0 killed $q0 killed $z0
; CHECK-SVE-NEXT: // kill: def $q1 killed $q1 killed $z1
-; CHECK-SVE-NEXT: mov v0.16b, v2.16b
; CHECK-SVE-NEXT: ret
;
; CHECK-GI-LABEL: amull2_i32:
diff --git a/llvm/test/CodeGen/AArch64/clmul-scalable.ll b/llvm/test/CodeGen/AArch64/clmul-scalable.ll
index d2c7f98854d91..ef903902b9e65 100644
--- a/llvm/test/CodeGen/AArch64/clmul-scalable.ll
+++ b/llvm/test/CodeGen/AArch64/clmul-scalable.ll
@@ -9,22 +9,22 @@
define <vscale x 16 x i8> @clmul_nxv16i8(<vscale x 16 x i8> %x, <vscale x 16 x i8> %y) {
; CHECK-SVE-LABEL: clmul_nxv16i8:
; CHECK-SVE: // %bb.0:
-; CHECK-SVE-NEXT: mov z2.d, z1.d
-; CHECK-SVE-NEXT: mov z3.d, z1.d
-; CHECK-SVE-NEXT: mov z4.d, z1.d
-; CHECK-SVE-NEXT: mov z5.d, z1.d
-; CHECK-SVE-NEXT: mov z6.d, z1.d
-; CHECK-SVE-NEXT: mov z7.d, z1.d
-; CHECK-SVE-NEXT: mov z24.d, z1.d
-; CHECK-SVE-NEXT: ptrue p0.b
-; CHECK-SVE-NEXT: and z1.b, z1.b, #0x80
+; CHECK-SVE-NEXT: movprfx z2, z1
; CHECK-SVE-NEXT: and z2.b, z2.b, #0x2
+; CHECK-SVE-NEXT: movprfx z3, z1
; CHECK-SVE-NEXT: and z3.b, z3.b, #0x1
+; CHECK-SVE-NEXT: movprfx z4, z1
; CHECK-SVE-NEXT: and z4.b, z4.b, #0x4
+; CHECK-SVE-NEXT: movprfx z5, z1
; CHECK-SVE-NEXT: and z5.b, z5.b, #0x8
+; CHECK-SVE-NEXT: movprfx z6, z1
; CHECK-SVE-NEXT: and z6.b, z6.b, #0x10
+; CHECK-SVE-NEXT: movprfx z7, z1
; CHECK-SVE-NEXT: and z7.b, z7.b, #0x20
+; CHECK-SVE-NEXT: ptrue p0.b
+; CHECK-SVE-NEXT: movprfx z24, z1
; CHECK-SVE-NEXT: and z24.b, z24.b, #0x40
+; CHECK-SVE-NEXT: and z1.b, z1.b, #0x80
; CHECK-SVE-NEXT: mul z2.b, p0/m, z2.b, z0.b
; CHECK-SVE-NEXT: mul z3.b, p0/m, z3.b, z0.b
; CHECK-SVE-NEXT: mul z4.b, p0/m, z4.b, z0.b
@@ -44,22 +44,22 @@ define <vscale x 16 x i8> @clmul_nxv16i8(<vscale x 16 x i8> %x, <vscale x 16 x i
;
; CHECK-SVE-AES-LABEL: clmul_nxv16i8:
; CHECK-SVE-AES: // %bb.0:
-; CHECK-SVE-AES-NEXT: mov z2.d, z1.d
-; CHECK-SVE-AES-NEXT: mov z3.d, z1.d
-; CHECK-SVE-AES-NEXT: mov z4.d, z1.d
-; CHECK-SVE-AES-NEXT: mov z5.d, z1.d
-; CHECK-SV...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/192491
More information about the llvm-commits
mailing list