[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