[llvm] [AArch64][SVE] Support copy of PPR2 register class in copyPhysReg (PR #216303)

Kerry McLaughlin via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 14 04:07:07 PDT 2026


https://github.com/kmclaughlin-arm created https://github.com/llvm/llvm-project/pull/216303

This fixes the following crash, which was observed after landing #209484:
https://clang.godbolt.org/z/YG1r63oT3

>From 851e31fe65b7cf140b5657edc1ab231ea3e9d132 Mon Sep 17 00:00:00 2001
From: Kerry McLaughlin <kerry.mclaughlin at arm.com>
Date: Fri, 14 Aug 2026 10:50:01 +0000
Subject: [PATCH] [AArch64][SVE] Support copy of PPR2 register class in
 copyPhysReg.

This fixes the following crash, which was observed after landing #209484:
https://github.com/llvm/llvm-project/pull/209484
---
 llvm/lib/Target/AArch64/AArch64InstrInfo.cpp  | 12 ++++++++++
 .../test/CodeGen/AArch64/sve-copy-pprpair.mir | 24 +++++++++++++++++++
 2 files changed, 36 insertions(+)
 create mode 100644 llvm/test/CodeGen/AArch64/sve-copy-pprpair.mir

diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index 9e128651598f3..1502724ffa713 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -5771,6 +5771,8 @@ void AArch64InstrInfo::copyPhysRegTuple(MachineBasicBlock &MBB,
     const MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opcode));
     AddSubReg(MIB, DestReg, Indices[SubReg], RegState::Define, TRI);
     AddSubReg(MIB, SrcReg, Indices[SubReg], {}, TRI);
+    if (Opcode == AArch64::ORR_PPzPP)
+      AddSubReg(MIB, SrcReg, Indices[SubReg], {}, TRI);
     AddSubReg(MIB, SrcReg, Indices[SubReg], getKillRegState(KillSrc), TRI);
   }
 }
@@ -5991,6 +5993,16 @@ void AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
     return;
   }
 
+  if (AArch64::PPR2RegClass.contains(DestReg) &&
+      AArch64::PPR2RegClass.contains(SrcReg)) {
+    assert(Subtarget.isSVEorStreamingSVEAvailable() &&
+           "Unexpected SVE predicate register.");
+    static const unsigned Indices[] = {AArch64::psub0, AArch64::psub1};
+    copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORR_PPzPP,
+                     Indices);
+    return;
+  }
+
   // Copy a Z register by ORRing with itself.
   if (AArch64::ZPRRegClass.contains(DestReg) &&
       AArch64::ZPRRegClass.contains(SrcReg)) {
diff --git a/llvm/test/CodeGen/AArch64/sve-copy-pprpair.mir b/llvm/test/CodeGen/AArch64/sve-copy-pprpair.mir
new file mode 100644
index 0000000000000..336886f699b49
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/sve-copy-pprpair.mir
@@ -0,0 +1,24 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve -run-pass=postrapseudos -simplify-mir -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name:            copy_ppr2
+alignment:       4
+tracksRegLiveness: true
+liveins:
+  - { reg: '$p0_p1' }
+frameInfo:
+  maxCallFrameSize: 0
+body:             |
+  bb.0:
+    liveins: $p0_p1
+    ; CHECK-LABEL: name: copy_ppr2
+    ; CHECK: liveins: $p0_p1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: $p2 = ORR_PPzPP $p0, $p0, killed $p0
+    ; CHECK-NEXT: $p3 = ORR_PPzPP $p1, $p1, killed $p1
+    ; CHECK-NEXT: RET_ReallyLR
+    $p2_p3 = COPY killed renamable $p0_p1
+    RET_ReallyLR
+
+...



More information about the llvm-commits mailing list