[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