From c0c0609474e141bbd44c092ebd5f6387501643bd Mon Sep 17 00:00:00 2001 From: Samuel Tebbs Date: Tue, 13 Feb 2024 11:23:34 +0000 Subject: [PATCH 01/19] [AArch64] Remove copy in SVE/SME predicate spill 7dc20ab introduced an extra COPY when spilling a PNR register, which can't be elided as the input (PNR predicate) and output (PPR predicate) register classes differ. This patch emits a new ConvertPNRtoPPR pseudo instruction instead. When this is expanded, it gets erased if the PNR is a subregister of the PPR, since the conversion is implicit, otherwise it is lowered to an ORR. --- .../AArch64/AArch64ExpandPseudoInsts.cpp | 17 +++++++++++ llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 6 ++-- .../lib/Target/AArch64/AArch64SVEInstrInfo.td | 2 ++ .../spillfill-sve-different-predicate.mir | 30 +++++++++++++++++++ llvm/test/CodeGen/AArch64/spillfill-sve.mir | 3 +- 5 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/spillfill-sve-different-predicate.mir diff --git a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp index b2c52b443753d..fe51a03bccc33 100644 --- a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp +++ b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp @@ -1112,6 +1112,23 @@ bool AArch64ExpandPseudo::expandMI(MachineBasicBlock &MBB, default: break; + case AArch64::ConvertPNRtoPPR: { + auto TRI = MBB.getParent()->getSubtarget().getRegisterInfo(); + MachineOperand DstMO = MI.getOperand(0); + MachineOperand SrcMO = MI.getOperand(1); + unsigned SrcReg = SrcMO.getReg(); + if (!TRI->isSubRegister(DstMO.getReg(), SrcReg)) { + unsigned SrcSuperReg = TRI->getMatchingSuperReg(SrcReg, AArch64::psub, + &AArch64::PPRRegClass); + BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ORR_PPzPP)) + .add(DstMO) + .addReg(SrcSuperReg) + .addReg(SrcSuperReg) + .addReg(SrcSuperReg); + } + MI.eraseFromParent(); + return true; + } case AArch64::BSPv8i8: case AArch64::BSPv16i8: { Register DstReg = MI.getOperand(0).getReg(); diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 17e0e36ee6821..622d553bdb966 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -4805,6 +4805,7 @@ void AArch64InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, bool Offset = true; MCRegister PNRReg = MCRegister::NoRegister; unsigned StackID = TargetStackID::Default; + const TargetInstrInfo *TII = MBB.getParent()->getSubtarget().getInstrInfo(); switch (TRI->getSpillSize(*RC)) { case 1: if (AArch64::FPR8RegClass.hasSubClassEq(RC)) @@ -4823,8 +4824,9 @@ void AArch64InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, "Unexpected register store without SVE2p1 or SME2"); if (SrcReg.isVirtual()) { auto NewSrcReg = - MF.getRegInfo().createVirtualRegister(&AArch64::PPRRegClass); - BuildMI(MBB, MBBI, DebugLoc(), get(TargetOpcode::COPY), NewSrcReg) + MF.getRegInfo().createVirtualRegister(&AArch64::PPR_p8to15RegClass); + BuildMI(MBB, MBBI, DebugLoc(), TII->get(AArch64::ConvertPNRtoPPR), + NewSrcReg) .addReg(SrcReg); SrcReg = NewSrcReg; } else diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index 7c98f934a1317..c2d42c7703a01 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -2313,6 +2313,8 @@ let Predicates = [HasBF16, HasSVEorSME] in { defm BFCVTNT_ZPmZ : sve_bfloat_convert<0b0, "bfcvtnt", int_aarch64_sve_fcvtnt_bf16f32>; } // End HasBF16, HasSVEorSME +def ConvertPNRtoPPR : Pseudo<(outs PPRAny:$Pd), (ins PNRAny:$Pm), []>, Sched<[]>; + let Predicates = [HasSVEorSME] in { // InstAliases def : InstAlias<"mov $Zd, $Zn", diff --git a/llvm/test/CodeGen/AArch64/spillfill-sve-different-predicate.mir b/llvm/test/CodeGen/AArch64/spillfill-sve-different-predicate.mir new file mode 100644 index 0000000000000..abbc1d615b66f --- /dev/null +++ b/llvm/test/CodeGen/AArch64/spillfill-sve-different-predicate.mir @@ -0,0 +1,30 @@ +# RUN: llc -mtriple=aarch64-linux-gnu -start-after=virtregrewriter -stop-after=aarch64-expand-pseudo -mattr=+sme2 -verify-machineinstrs -o - %s \ +# RUN: | FileCheck %s + +--- | + target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" + target triple = "aarch64-unknown-linux-gnu" + + define void @test_convert_different_reg() #0 { entry: unreachable } + + attributes #0 = { "target-features"="+sme2" } + +--- +name: test_convert_different_reg +tracksRegLiveness: true +body: | + bb.0.entry: + ; CHECK-LABEL: name: test_convert_different_reg + ; CHECK: renamable $pn8 = WHILEGE_CXX_B undef $x0, undef $x0, 0, implicit-def dead $nzcv + ; CHECK-NEXT: renamable $p9 = ORR_PPzPP $p8, $p8, $p8 + ; CHECK-NEXT: STR_PXI killed renamable $p9, $sp, 7 + ; CHECK-NEXT: renamable $p0 = LDR_PXI $sp, 7 + early-clobber $sp = frame-setup STRXpre killed $fp, $sp, -16 + frame-setup CFI_INSTRUCTION escape 0x0f, 0x0c, 0x8f, 0x00, 0x11, 0x10, 0x22, 0x11, 0x08, 0x92, 0x2e, 0x00, 0x1e, 0x22 + frame-setup CFI_INSTRUCTION offset $w29, -16 + renamable $pn8 = WHILEGE_CXX_B undef $x0, undef $x0, 0, implicit-def dead $nzcv + renamable $p9 = ConvertPNRtoPPR killed renamable $pn8 + STR_PXI killed renamable $p9, $sp, 7 + renamable $p0 = LDR_PXI $sp, 7 + early-clobber $sp, $fp = frame-destroy LDRXpost $sp, 16 + RET undef $lr diff --git a/llvm/test/CodeGen/AArch64/spillfill-sve.mir b/llvm/test/CodeGen/AArch64/spillfill-sve.mir index ef7d55a1c2395..af062d33c5642 100644 --- a/llvm/test/CodeGen/AArch64/spillfill-sve.mir +++ b/llvm/test/CodeGen/AArch64/spillfill-sve.mir @@ -213,8 +213,7 @@ body: | ; EXPAND-LABEL: name: spills_fills_stack_id_virtreg_pnr ; EXPAND: renamable $pn8 = WHILEGE_CXX_B - ; EXPAND: $p0 = ORR_PPzPP $p8, $p8, killed $p8 - ; EXPAND: STR_PXI killed renamable $p0, $sp, 7 + ; EXPAND: STR_PXI killed renamable $p8, $sp, 7 ; ; EXPAND: renamable $p0 = LDR_PXI $sp, 7 ; EXPAND: $p8 = ORR_PPzPP $p0, $p0, killed $p0, implicit-def $pn8 From 929b1110ee05aa84224007045ecb5b5ee0e9301d Mon Sep 17 00:00:00 2001 From: Samuel Tebbs Date: Wed, 21 Feb 2024 16:30:21 +0000 Subject: [PATCH 02/19] fixup: constrain reg class instead of convert --- .../AArch64/AArch64ExpandPseudoInsts.cpp | 17 ----------- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 10 ++----- .../lib/Target/AArch64/AArch64SVEInstrInfo.td | 2 -- .../spillfill-sve-different-predicate.mir | 30 ------------------- llvm/test/CodeGen/AArch64/spillfill-sve.mir | 5 ++-- 5 files changed, 4 insertions(+), 60 deletions(-) delete mode 100644 llvm/test/CodeGen/AArch64/spillfill-sve-different-predicate.mir diff --git a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp index fe51a03bccc33..b2c52b443753d 100644 --- a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp +++ b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp @@ -1112,23 +1112,6 @@ bool AArch64ExpandPseudo::expandMI(MachineBasicBlock &MBB, default: break; - case AArch64::ConvertPNRtoPPR: { - auto TRI = MBB.getParent()->getSubtarget().getRegisterInfo(); - MachineOperand DstMO = MI.getOperand(0); - MachineOperand SrcMO = MI.getOperand(1); - unsigned SrcReg = SrcMO.getReg(); - if (!TRI->isSubRegister(DstMO.getReg(), SrcReg)) { - unsigned SrcSuperReg = TRI->getMatchingSuperReg(SrcReg, AArch64::psub, - &AArch64::PPRRegClass); - BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ORR_PPzPP)) - .add(DstMO) - .addReg(SrcSuperReg) - .addReg(SrcSuperReg) - .addReg(SrcSuperReg); - } - MI.eraseFromParent(); - return true; - } case AArch64::BSPv8i8: case AArch64::BSPv16i8: { Register DstReg = MI.getOperand(0).getReg(); diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 622d553bdb966..e2620a13fdace 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -4805,7 +4805,6 @@ void AArch64InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, bool Offset = true; MCRegister PNRReg = MCRegister::NoRegister; unsigned StackID = TargetStackID::Default; - const TargetInstrInfo *TII = MBB.getParent()->getSubtarget().getInstrInfo(); switch (TRI->getSpillSize(*RC)) { case 1: if (AArch64::FPR8RegClass.hasSubClassEq(RC)) @@ -4823,12 +4822,7 @@ void AArch64InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, assert((Subtarget.hasSVE2p1() || Subtarget.hasSME2()) && "Unexpected register store without SVE2p1 or SME2"); if (SrcReg.isVirtual()) { - auto NewSrcReg = - MF.getRegInfo().createVirtualRegister(&AArch64::PPR_p8to15RegClass); - BuildMI(MBB, MBBI, DebugLoc(), TII->get(AArch64::ConvertPNRtoPPR), - NewSrcReg) - .addReg(SrcReg); - SrcReg = NewSrcReg; + MF.getRegInfo().constrainRegClass(SrcReg, &AArch64::PPRRegClass); } else SrcReg = (SrcReg - AArch64::PN0) + AArch64::P0; Opc = AArch64::STR_PXI; @@ -5008,7 +5002,7 @@ void AArch64InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, "Unexpected register load without SVE2p1 or SME2"); PNRReg = DestReg; if (DestReg.isVirtual()) - DestReg = MF.getRegInfo().createVirtualRegister(&AArch64::PPRRegClass); + MF.getRegInfo().constrainRegClass(DestReg, &AArch64::PPRRegClass); else DestReg = (DestReg - AArch64::PN0) + AArch64::P0; Opc = AArch64::LDR_PXI; diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index c2d42c7703a01..7c98f934a1317 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -2313,8 +2313,6 @@ let Predicates = [HasBF16, HasSVEorSME] in { defm BFCVTNT_ZPmZ : sve_bfloat_convert<0b0, "bfcvtnt", int_aarch64_sve_fcvtnt_bf16f32>; } // End HasBF16, HasSVEorSME -def ConvertPNRtoPPR : Pseudo<(outs PPRAny:$Pd), (ins PNRAny:$Pm), []>, Sched<[]>; - let Predicates = [HasSVEorSME] in { // InstAliases def : InstAlias<"mov $Zd, $Zn", diff --git a/llvm/test/CodeGen/AArch64/spillfill-sve-different-predicate.mir b/llvm/test/CodeGen/AArch64/spillfill-sve-different-predicate.mir deleted file mode 100644 index abbc1d615b66f..0000000000000 --- a/llvm/test/CodeGen/AArch64/spillfill-sve-different-predicate.mir +++ /dev/null @@ -1,30 +0,0 @@ -# RUN: llc -mtriple=aarch64-linux-gnu -start-after=virtregrewriter -stop-after=aarch64-expand-pseudo -mattr=+sme2 -verify-machineinstrs -o - %s \ -# RUN: | FileCheck %s - ---- | - target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" - target triple = "aarch64-unknown-linux-gnu" - - define void @test_convert_different_reg() #0 { entry: unreachable } - - attributes #0 = { "target-features"="+sme2" } - ---- -name: test_convert_different_reg -tracksRegLiveness: true -body: | - bb.0.entry: - ; CHECK-LABEL: name: test_convert_different_reg - ; CHECK: renamable $pn8 = WHILEGE_CXX_B undef $x0, undef $x0, 0, implicit-def dead $nzcv - ; CHECK-NEXT: renamable $p9 = ORR_PPzPP $p8, $p8, $p8 - ; CHECK-NEXT: STR_PXI killed renamable $p9, $sp, 7 - ; CHECK-NEXT: renamable $p0 = LDR_PXI $sp, 7 - early-clobber $sp = frame-setup STRXpre killed $fp, $sp, -16 - frame-setup CFI_INSTRUCTION escape 0x0f, 0x0c, 0x8f, 0x00, 0x11, 0x10, 0x22, 0x11, 0x08, 0x92, 0x2e, 0x00, 0x1e, 0x22 - frame-setup CFI_INSTRUCTION offset $w29, -16 - renamable $pn8 = WHILEGE_CXX_B undef $x0, undef $x0, 0, implicit-def dead $nzcv - renamable $p9 = ConvertPNRtoPPR killed renamable $pn8 - STR_PXI killed renamable $p9, $sp, 7 - renamable $p0 = LDR_PXI $sp, 7 - early-clobber $sp, $fp = frame-destroy LDRXpost $sp, 16 - RET undef $lr diff --git a/llvm/test/CodeGen/AArch64/spillfill-sve.mir b/llvm/test/CodeGen/AArch64/spillfill-sve.mir index af062d33c5642..fba8af5a7028a 100644 --- a/llvm/test/CodeGen/AArch64/spillfill-sve.mir +++ b/llvm/test/CodeGen/AArch64/spillfill-sve.mir @@ -213,10 +213,9 @@ body: | ; EXPAND-LABEL: name: spills_fills_stack_id_virtreg_pnr ; EXPAND: renamable $pn8 = WHILEGE_CXX_B - ; EXPAND: STR_PXI killed renamable $p8, $sp, 7 + ; EXPAND: STR_PXI killed renamable $pn8, $sp, 7 ; - ; EXPAND: renamable $p0 = LDR_PXI $sp, 7 - ; EXPAND: $p8 = ORR_PPzPP $p0, $p0, killed $p0, implicit-def $pn8 + ; EXPAND: renamable $pn8 = LDR_PXI $sp, 7 ; EXPAND: $p0 = PEXT_PCI_B killed renamable $pn8, 0 From 514b9b59709ec95b318e3983433b8b6101d5ed29 Mon Sep 17 00:00:00 2001 From: Samuel Tebbs Date: Tue, 27 Feb 2024 14:29:47 +0000 Subject: [PATCH 03/19] fixup: let predicate spill and fill take ppr or pnr --- llvm/lib/Target/AArch64/AArch64RegisterInfo.td | 10 ++++++++++ llvm/lib/Target/AArch64/SVEInstrFormats.td | 6 +++--- llvm/test/CodeGen/AArch64/spillfill-sve.mir | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td index fef1748021b07..0e2f1b6c20a85 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td @@ -1004,6 +1004,16 @@ let Namespace = "AArch64" in { def psub1 : SubRegIndex<16, -1>; } +class PPRorPNRClass : RegisterClass< + "AArch64", + [ nxv16i1, nxv8i1, nxv4i1, nxv2i1, nxv1i1 ], 16, + (add PPR, PNR)> { + let Size = 16; +} +def PPRorPNR : PPRorPNRClass; +def PPRorPNRAsmOpAny : PPRAsmOperand<"PPRorPNRAny", "PPRorPNR", 0>; +def PPRorPNRAny : PPRRegOp<"", PPRorPNRAsmOpAny, ElementSizeNone, PPRorPNR>; + // Pairs of SVE predicate vector registers. def PSeqPairs : RegisterTuples<[psub0, psub1], [(rotl PPR, 0), (rotl PPR, 1)]>; diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td index 8baf3a6d3d818..200b131c05adc 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -6689,7 +6689,7 @@ multiclass sve_mem_z_spill { } class sve_mem_p_spill -: I<(outs), (ins PPRAny:$Pt, GPR64sp:$Rn, simm9:$imm9), +: I<(outs), (ins PPRorPNRAny:$Pt, GPR64sp:$Rn, simm9:$imm9), asm, "\t$Pt, [$Rn, $imm9, mul vl]", "", []>, Sched<[]> { @@ -6712,7 +6712,7 @@ multiclass sve_mem_p_spill { def NAME : sve_mem_p_spill; def : InstAlias(NAME) PPRAny:$Pt, GPR64sp:$Rn, 0), 1>; + (!cast(NAME) PPRorPNRAny:$Pt, GPR64sp:$Rn, 0), 1>; } //===----------------------------------------------------------------------===// @@ -7858,7 +7858,7 @@ multiclass sve_mem_z_fill { } class sve_mem_p_fill -: I<(outs PPRAny:$Pt), (ins GPR64sp:$Rn, simm9:$imm9), +: I<(outs PPRorPNRAny:$Pt), (ins GPR64sp:$Rn, simm9:$imm9), asm, "\t$Pt, [$Rn, $imm9, mul vl]", "", []>, Sched<[]> { diff --git a/llvm/test/CodeGen/AArch64/spillfill-sve.mir b/llvm/test/CodeGen/AArch64/spillfill-sve.mir index fba8af5a7028a..e30853c8d087b 100644 --- a/llvm/test/CodeGen/AArch64/spillfill-sve.mir +++ b/llvm/test/CodeGen/AArch64/spillfill-sve.mir @@ -1,5 +1,5 @@ # RUN: llc -mtriple=aarch64-linux-gnu -run-pass=greedy %s -o - | FileCheck %s -# RUN: llc -mtriple=aarch64-linux-gnu -start-before=greedy -stop-after=aarch64-expand-pseudo %s -o - | FileCheck %s --check-prefix=EXPAND +# RUN: llc -mtriple=aarch64-linux-gnu -start-before=greedy -stop-after=aarch64-expand-pseudo -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=EXPAND --- | ; ModuleID = '' source_filename = "" From 264a844fd6cc2d97fbe9be45337e9cb635bb2b0e Mon Sep 17 00:00:00 2001 From: Samuel Tebbs Date: Tue, 27 Feb 2024 14:29:58 +0000 Subject: [PATCH 04/19] fixup: remove braces --- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index e2620a13fdace..692a66e971b10 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -4821,9 +4821,9 @@ void AArch64InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, } else if (AArch64::PNRRegClass.hasSubClassEq(RC)) { assert((Subtarget.hasSVE2p1() || Subtarget.hasSME2()) && "Unexpected register store without SVE2p1 or SME2"); - if (SrcReg.isVirtual()) { + if (SrcReg.isVirtual()) MF.getRegInfo().constrainRegClass(SrcReg, &AArch64::PPRRegClass); - } else + else SrcReg = (SrcReg - AArch64::PN0) + AArch64::P0; Opc = AArch64::STR_PXI; StackID = TargetStackID::ScalableVector; From 53a317716b2df575280154fe0d2f86a71d00ed52 Mon Sep 17 00:00:00 2001 From: Samuel Tebbs Date: Wed, 28 Feb 2024 13:49:53 +0000 Subject: [PATCH 05/19] fixup: add decode function --- .../AArch64/Disassembler/AArch64Disassembler.cpp | 15 +++++++++++++++ .../AArch64/GlobalISel/regbank-inlineasm.mir | 8 ++++---- .../emit_fneg_with_non_register_operand.mir | 8 ++++---- llvm/test/CodeGen/AArch64/peephole-insvigpr.mir | 4 ++-- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index a21b4b77166ed..b596d3505a8e4 100644 --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -143,6 +143,9 @@ DecodeMatrixTileListRegisterClass(MCInst &Inst, unsigned RegMask, static DecodeStatus DecodePPRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder); +static DecodeStatus DecodePPRorPNRRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Addr, + const MCDisassembler *Decoder); static DecodeStatus DecodePNRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder); @@ -741,6 +744,18 @@ static DecodeStatus DecodeMatrixTile(MCInst &Inst, unsigned RegNo, return Success; } +static DecodeStatus DecodePPRorPNRRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Addr, + const MCDisassembler *Decoder) { + if (RegNo > 15) + return Fail; + + unsigned Register = + AArch64MCRegisterClasses[AArch64::PPRorPNRRegClassID].getRegister(RegNo); + Inst.addOperand(MCOperand::createReg(Register)); + return Success; +} + static DecodeStatus DecodePPRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr, const MCDisassembler *Decoder) { diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir index e77fac19e0a78..ae4619e9e7977 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir @@ -57,11 +57,11 @@ tracksRegLiveness: true body: | bb.1: ; CHECK-LABEL: name: inlineasm_virt_reg_output - ; CHECK: INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 1310730 /* regdef:PPR2_with_psub_in_PNR_3b_and_PPR2_with_psub1_in_PPR_p8to15 */, def %0 + ; CHECK: INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, {{[0-9]+}} /* regdef:GPR32common */, def %0 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr(s32) = COPY %0 ; CHECK-NEXT: $w0 = COPY [[COPY]](s32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 1310730 /* regdef:GPR32common */, def %0:gpr32common + INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 1769482 /* regdef:GPR32common */, def %0:gpr32common %1:_(s32) = COPY %0 $w0 = COPY %1(s32) RET_ReallyLR implicit $w0 @@ -75,12 +75,12 @@ tracksRegLiveness: true body: | bb.1: ; CHECK-LABEL: name: inlineasm_virt_mixed_types - ; CHECK: INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 1310730 /* regdef:PPR2_with_psub_in_PNR_3b_and_PPR2_with_psub1_in_PPR_p8to15 */, def %0, 2162698 /* regdef:WSeqPairsClass */, def %1 + ; CHECK: INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, {{[0-9]+}} /* regdef:GPR32common */, def %0, {{[0-9]+}} /* regdef:FPR64 */, def %1 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr(s32) = COPY %0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr(s64) = COPY %1 ; CHECK-NEXT: $d0 = COPY [[COPY1]](s64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 1310730 /* regdef:GPR32common */, def %0:gpr32common, 2162698 /* regdef:FPR64 */, def %1:fpr64 + INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 1769482 /* regdef:GPR32common */, def %0:gpr32common, 2621450 /* regdef:FPR64 */, def %1:fpr64 %3:_(s32) = COPY %0 %4:_(s64) = COPY %1 $d0 = COPY %4(s64) diff --git a/llvm/test/CodeGen/AArch64/emit_fneg_with_non_register_operand.mir b/llvm/test/CodeGen/AArch64/emit_fneg_with_non_register_operand.mir index 92fb053b0db72..1dae8a8ad4d23 100644 --- a/llvm/test/CodeGen/AArch64/emit_fneg_with_non_register_operand.mir +++ b/llvm/test/CodeGen/AArch64/emit_fneg_with_non_register_operand.mir @@ -91,10 +91,10 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[LOADgot:%[0-9]+]]:gpr64common = LOADgot target-flags(aarch64-got) @c ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[LOADgot]], 0 :: (dereferenceable load (s64) from @c) - ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, {{[0-9]+}} /* regdef:WSeqPairsClass_with_sube32_in_MatrixIndexGPR32_12_15 */, def %2, 2147483657 /* reguse tiedto:$0 */, [[LDRDui]](tied-def 3) + ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, {{[0-9]+}} /* regdef:FPR64 */, def %2, 2147483657 /* reguse tiedto:$0 */, [[LDRDui]](tied-def 3) ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY %2 ; CHECK-NEXT: [[LDRDui1:%[0-9]+]]:fpr64 = LDRDui [[LOADgot]], 0 :: (dereferenceable load (s64) from @c) - ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, {{[0-9]+}} /* regdef:WSeqPairsClass_with_sube32_in_MatrixIndexGPR32_12_15 */, def %4, 2147483657 /* reguse tiedto:$0 */, [[LDRDui1]](tied-def 3) + ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, {{[0-9]+}} /* regdef:FPR64 */, def %4, 2147483657 /* reguse tiedto:$0 */, [[LDRDui1]](tied-def 3) ; CHECK-NEXT: [[FNEGDr:%[0-9]+]]:fpr64 = FNEGDr %2 ; CHECK-NEXT: nofpexcept FCMPDrr %4, killed [[FNEGDr]], implicit-def $nzcv, implicit $fpcr ; CHECK-NEXT: Bcc 1, %bb.2, implicit $nzcv @@ -111,10 +111,10 @@ body: | %6:gpr64common = LOADgot target-flags(aarch64-got) @c %3:fpr64 = LDRDui %6, 0 :: (dereferenceable load (s64) from @c) - INLINEASM &"", 1 /* sideeffect attdialect */, 2359306 /* regdef:FPR64 */, def %2, 2147483657 /* reguse tiedto:$0 */, %3(tied-def 3) + INLINEASM &"", 1 /* sideeffect attdialect */, 2621450 /* regdef:FPR64 */, def %2, 2147483657 /* reguse tiedto:$0 */, %3(tied-def 3) %0:fpr64 = COPY %2 %5:fpr64 = LDRDui %6, 0 :: (dereferenceable load (s64) from @c) - INLINEASM &"", 1 /* sideeffect attdialect */, 2359306 /* regdef:FPR64 */, def %4, 2147483657 /* reguse tiedto:$0 */, %5(tied-def 3) + INLINEASM &"", 1 /* sideeffect attdialect */, 2621450 /* regdef:FPR64 */, def %4, 2147483657 /* reguse tiedto:$0 */, %5(tied-def 3) %7:fpr64 = FNEGDr %2 nofpexcept FCMPDrr %4, killed %7, implicit-def $nzcv, implicit $fpcr Bcc 1, %bb.2, implicit $nzcv diff --git a/llvm/test/CodeGen/AArch64/peephole-insvigpr.mir b/llvm/test/CodeGen/AArch64/peephole-insvigpr.mir index 65148344096cd..a86d3fb1094c5 100644 --- a/llvm/test/CodeGen/AArch64/peephole-insvigpr.mir +++ b/llvm/test/CodeGen/AArch64/peephole-insvigpr.mir @@ -487,7 +487,7 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64common = COPY $x0 ; CHECK-NEXT: [[DEF:%[0-9]+]]:gpr64all = IMPLICIT_DEF ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY [[DEF]] - ; CHECK-NEXT: INLINEASM &"ldr ${0:s}, $1", 8 /* mayload attdialect */, {{[0-9]+}} /* regdef:WSeqPairsClass_with_sube32_in_MatrixIndexGPR32_12_15 */, def %1, 262158 /* mem:m */, killed [[COPY1]] + ; CHECK-NEXT: INLINEASM &"ldr ${0:s}, $1", 8 /* mayload attdialect */, {{[0-9]+}} /* regdef:FPR64 */, def %1, 262158 /* mem:m */, killed [[COPY1]] ; CHECK-NEXT: [[MOVIv2d_ns:%[0-9]+]]:fpr128 = MOVIv2d_ns 0 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[MOVIv2d_ns]].dsub ; CHECK-NEXT: [[DEF1:%[0-9]+]]:fpr128 = IMPLICIT_DEF @@ -505,7 +505,7 @@ body: | %0:gpr64common = COPY $x0 %2:gpr64all = IMPLICIT_DEF %3:gpr64sp = COPY %2 - INLINEASM &"ldr ${0:s}, $1", 8 /* mayload attdialect */, 2359306 /* regdef:FPR64 */, def %1, 262158 /* mem:m */, killed %3 + INLINEASM &"ldr ${0:s}, $1", 8 /* mayload attdialect */, 2621450 /* regdef:FPR64 */, def %1, 262158 /* mem:m */, killed %3 %4:fpr128 = MOVIv2d_ns 0 %5:fpr64 = COPY %4.dsub %7:fpr128 = IMPLICIT_DEF From 6a4502c646b4d106038e7ff792d1445c1d533602 Mon Sep 17 00:00:00 2001 From: Samuel Tebbs Date: Wed, 28 Feb 2024 14:58:55 +0000 Subject: [PATCH 06/19] fixup: remove inst aliases --- llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index 7c98f934a1317..872f33e67184d 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -4017,16 +4017,6 @@ let Predicates = [HasSVEorSME] in { // Aliases for existing SVE instructions for which predicate-as-counter are // accepted as an operand to the instruction -def : InstAlias<"ldr $Pt, [$Rn, $imm9, mul vl]", - (LDR_PXI PNRasPPRAny:$Pt, GPR64sp:$Rn, simm9:$imm9), 0>; -def : InstAlias<"ldr $Pt, [$Rn]", - (LDR_PXI PNRasPPRAny:$Pt, GPR64sp:$Rn, 0), 0>; - -def : InstAlias<"str $Pt, [$Rn, $imm9, mul vl]", - (STR_PXI PNRasPPRAny:$Pt, GPR64sp:$Rn, simm9:$imm9), 0>; -def : InstAlias<"str $Pt, [$Rn]", - (STR_PXI PNRasPPRAny:$Pt, GPR64sp:$Rn, 0), 0>; - def : InstAlias<"mov $Pd, $Pn", (ORR_PPzPP PNRasPPR8:$Pd, PNRasPPR8:$Pn, PNRasPPR8:$Pn, PNRasPPR8:$Pn), 0>; From 808ddbbf8fdcb71edab45f166266b11a979740b2 Mon Sep 17 00:00:00 2001 From: Samuel Tebbs Date: Wed, 28 Feb 2024 14:59:13 +0000 Subject: [PATCH 07/19] fixup: match reg class in AArch64AsmParser --- llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index b807aaf76fdb0..d40b78e9fdcaa 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -6019,6 +6019,7 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode, return Error(Loc, "Invalid restricted vector register, expected z0.d..z15.d"); case Match_InvalidSVEPattern: return Error(Loc, "invalid predicate pattern"); + case Match_InvalidSVEPPRorPNRAnyReg: case Match_InvalidSVEPredicateAnyReg: case Match_InvalidSVEPredicateBReg: case Match_InvalidSVEPredicateHReg: @@ -6653,6 +6654,7 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_InvalidZPR_4b16: case Match_InvalidZPR_4b32: case Match_InvalidZPR_4b64: + case Match_InvalidSVEPPRorPNRAnyReg: case Match_InvalidSVEPredicateAnyReg: case Match_InvalidSVEPattern: case Match_InvalidSVEVecLenSpecifier: From ed8519e84238a4887e47721ddce11cf2eefc8e0e Mon Sep 17 00:00:00 2001 From: Samuel Tebbs Date: Wed, 28 Feb 2024 14:59:27 +0000 Subject: [PATCH 08/19] Add svcount to reg class --- llvm/lib/Target/AArch64/AArch64RegisterInfo.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td index 0e2f1b6c20a85..e4d6e657e3e0c 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td @@ -1006,7 +1006,7 @@ let Namespace = "AArch64" in { class PPRorPNRClass : RegisterClass< "AArch64", - [ nxv16i1, nxv8i1, nxv4i1, nxv2i1, nxv1i1 ], 16, + [ nxv16i1, nxv8i1, nxv4i1, nxv2i1, nxv1i1, aarch64svcount ], 16, (add PPR, PNR)> { let Size = 16; } From 6a5545134f7225450a8141f175f9a168b1e7226d Mon Sep 17 00:00:00 2001 From: Samuel Tebbs Date: Wed, 28 Feb 2024 14:59:39 +0000 Subject: [PATCH 09/19] fixup: format definitions --- llvm/lib/Target/AArch64/AArch64RegisterInfo.td | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td index e4d6e657e3e0c..81936c6adb2d8 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td @@ -1010,9 +1010,9 @@ class PPRorPNRClass : RegisterClass< (add PPR, PNR)> { let Size = 16; } -def PPRorPNR : PPRorPNRClass; -def PPRorPNRAsmOpAny : PPRAsmOperand<"PPRorPNRAny", "PPRorPNR", 0>; -def PPRorPNRAny : PPRRegOp<"", PPRorPNRAsmOpAny, ElementSizeNone, PPRorPNR>; +def PPRorPNR : PPRorPNRClass; +def PPRorPNRAsmOpAny : PPRAsmOperand<"PPRorPNRAny", "PPRorPNR", 0>; +def PPRorPNRAny : PPRRegOp<"", PPRorPNRAsmOpAny, ElementSizeNone, PPRorPNR>; // Pairs of SVE predicate vector registers. def PSeqPairs : RegisterTuples<[psub0, psub1], [(rotl PPR, 0), (rotl PPR, 1)]>; From a229c769973338a47aad3dd33e3a3483d5e5e8d7 Mon Sep 17 00:00:00 2001 From: Samuel Tebbs Date: Thu, 29 Feb 2024 15:10:31 +0000 Subject: [PATCH 10/19] fixup: use reg class numbers in MIR tests --- llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir | 4 ++-- .../CodeGen/AArch64/emit_fneg_with_non_register_operand.mir | 4 ++-- llvm/test/CodeGen/AArch64/peephole-insvigpr.mir | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir index ae4619e9e7977..2ffb785680685 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir @@ -57,7 +57,7 @@ tracksRegLiveness: true body: | bb.1: ; CHECK-LABEL: name: inlineasm_virt_reg_output - ; CHECK: INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, {{[0-9]+}} /* regdef:GPR32common */, def %0 + ; CHECK: INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 1769482 /* regdef:GPR32common */, def %0 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr(s32) = COPY %0 ; CHECK-NEXT: $w0 = COPY [[COPY]](s32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 @@ -75,7 +75,7 @@ tracksRegLiveness: true body: | bb.1: ; CHECK-LABEL: name: inlineasm_virt_mixed_types - ; CHECK: INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, {{[0-9]+}} /* regdef:GPR32common */, def %0, {{[0-9]+}} /* regdef:FPR64 */, def %1 + ; CHECK: INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 1769482 /* regdef:GPR32common */, def %0, {{[0-9]+}} /* regdef:FPR64 */, def %1 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr(s32) = COPY %0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr(s64) = COPY %1 ; CHECK-NEXT: $d0 = COPY [[COPY1]](s64) diff --git a/llvm/test/CodeGen/AArch64/emit_fneg_with_non_register_operand.mir b/llvm/test/CodeGen/AArch64/emit_fneg_with_non_register_operand.mir index 1dae8a8ad4d23..2be7aba2a3df8 100644 --- a/llvm/test/CodeGen/AArch64/emit_fneg_with_non_register_operand.mir +++ b/llvm/test/CodeGen/AArch64/emit_fneg_with_non_register_operand.mir @@ -91,10 +91,10 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[LOADgot:%[0-9]+]]:gpr64common = LOADgot target-flags(aarch64-got) @c ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[LOADgot]], 0 :: (dereferenceable load (s64) from @c) - ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, {{[0-9]+}} /* regdef:FPR64 */, def %2, 2147483657 /* reguse tiedto:$0 */, [[LDRDui]](tied-def 3) + ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 2621450 /* regdef:FPR64 */, def %2, 2147483657 /* reguse tiedto:$0 */, [[LDRDui]](tied-def 3) ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY %2 ; CHECK-NEXT: [[LDRDui1:%[0-9]+]]:fpr64 = LDRDui [[LOADgot]], 0 :: (dereferenceable load (s64) from @c) - ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, {{[0-9]+}} /* regdef:FPR64 */, def %4, 2147483657 /* reguse tiedto:$0 */, [[LDRDui1]](tied-def 3) + ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 2621450 /* regdef:FPR64 */, def %4, 2147483657 /* reguse tiedto:$0 */, [[LDRDui1]](tied-def 3) ; CHECK-NEXT: [[FNEGDr:%[0-9]+]]:fpr64 = FNEGDr %2 ; CHECK-NEXT: nofpexcept FCMPDrr %4, killed [[FNEGDr]], implicit-def $nzcv, implicit $fpcr ; CHECK-NEXT: Bcc 1, %bb.2, implicit $nzcv diff --git a/llvm/test/CodeGen/AArch64/peephole-insvigpr.mir b/llvm/test/CodeGen/AArch64/peephole-insvigpr.mir index a86d3fb1094c5..5dd29cf39c0ea 100644 --- a/llvm/test/CodeGen/AArch64/peephole-insvigpr.mir +++ b/llvm/test/CodeGen/AArch64/peephole-insvigpr.mir @@ -487,7 +487,7 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64common = COPY $x0 ; CHECK-NEXT: [[DEF:%[0-9]+]]:gpr64all = IMPLICIT_DEF ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY [[DEF]] - ; CHECK-NEXT: INLINEASM &"ldr ${0:s}, $1", 8 /* mayload attdialect */, {{[0-9]+}} /* regdef:FPR64 */, def %1, 262158 /* mem:m */, killed [[COPY1]] + ; CHECK-NEXT: INLINEASM &"ldr ${0:s}, $1", 8 /* mayload attdialect */, 2621450 /* regdef:FPR64 */, def %1, 262158 /* mem:m */, killed [[COPY1]] ; CHECK-NEXT: [[MOVIv2d_ns:%[0-9]+]]:fpr128 = MOVIv2d_ns 0 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[MOVIv2d_ns]].dsub ; CHECK-NEXT: [[DEF1:%[0-9]+]]:fpr128 = IMPLICIT_DEF From 8c5b567286f7cf7450ba82a8de550438a72d4cc2 Mon Sep 17 00:00:00 2001 From: Samuel Tebbs Date: Wed, 6 Mar 2024 15:45:33 +0000 Subject: [PATCH 11/19] fixup: Add parsing and rendering functions --- .../lib/Target/AArch64/AArch64RegisterInfo.td | 14 +++++++- .../AArch64/AsmParser/AArch64AsmParser.cpp | 36 +++++++++++++++++++ llvm/lib/Target/AArch64/SVEInstrFormats.td | 2 +- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td index 81936c6adb2d8..d57429017aa0e 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td @@ -1010,8 +1010,20 @@ class PPRorPNRClass : RegisterClass< (add PPR, PNR)> { let Size = 16; } + def PPRorPNR : PPRorPNRClass; -def PPRorPNRAsmOpAny : PPRAsmOperand<"PPRorPNRAny", "PPRorPNR", 0>; + +class PPRorPNRAsmOperand: AsmOperandClass { + let Name = "SVE" # name # "Reg"; + let PredicateMethod = "isSVEPredicateOrPredicateAsCounterRegOfWidth<" + # Width # ", " # "AArch64::" + # RegClass # "RegClassID>"; + let DiagnosticType = "InvalidSVE" # name # "Reg"; + let RenderMethod = "addPPRorPNRRegOperands"; + let ParserMethod = "tryParseSVEPredicateOrPredicateAsCounterVector"; +} + +def PPRorPNRAsmOpAny : PPRorPNRAsmOperand<"PPRorPNRAny", "PPRorPNR", 0>; def PPRorPNRAny : PPRRegOp<"", PPRorPNRAsmOpAny, ElementSizeNone, PPRorPNR>; // Pairs of SVE predicate vector registers. diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index d40b78e9fdcaa..8915d3940b86a 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -276,6 +276,8 @@ class AArch64AsmParser : public MCTargetAsmParser { ParseStatus tryParseSVEDataVector(OperandVector &Operands); template ParseStatus tryParseSVEPredicateVector(OperandVector &Operands); + ParseStatus + tryParseSVEPredicateOrPredicateAsCounterVector(OperandVector &Operands); template ParseStatus tryParseVectorList(OperandVector &Operands, bool ExpectMatch = false); @@ -1241,6 +1243,7 @@ class AArch64Operand : public MCParsedAsmOperand { case AArch64::PPR_p8to15RegClassID: case AArch64::PNRRegClassID: case AArch64::PNR_p8to15RegClassID: + case AArch64::PPRorPNRRegClassID: RK = RegKind::SVEPredicateAsCounter; break; default: @@ -1264,6 +1267,7 @@ class AArch64Operand : public MCParsedAsmOperand { case AArch64::PPR_p8to15RegClassID: case AArch64::PNRRegClassID: case AArch64::PNR_p8to15RegClassID: + case AArch64::PPRorPNRRegClassID: RK = RegKind::SVEPredicateVector; break; default: @@ -1290,6 +1294,20 @@ class AArch64Operand : public MCParsedAsmOperand { return DiagnosticPredicateTy::NearMatch; } + template + DiagnosticPredicate isSVEPredicateOrPredicateAsCounterRegOfWidth() const { + if (Kind != k_Register || (Reg.Kind != RegKind::SVEPredicateAsCounter && + Reg.Kind != RegKind::SVEPredicateVector)) + return DiagnosticPredicateTy::NoMatch; + + if ((isSVEPredicateAsCounterReg() || + isSVEPredicateVectorRegOfWidth()) && + (Reg.ElementWidth == ElementWidth)) + return DiagnosticPredicateTy::Match; + + return DiagnosticPredicateTy::NearMatch; + } + template DiagnosticPredicate isSVEPredicateAsCounterRegOfWidth() const { if (Kind != k_Register || Reg.Kind != RegKind::SVEPredicateAsCounter) @@ -1770,6 +1788,15 @@ class AArch64Operand : public MCParsedAsmOperand { Inst.addOperand(MCOperand::createReg(AArch64::Z0 + getReg() - Base)); } + void addPPRorPNRRegOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + unsigned Reg = getReg(); + // Normalise to PPR + if (Reg >= AArch64::PN0) + Reg = Reg - AArch64::PN0 + AArch64::P0; + Inst.addOperand(MCOperand::createReg(Reg)); + } + void addPNRasPPRRegOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); Inst.addOperand( @@ -4167,6 +4194,15 @@ ParseStatus AArch64AsmParser::tryParseVectorRegister(MCRegister &Reg, return ParseStatus::NoMatch; } +ParseStatus AArch64AsmParser::tryParseSVEPredicateOrPredicateAsCounterVector( + OperandVector &Operands) { + ParseStatus Status = + tryParseSVEPredicateVector(Operands); + if (!Status.isSuccess()) + Status = tryParseSVEPredicateVector(Operands); + return Status; +} + /// tryParseSVEPredicateVector - Parse a SVE predicate register operand. template ParseStatus diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td index 200b131c05adc..87bf9f02dc7ed 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -7881,7 +7881,7 @@ multiclass sve_mem_p_fill { def NAME : sve_mem_p_fill; def : InstAlias(NAME) PPRAny:$Pt, GPR64sp:$Rn, 0), 1>; + (!cast(NAME) PPRorPNRAny:$Pt, GPR64sp:$Rn, 0), 1>; } class sve2_mem_gldnt_vs_base opc, dag iops, string asm, From a64ca2257a070fba103b894a8bf30f397fa7c552 Mon Sep 17 00:00:00 2001 From: Samuel Tebbs Date: Thu, 7 Mar 2024 09:41:28 +0000 Subject: [PATCH 12/19] fixup: remove spaces --- llvm/lib/Target/AArch64/AArch64RegisterInfo.td | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td index d57429017aa0e..d32044eebdfba 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td @@ -1011,8 +1011,6 @@ class PPRorPNRClass : RegisterClass< let Size = 16; } -def PPRorPNR : PPRorPNRClass; - class PPRorPNRAsmOperand: AsmOperandClass { let Name = "SVE" # name # "Reg"; let PredicateMethod = "isSVEPredicateOrPredicateAsCounterRegOfWidth<" @@ -1023,8 +1021,9 @@ class PPRorPNRAsmOperand: AsmOperandCla let ParserMethod = "tryParseSVEPredicateOrPredicateAsCounterVector"; } -def PPRorPNRAsmOpAny : PPRorPNRAsmOperand<"PPRorPNRAny", "PPRorPNR", 0>; -def PPRorPNRAny : PPRRegOp<"", PPRorPNRAsmOpAny, ElementSizeNone, PPRorPNR>; +def PPRorPNR : PPRorPNRClass; +def PPRorPNRAsmOpAny : PPRorPNRAsmOperand<"PPRorPNRAny", "PPRorPNR", 0>; +def PPRorPNRAny : PPRRegOp<"", PPRorPNRAsmOpAny, ElementSizeNone, PPRorPNR>; // Pairs of SVE predicate vector registers. def PSeqPairs : RegisterTuples<[psub0, psub1], [(rotl PPR, 0), (rotl PPR, 1)]>; From 9e59c45a8b99d44a8c43ba6b8c454cc7cd0bd728 Mon Sep 17 00:00:00 2001 From: Samuel Tebbs Date: Thu, 7 Mar 2024 09:47:02 +0000 Subject: [PATCH 13/19] fixup: format decode function --- .../Target/AArch64/Disassembler/AArch64Disassembler.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index b596d3505a8e4..ddb875e73ff5a 100644 --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -144,8 +144,8 @@ static DecodeStatus DecodePPRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder); static DecodeStatus DecodePPRorPNRRegisterClass(MCInst &Inst, unsigned RegNo, - uint64_t Addr, - const MCDisassembler *Decoder); + uint64_t Addr, + const MCDisassembler *Decoder); static DecodeStatus DecodePNRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder); @@ -745,8 +745,8 @@ static DecodeStatus DecodeMatrixTile(MCInst &Inst, unsigned RegNo, } static DecodeStatus DecodePPRorPNRRegisterClass(MCInst &Inst, unsigned RegNo, - uint64_t Addr, - const MCDisassembler *Decoder) { + uint64_t Addr, + const MCDisassembler *Decoder) { if (RegNo > 15) return Fail; From 1a398e1b0e8e83c50a4dbce76f6dca051c1473da Mon Sep 17 00:00:00 2001 From: Samuel Tebbs Date: Wed, 20 Mar 2024 09:51:14 +0000 Subject: [PATCH 14/19] fixup: merge pprorpnr and ppraspnr handling --- llvm/lib/Target/AArch64/AArch64RegisterInfo.td | 13 ++----------- llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td | 4 ++-- .../Target/AArch64/AsmParser/AArch64AsmParser.cpp | 6 ++---- llvm/lib/Target/AArch64/SMEInstrFormats.td | 15 +-------------- llvm/lib/Target/AArch64/SVEInstrFormats.td | 4 ++-- llvm/test/MC/AArch64/SVE/pfalse-diagnostics.s | 2 +- 6 files changed, 10 insertions(+), 34 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td index d32044eebdfba..80d0f9c57f4b3 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td @@ -953,17 +953,6 @@ class PNRAsmOperand: AsmOperandClass { let ParserMethod = "tryParseSVEPredicateVector"; } -let RenderMethod = "addPNRasPPRRegOperands" in { - def PNRasPPROpAny : PNRAsmOperand<"PNRasPPRPredicateAny", "PNR", 0>; - def PNRasPPROp8 : PNRAsmOperand<"PNRasPPRPredicateB", "PNR", 8>; -} - -class PNRasPPRRegOp : SVERegOp {} - -def PNRasPPRAny : PNRasPPRRegOp<"", PNRasPPROpAny, ElementSizeNone, PPR>; -def PNRasPPR8 : PNRasPPRRegOp<"b", PNRasPPROp8, ElementSizeB, PPR>; - def PNRAsmOpAny: PNRAsmOperand<"PNPredicateAny", "PNR", 0>; def PNRAsmOp8 : PNRAsmOperand<"PNPredicateB", "PNR", 8>; def PNRAsmOp16 : PNRAsmOperand<"PNPredicateH", "PNR", 16>; @@ -1022,8 +1011,10 @@ class PPRorPNRAsmOperand: AsmOperandCla } def PPRorPNR : PPRorPNRClass; +def PPRorPNRAsmOp8 : PPRorPNRAsmOperand<"PPRorPNRB", "PPRorPNR", 8>; def PPRorPNRAsmOpAny : PPRorPNRAsmOperand<"PPRorPNRAny", "PPRorPNR", 0>; def PPRorPNRAny : PPRRegOp<"", PPRorPNRAsmOpAny, ElementSizeNone, PPRorPNR>; +def PPRorPNR8 : PPRRegOp<"b", PPRorPNRAsmOp8, ElementSizeB, PPRorPNR>; // Pairs of SVE predicate vector registers. def PSeqPairs : RegisterTuples<[psub0, psub1], [(rotl PPR, 0), (rotl PPR, 1)]>; diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index 872f33e67184d..d81ac4915a183 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -4018,9 +4018,9 @@ let Predicates = [HasSVEorSME] in { // Aliases for existing SVE instructions for which predicate-as-counter are // accepted as an operand to the instruction def : InstAlias<"mov $Pd, $Pn", - (ORR_PPzPP PNRasPPR8:$Pd, PNRasPPR8:$Pn, PNRasPPR8:$Pn, PNRasPPR8:$Pn), 0>; + (ORR_PPzPP PPRorPNR8:$Pd, PPRorPNR8:$Pn, PPRorPNR8:$Pn, PPRorPNR8:$Pn), 0>; -def : InstAlias<"pfalse\t$Pd", (PFALSE PNRasPPR8:$Pd), 0>; +def : InstAlias<"pfalse\t$Pd", (PFALSE PPRorPNR8:$Pd), 0>; } diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 8915d3940b86a..ba6325351deac 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -6056,6 +6056,7 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode, case Match_InvalidSVEPattern: return Error(Loc, "invalid predicate pattern"); case Match_InvalidSVEPPRorPNRAnyReg: + case Match_InvalidSVEPPRorPNRBReg: case Match_InvalidSVEPredicateAnyReg: case Match_InvalidSVEPredicateBReg: case Match_InvalidSVEPredicateHReg: @@ -6168,9 +6169,6 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode, case Match_AddSubLSLImm3ShiftLarge: return Error(Loc, "expected 'lsl' with optional integer in range [0, 7]"); - case Match_InvalidSVEPNRasPPRPredicateBReg: - return Error(Loc, - "Expected predicate-as-counter register name with .B suffix"); default: llvm_unreachable("unexpected error code!"); } @@ -6752,7 +6750,7 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_InvalidSVEVectorListStrided4x16: case Match_InvalidSVEVectorListStrided4x32: case Match_InvalidSVEVectorListStrided4x64: - case Match_InvalidSVEPNRasPPRPredicateBReg: + case Match_InvalidSVEPPRorPNRBReg: case Match_MSR: case Match_MRS: { if (ErrorInfo >= Operands.size()) diff --git a/llvm/lib/Target/AArch64/SMEInstrFormats.td b/llvm/lib/Target/AArch64/SMEInstrFormats.td index 33cb5f9734b81..88896879b052d 100644 --- a/llvm/lib/Target/AArch64/SMEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SMEInstrFormats.td @@ -1303,7 +1303,7 @@ multiclass sve2_clamp { } class sve2_int_perm_sel_p - : I<(outs PPRAny:$Pd), (ins PPRAny:$Pn, ppr_ty:$Pm, + : I<(outs PPRorPNRAny:$Pd), (ins PPRorPNRAny:$Pn, ppr_ty:$Pm, MatrixIndexGPR32Op12_15:$Rv, imm_ty:$imm), asm, "\t$Pd, $Pn, $Pm[$Rv, $imm]", "", []>, Sched<[]> { @@ -1347,19 +1347,6 @@ multiclass sve2_int_perm_sel_p { let Inst{20-18} = 0b000; } - def : InstAlias(NAME # _B) PNRasPPRAny:$Pd, - PNRasPPRAny:$Pn, PPR8:$Pm, MatrixIndexGPR32Op12_15:$Rv, sme_elm_idx0_15:$imm), 0>; - def : InstAlias(NAME # _H) PNRasPPRAny:$Pd, - PNRasPPRAny:$Pn, PPR16:$Pm, MatrixIndexGPR32Op12_15:$Rv, sme_elm_idx0_7:$imm), 0>; - def : InstAlias(NAME # _S) PNRasPPRAny:$Pd, - PNRasPPRAny:$Pn, PPR32:$Pm, MatrixIndexGPR32Op12_15:$Rv, sme_elm_idx0_3:$imm), 0>; - def : InstAlias(NAME # _D) PNRasPPRAny:$Pd, - PNRasPPRAny:$Pn, PPR64:$Pm, MatrixIndexGPR32Op12_15:$Rv, sme_elm_idx0_1:$imm), 0>; - def : Pat<(nxv16i1 (op (nxv16i1 PPRAny:$Pn), (nxv16i1 PPR8:$Pm), MatrixIndexGPR32Op12_15:$idx)), (!cast(NAME # _B) $Pn, $Pm, $idx, 0)>; diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td index 87bf9f02dc7ed..2bb023dcdc0e7 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -740,7 +740,7 @@ let hasNoSchedulingInfo = 1 in { //===----------------------------------------------------------------------===// class sve_int_pfalse opc, string asm> -: I<(outs PPR8:$Pd), (ins), +: I<(outs PPRorPNR8:$Pd), (ins), asm, "\t$Pd", "", []>, Sched<[]> { @@ -1848,7 +1848,7 @@ multiclass sve_int_sel_vvv { //===----------------------------------------------------------------------===// class sve_int_pred_log opc, string asm> -: I<(outs PPR8:$Pd), (ins PPRAny:$Pg, PPR8:$Pn, PPR8:$Pm), +: I<(outs PPRorPNR8:$Pd), (ins PPRorPNRAny:$Pg, PPRorPNR8:$Pn, PPRorPNR8:$Pm), asm, "\t$Pd, $Pg/z, $Pn, $Pm", "", []>, Sched<[]> { diff --git a/llvm/test/MC/AArch64/SVE/pfalse-diagnostics.s b/llvm/test/MC/AArch64/SVE/pfalse-diagnostics.s index f4d95c5910d89..e44453b4c3265 100644 --- a/llvm/test/MC/AArch64/SVE/pfalse-diagnostics.s +++ b/llvm/test/MC/AArch64/SVE/pfalse-diagnostics.s @@ -17,6 +17,6 @@ pfalse pn16.b // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: pfalse pn5.d -// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Expected predicate-as-counter register name with .B suffix +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid predicate register // CHECK-NEXT: pfalse pn5.d // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: From 2f6d4186e5a88ffc74e071c9e1ff30bffe02dc11 Mon Sep 17 00:00:00 2001 From: Samuel Tebbs Date: Tue, 2 Apr 2024 17:04:03 +0100 Subject: [PATCH 15/19] fixup: combine ppr and pnr stack slot handling --- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 66 +++++++++++--------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 692a66e971b10..eadd4f5929a0a 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -4813,20 +4813,22 @@ void AArch64InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, case 2: if (AArch64::FPR16RegClass.hasSubClassEq(RC)) Opc = AArch64::STRHui; - else if (AArch64::PPRRegClass.hasSubClassEq(RC)) { - assert(Subtarget.hasSVEorSME() && - "Unexpected register store without SVE store instructions"); - Opc = AArch64::STR_PXI; - StackID = TargetStackID::ScalableVector; - } else if (AArch64::PNRRegClass.hasSubClassEq(RC)) { - assert((Subtarget.hasSVE2p1() || Subtarget.hasSME2()) && - "Unexpected register store without SVE2p1 or SME2"); - if (SrcReg.isVirtual()) - MF.getRegInfo().constrainRegClass(SrcReg, &AArch64::PPRRegClass); - else - SrcReg = (SrcReg - AArch64::PN0) + AArch64::P0; - Opc = AArch64::STR_PXI; - StackID = TargetStackID::ScalableVector; + else { + bool IsPPR = AArch64::PPRRegClass.hasSubClassEq(RC); + bool IsPNR = AArch64::PNRRegClass.hasSubClassEq(RC); + if (IsPPR || IsPNR) { + assert((!IsPPR || Subtarget.hasSVEorSME()) && + "Unexpected register store without SVE store instructions"); + assert((!IsPNR || Subtarget.hasSVE2p1() || Subtarget.hasSME2()) && + "Unexpected register store without SVE2p1 or SME2"); + Opc = AArch64::STR_PXI; + StackID = TargetStackID::ScalableVector; + if (SrcReg.isVirtual()) + MF.getRegInfo().constrainRegClass(SrcReg, &AArch64::PPRRegClass); + else if (IsPNR) + // Normalise to PPR + SrcReg = (SrcReg - AArch64::PN0) + AArch64::P0; + } } break; case 4: @@ -4992,21 +4994,27 @@ void AArch64InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, case 2: if (AArch64::FPR16RegClass.hasSubClassEq(RC)) Opc = AArch64::LDRHui; - else if (AArch64::PPRRegClass.hasSubClassEq(RC)) { - assert(Subtarget.hasSVEorSME() && - "Unexpected register load without SVE load instructions"); - Opc = AArch64::LDR_PXI; - StackID = TargetStackID::ScalableVector; - } else if (AArch64::PNRRegClass.hasSubClassEq(RC)) { - assert((Subtarget.hasSVE2p1() || Subtarget.hasSME2()) && - "Unexpected register load without SVE2p1 or SME2"); - PNRReg = DestReg; - if (DestReg.isVirtual()) - MF.getRegInfo().constrainRegClass(DestReg, &AArch64::PPRRegClass); - else - DestReg = (DestReg - AArch64::PN0) + AArch64::P0; - Opc = AArch64::LDR_PXI; - StackID = TargetStackID::ScalableVector; + else { + bool IsPPR = AArch64::PPRRegClass.hasSubClassEq(RC); + bool IsPNR = AArch64::PNRRegClass.hasSubClassEq(RC); + if (IsPPR || IsPNR) { + assert((!IsPPR || Subtarget.hasSVEorSME()) && + "Unexpected register load without SVE load instructions"); + assert((!IsPNR || Subtarget.hasSVE2p1() || Subtarget.hasSME2()) && + "Unexpected register load without SVE2p1 or SME2"); + + if (IsPNR) + PNRReg = DestReg; + + if (DestReg.isVirtual()) + MF.getRegInfo().constrainRegClass(DestReg, &AArch64::PPRRegClass); + else if (IsPNR) + // Normalise to PPR + DestReg = (DestReg - AArch64::PN0) + AArch64::P0; + + Opc = AArch64::LDR_PXI; + StackID = TargetStackID::ScalableVector; + } } break; case 4: From f06c0ce066684bacf1ce471238566329ce62b2c7 Mon Sep 17 00:00:00 2001 From: Samuel Tebbs Date: Tue, 2 Apr 2024 17:04:19 +0100 Subject: [PATCH 16/19] fixup: add <= pn15 to asm parser --- llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index ba6325351deac..4fd20b08e5def 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -1792,7 +1792,7 @@ class AArch64Operand : public MCParsedAsmOperand { assert(N == 1 && "Invalid number of operands!"); unsigned Reg = getReg(); // Normalise to PPR - if (Reg >= AArch64::PN0) + if (Reg >= AArch64::PN0 && Reg <= AArch64::PN15) Reg = Reg - AArch64::PN0 + AArch64::P0; Inst.addOperand(MCOperand::createReg(Reg)); } From 23b051b21278dedd666bce3719d37176919bc9bc Mon Sep 17 00:00:00 2001 From: Sam Tebbs Date: Fri, 5 Apr 2024 16:46:29 +0100 Subject: [PATCH 17/19] fixup: simplify load/storeRegToStackSlot --- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 13 ------------- llvm/test/CodeGen/AArch64/spillfill-sve.mir | 4 ++-- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index eadd4f5929a0a..1efd63aeaad91 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -4823,11 +4823,6 @@ void AArch64InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, "Unexpected register store without SVE2p1 or SME2"); Opc = AArch64::STR_PXI; StackID = TargetStackID::ScalableVector; - if (SrcReg.isVirtual()) - MF.getRegInfo().constrainRegClass(SrcReg, &AArch64::PPRRegClass); - else if (IsPNR) - // Normalise to PPR - SrcReg = (SrcReg - AArch64::PN0) + AArch64::P0; } } break; @@ -5002,16 +4997,8 @@ void AArch64InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, "Unexpected register load without SVE load instructions"); assert((!IsPNR || Subtarget.hasSVE2p1() || Subtarget.hasSME2()) && "Unexpected register load without SVE2p1 or SME2"); - if (IsPNR) PNRReg = DestReg; - - if (DestReg.isVirtual()) - MF.getRegInfo().constrainRegClass(DestReg, &AArch64::PPRRegClass); - else if (IsPNR) - // Normalise to PPR - DestReg = (DestReg - AArch64::PN0) + AArch64::P0; - Opc = AArch64::LDR_PXI; StackID = TargetStackID::ScalableVector; } diff --git a/llvm/test/CodeGen/AArch64/spillfill-sve.mir b/llvm/test/CodeGen/AArch64/spillfill-sve.mir index e30853c8d087b..11cf388e38531 100644 --- a/llvm/test/CodeGen/AArch64/spillfill-sve.mir +++ b/llvm/test/CodeGen/AArch64/spillfill-sve.mir @@ -173,8 +173,8 @@ body: | ; CHECK-NEXT: stack-id: scalable-vector, callee-saved-register: '' ; EXPAND-LABEL: name: spills_fills_stack_id_pnr - ; EXPAND: STR_PXI $p0, $sp, 7 - ; EXPAND: $p0 = LDR_PXI $sp, 7, implicit-def $pn0 + ; EXPAND: STR_PXI $pn0, $sp, 7 + ; EXPAND: $pn0 = LDR_PXI $sp, 7, implicit-def $pn0 %0:pnr = COPY $pn0 From a53aeb4d90129ca87aba68a38012eacf65211c47 Mon Sep 17 00:00:00 2001 From: Sam Tebbs Date: Fri, 5 Apr 2024 16:55:51 +0100 Subject: [PATCH 18/19] fixup: remove extra parentheses --- llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 4fd20b08e5def..7aa8f6cd57557 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -1302,7 +1302,7 @@ class AArch64Operand : public MCParsedAsmOperand { if ((isSVEPredicateAsCounterReg() || isSVEPredicateVectorRegOfWidth()) && - (Reg.ElementWidth == ElementWidth)) + Reg.ElementWidth == ElementWidth) return DiagnosticPredicateTy::Match; return DiagnosticPredicateTy::NearMatch; From 03aabd26e1f2c0b5c9360eb1f48102b69937a10c Mon Sep 17 00:00:00 2001 From: Samuel Tebbs Date: Tue, 9 Apr 2024 09:49:12 +0100 Subject: [PATCH 19/19] fixup: remove IsPPR and move error match case statement --- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 48 +++++++++---------- .../AArch64/AsmParser/AArch64AsmParser.cpp | 2 +- 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 1efd63aeaad91..847cf4042ecc2 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -4810,22 +4810,20 @@ void AArch64InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, if (AArch64::FPR8RegClass.hasSubClassEq(RC)) Opc = AArch64::STRBui; break; - case 2: + case 2: { + bool IsPNR = AArch64::PNRRegClass.hasSubClassEq(RC); if (AArch64::FPR16RegClass.hasSubClassEq(RC)) Opc = AArch64::STRHui; - else { - bool IsPPR = AArch64::PPRRegClass.hasSubClassEq(RC); - bool IsPNR = AArch64::PNRRegClass.hasSubClassEq(RC); - if (IsPPR || IsPNR) { - assert((!IsPPR || Subtarget.hasSVEorSME()) && - "Unexpected register store without SVE store instructions"); - assert((!IsPNR || Subtarget.hasSVE2p1() || Subtarget.hasSME2()) && - "Unexpected register store without SVE2p1 or SME2"); - Opc = AArch64::STR_PXI; - StackID = TargetStackID::ScalableVector; - } + else if (IsPNR || AArch64::PPRRegClass.hasSubClassEq(RC)) { + assert(Subtarget.hasSVEorSME() && + "Unexpected register store without SVE store instructions"); + assert((!IsPNR || Subtarget.hasSVE2p1() || Subtarget.hasSME2()) && + "Unexpected register store without SVE2p1 or SME2"); + Opc = AArch64::STR_PXI; + StackID = TargetStackID::ScalableVector; } break; + } case 4: if (AArch64::GPR32allRegClass.hasSubClassEq(RC)) { Opc = AArch64::STRWui; @@ -4986,24 +4984,22 @@ void AArch64InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, if (AArch64::FPR8RegClass.hasSubClassEq(RC)) Opc = AArch64::LDRBui; break; - case 2: + case 2: { + bool IsPNR = AArch64::PNRRegClass.hasSubClassEq(RC); if (AArch64::FPR16RegClass.hasSubClassEq(RC)) Opc = AArch64::LDRHui; - else { - bool IsPPR = AArch64::PPRRegClass.hasSubClassEq(RC); - bool IsPNR = AArch64::PNRRegClass.hasSubClassEq(RC); - if (IsPPR || IsPNR) { - assert((!IsPPR || Subtarget.hasSVEorSME()) && - "Unexpected register load without SVE load instructions"); - assert((!IsPNR || Subtarget.hasSVE2p1() || Subtarget.hasSME2()) && - "Unexpected register load without SVE2p1 or SME2"); - if (IsPNR) - PNRReg = DestReg; - Opc = AArch64::LDR_PXI; - StackID = TargetStackID::ScalableVector; - } + else if (IsPNR || AArch64::PPRRegClass.hasSubClassEq(RC)) { + assert(Subtarget.hasSVEorSME() && + "Unexpected register load without SVE load instructions"); + assert((!IsPNR || Subtarget.hasSVE2p1() || Subtarget.hasSME2()) && + "Unexpected register load without SVE2p1 or SME2"); + if (IsPNR) + PNRReg = DestReg; + Opc = AArch64::LDR_PXI; + StackID = TargetStackID::ScalableVector; } break; + } case 4: if (AArch64::GPR32allRegClass.hasSubClassEq(RC)) { Opc = AArch64::LDRWui; diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 7aa8f6cd57557..c5dc2240cd976 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -6689,6 +6689,7 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_InvalidZPR_4b32: case Match_InvalidZPR_4b64: case Match_InvalidSVEPPRorPNRAnyReg: + case Match_InvalidSVEPPRorPNRBReg: case Match_InvalidSVEPredicateAnyReg: case Match_InvalidSVEPattern: case Match_InvalidSVEVecLenSpecifier: @@ -6750,7 +6751,6 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_InvalidSVEVectorListStrided4x16: case Match_InvalidSVEVectorListStrided4x32: case Match_InvalidSVEVectorListStrided4x64: - case Match_InvalidSVEPPRorPNRBReg: case Match_MSR: case Match_MRS: { if (ErrorInfo >= Operands.size())