-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[SystemZ] Replace SELRMux with COPY in case of identical operands. #125108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-backend-systemz Author: Jonas Paulsson (JonPsson1) ChangesIf both operands of a SELRMux use the same register which is killed, and the SELRMux is expanded to a jump Early IfConvert =>
Machine Common Subexpression Elimination =>
Regalloc =>
SystemZ Post Rewrite => // Broken: First COPY kills $r1, but is still live into and used in successor block.
Machine Copy Propagation => // Acts on the kill flag with wrong-code resulting:
This is the same test case as first reported with #124542 and then #124768 with suspicions that turned out to be false. @dominik-steenken Full diff: https://github.com/llvm/llvm-project/pull/125108.diff 2 Files Affected:
diff --git a/llvm/lib/Target/SystemZ/SystemZPostRewrite.cpp b/llvm/lib/Target/SystemZ/SystemZPostRewrite.cpp
index e15f9027cc20956..6b6ec5b6b9dc81e 100644
--- a/llvm/lib/Target/SystemZ/SystemZPostRewrite.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZPostRewrite.cpp
@@ -107,6 +107,18 @@ void SystemZPostRewrite::selectSELRMux(MachineBasicBlock &MBB,
bool Src1IsHigh = SystemZ::isHighReg(Src1Reg);
bool Src2IsHigh = SystemZ::isHighReg(Src2Reg);
+ // In rare cases both sources are the same register (after
+ // machine-cse). This must be handled as it may lead to wrong-code (after
+ // machine-cp) if the kill flag on Src1 isn't cleared (with
+ // expandCondMove()).
+ if (Src1Reg == Src2Reg) {
+ BuildMI(*MBBI->getParent(), MBBI, MBBI->getDebugLoc(),
+ TII->get(SystemZ::COPY), DestReg)
+ .addReg(MBBI->getOperand(1).getReg(), getRegState(MBBI->getOperand(1)));
+ MBBI->eraseFromParent();
+ return;
+ }
+
// If sources and destination aren't all high or all low, we may be able to
// simplify the operation by moving one of the sources to the destination
// first. But only if this doesn't clobber the other source.
diff --git a/llvm/test/CodeGen/SystemZ/cond-move-10.mir b/llvm/test/CodeGen/SystemZ/cond-move-10.mir
new file mode 100644
index 000000000000000..1db960829729eab
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/cond-move-10.mir
@@ -0,0 +1,21 @@
+# RUN: llc -o - %s -mtriple=s390x-linux-gnu -mcpu=z15 -run-pass=systemz-post-rewrite \
+# RUN: 2>&1 | FileCheck %s
+
+# The SELRMux has two identical sources - replace with a copy instruction.
+# CHECK: name: fun0
+# CHECK: renamable $r1l = AHIMuxK killed renamable $r1l, -1, implicit-def dead $cc
+# CHECK-NEXT: CHIMux renamable $r5h, 9, implicit-def $cc
+# CHECK-NEXT: $r14h = COPY killed renamable $r1l
+---
+name: fun0
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $r1l, $r5h
+ renamable $r1l = AHIMuxK killed renamable $r1l, -1, implicit-def dead $cc
+ CHIMux renamable $r5h, 9, implicit-def $cc
+ renamable $r14h = SELRMux killed renamable $r1l, renamable $r1l, 14, 8, implicit $cc
+ $r14l = COPY killed renamable $r14h
+ $r14d = LGFR $r14l
+ Return implicit $r14d
+...
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh, interesting case. Would be good to fix the formatting issue, otherwise LGTM.
/cherry-pick eb1a571 |
/pull-request #125236 |
…lvm#125108) If both operands of a SELRMux use the same register which is killed, and the SELRMux is expanded to a jump sequence, a broken MIR results if the kill flag is not removed. This patch replaces the SELRMux with a COPY in these cases. (cherry picked from commit eb1a571)
If both operands of a SELRMux use the same register which is killed, and the SELRMux is expanded to a jump
sequence, a broken MIR results if the kill flag is not removed. In the CSmith test case, it happened like this:
Early IfConvert =>
Machine Common Subexpression Elimination =>
Regalloc =>
SystemZ Post Rewrite => // Broken: First COPY kills $r1, but is still live into and used in successor block.
Machine Copy Propagation => // Acts on the kill flag with wrong-code resulting:
This is the same test case as first reported with #124542 and then #124768 with suspicions that turned out to be false.
@dominik-steenken