[llvm] [PowerPC] Fix Impossible reg-to-reg copy when inline asm uses crN registers as inputs (PR #196182)

via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 4 03:45:59 PDT 2026


https://github.com/chirizxc updated https://github.com/llvm/llvm-project/pull/196182

>From 3ecaa47f5f49f8a4f04356416cf0e9b2a00ed00d Mon Sep 17 00:00:00 2001
From: chiri <chirizxc at proton.me>
Date: Thu, 7 May 2026 00:03:56 +0300
Subject: [PATCH 1/3] fix 196085

---
 llvm/lib/Target/PowerPC/PPCInstrInfo.cpp | 31 ++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
index ff302862640ec..4ff266c7b6e00 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
@@ -1735,6 +1735,37 @@ void PPCInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
         .addImm(28)
         .addImm(31);
     return;
+  } else if (PPC::CRRCRegClass.contains(DestReg) &&
+             (PPC::G8RCRegClass.contains(SrcReg) ||
+              PPC::GPRCRegClass.contains(SrcReg))) {
+    bool Is64Bit = PPC::G8RCRegClass.contains(SrcReg);
+    unsigned MvCode = Is64Bit ? PPC::MTOCRF8 : PPC::MTOCRF;
+    unsigned ShCode = Is64Bit ? PPC::RLWINM8 : PPC::RLWINM;
+    unsigned CRNum = TRI->getEncodingValue(DestReg);
+    if (CRNum == 7) {
+      BuildMI(MBB, I, DL, get(MvCode), DestReg)
+          .addReg(SrcReg, getKillRegState(KillSrc));
+      return;
+    }
+    Register TmpReg = SrcReg;
+    RegState SrcKill = getKillRegState(KillSrc);
+    if (!KillSrc) {
+      RegScavenger RS;
+      RS.enterBasicBlockEnd(MBB);
+      RS.backward(std::next(I));
+      TmpReg = RS.scavengeRegisterBackwards(
+          Is64Bit ? PPC::G8RCRegClass : PPC::GPRCRegClass, I,
+          /* RestoreAfter */ false, 0, /* AllowSpill */ false);
+      assert(TmpReg && "No register left to scavenge!");
+      SrcKill = RegState::NoFlags;
+    }
+    BuildMI(MBB, I, DL, get(ShCode), TmpReg)
+        .addReg(SrcReg, SrcKill)
+        .addImm(32 - CRNum * 4 - 4)
+        .addImm(0)
+        .addImm(31);
+    BuildMI(MBB, I, DL, get(MvCode), DestReg).addReg(TmpReg, RegState::Kill);
+    return;
   } else if (PPC::G8RCRegClass.contains(SrcReg) &&
              PPC::VSFRCRegClass.contains(DestReg)) {
     assert(Subtarget.hasDirectMove() &&

>From 46465ce624b2a4b769872cb924146a49611d9d7a Mon Sep 17 00:00:00 2001
From: chiri <chirizxc at proton.me>
Date: Thu, 7 May 2026 00:08:34 +0300
Subject: [PATCH 2/3] add test

---
 .../CodeGen/PowerPC/inline-asm-cr-input.ll    | 38 +++++++++++++++++++
 1 file changed, 38 insertions(+)
 create mode 100644 llvm/test/CodeGen/PowerPC/inline-asm-cr-input.ll

diff --git a/llvm/test/CodeGen/PowerPC/inline-asm-cr-input.ll b/llvm/test/CodeGen/PowerPC/inline-asm-cr-input.ll
new file mode 100644
index 0000000000000..5541eb16bb26d
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/inline-asm-cr-input.ll
@@ -0,0 +1,38 @@
+; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-unknown-eabi < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-unknown < %s | FileCheck %s
+
+define i32 @cr0_input() {
+; CHECK-LABEL: cr0_input:
+; CHECK: {{mto?crf}} 128, {{[0-9]+}}
+; CHECK: #APP
+; CHECK-NEXT: rfi
+; CHECK-NEXT: #NO_APP
+entry:
+  %0 = call i32 asm sideeffect "rfi", "={r3},{r3},{cr0}"(i32 0, i1 false)
+  ret i32 %0
+}
+
+define i32 @cr1_input() {
+; CHECK-LABEL: cr1_input:
+; CHECK: li [[REG:[0-9]+]], 1
+; CHECK: rotlwi [[REG]], [[REG]], 24
+; CHECK: {{mto?crf}} 64, [[REG]]
+; CHECK: #APP
+; CHECK-NEXT: rfi
+; CHECK-NEXT: #NO_APP
+entry:
+  %0 = call i32 asm sideeffect "rfi", "={r3},{r3},{cr1}"(i32 0, i1 true)
+  ret i32 %0
+}
+
+define i32 @cr7_input() {
+; CHECK-LABEL: cr7_input:
+; CHECK: li [[REG:[0-9]+]], 1
+; CHECK: {{mto?crf}} 1, [[REG]]
+; CHECK: #APP
+; CHECK-NEXT: rfi
+; CHECK-NEXT: #NO_APP
+entry:
+  %0 = call i32 asm sideeffect "rfi", "={r3},{r3},{cr7}"(i32 0, i1 true)
+  ret i32 %0
+}

>From 8c97710e213fb417c88774e25fb67daf6163f4b7 Mon Sep 17 00:00:00 2001
From: chiri <chirizxc at proton.me>
Date: Tue, 4 Aug 2026 13:45:49 +0300
Subject: [PATCH 3/3] fix build

---
 llvm/lib/Target/PowerPC/PPCInstrInfo.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
index 79d1555987cbb..a73e32d67a00c 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
@@ -1735,7 +1735,7 @@ void PPCInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
     bool Is64Bit = PPC::G8RCRegClass.contains(SrcReg);
     unsigned MvCode = Is64Bit ? PPC::MTOCRF8 : PPC::MTOCRF;
     unsigned ShCode = Is64Bit ? PPC::RLWINM8 : PPC::RLWINM;
-    unsigned CRNum = TRI->getEncodingValue(DestReg);
+    unsigned CRNum = RI.getEncodingValue(DestReg);
     if (CRNum == 7) {
       BuildMI(MBB, I, DL, get(MvCode), DestReg)
           .addReg(SrcReg, getKillRegState(KillSrc));



More information about the llvm-commits mailing list