[llvm] 8a5858c - [TwoAddressInstruction][PowerPC] Call `regOverlapsSet` to find out real clobbers and uses
Kai Luo via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 8 19:35:01 PDT 2020
Author: Kai Luo
Date: 2020-10-09T02:34:54Z
New Revision: 8a5858c8fd50e6f5767a21854951c3ccba17e8c4
URL: https://github.com/llvm/llvm-project/commit/8a5858c8fd50e6f5767a21854951c3ccba17e8c4
DIFF: https://github.com/llvm/llvm-project/commit/8a5858c8fd50e6f5767a21854951c3ccba17e8c4.diff
LOG: [TwoAddressInstruction][PowerPC] Call `regOverlapsSet` to find out real clobbers and uses
In `rescheduleKillAboveMI`, current implementation uses `SmallSet` to track reg's defs and uses. When comparing, use `SmallSet.count` to find out if it's clobbered or used. It's not correct if involving subregisters. This patch uses `regOverlapsSet` already used by `rescheduleMIBelowKill` to fix the issue.
Fixed https://bugs.llvm.org/show_bug.cgi?id=47707.
Reviewed By: #powerpc, nemanjai
Differential Revision: https://reviews.llvm.org/D88716
Added:
llvm/test/CodeGen/PowerPC/pr47707.ll
Modified:
llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
index 615ff4b8789c..4a727902bdd2 100644
--- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
+++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
@@ -936,10 +936,10 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi,
if (!KillMI->isSafeToMove(AA, SeenStore))
return false;
- SmallSet<unsigned, 2> Uses;
- SmallSet<unsigned, 2> Kills;
- SmallSet<unsigned, 2> Defs;
- SmallSet<unsigned, 2> LiveDefs;
+ SmallVector<unsigned, 2> Uses;
+ SmallVector<unsigned, 2> Kills;
+ SmallVector<unsigned, 2> Defs;
+ SmallVector<unsigned, 2> LiveDefs;
for (const MachineOperand &MO : KillMI->operands()) {
if (!MO.isReg())
continue;
@@ -952,13 +952,13 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi,
bool isKill = MO.isKill() || (LIS && isPlainlyKilled(KillMI, MOReg, LIS));
if (MOReg == Reg && !isKill)
return false;
- Uses.insert(MOReg);
+ Uses.push_back(MOReg);
if (isKill && MOReg != Reg)
- Kills.insert(MOReg);
+ Kills.push_back(MOReg);
} else if (Register::isPhysicalRegister(MOReg)) {
- Defs.insert(MOReg);
+ Defs.push_back(MOReg);
if (!MO.isDead())
- LiveDefs.insert(MOReg);
+ LiveDefs.push_back(MOReg);
}
}
@@ -984,11 +984,11 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi,
if (!MOReg)
continue;
if (MO.isUse()) {
- if (Defs.count(MOReg))
+ if (regOverlapsSet(Defs, MOReg, TRI))
// Moving KillMI can clobber the physical register if the def has
// not been seen.
return false;
- if (Kills.count(MOReg))
+ if (regOverlapsSet(Kills, MOReg, TRI))
// Don't want to extend other live ranges and update kills.
return false;
if (&OtherMI != MI && MOReg == Reg &&
@@ -1002,12 +1002,13 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi,
for (unsigned i = 0, e = OtherDefs.size(); i != e; ++i) {
unsigned MOReg = OtherDefs[i];
- if (Uses.count(MOReg))
+ if (regOverlapsSet(Uses, MOReg, TRI))
return false;
- if (Register::isPhysicalRegister(MOReg) && LiveDefs.count(MOReg))
+ if (Register::isPhysicalRegister(MOReg) &&
+ regOverlapsSet(LiveDefs, MOReg, TRI))
return false;
// Physical register def is seen.
- Defs.erase(MOReg);
+ Defs.erase(std::remove(Defs.begin(), Defs.end(), MOReg), Defs.end());
}
}
diff --git a/llvm/test/CodeGen/PowerPC/pr47707.ll b/llvm/test/CodeGen/PowerPC/pr47707.ll
new file mode 100644
index 000000000000..099fcf10d994
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/pr47707.ll
@@ -0,0 +1,47 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -simplify-mir -verify-machineinstrs < %s | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-n32:64"
+target triple = "powerpc64le-grtev4-linux-gnu"
+
+define void @foo(i64* %p1, i64 %v1, i8 %v2, i64 %v3) {
+; CHECK-LABEL: foo:
+; CHECK: # %bb.0:
+; CHECK-NEXT: mr 7, 5
+; CHECK-NEXT: rldimi. 7, 4, 8, 0
+; CHECK-NEXT: mcrf 1, 0
+; CHECK-NEXT: andi. 5, 5, 1
+; CHECK-NEXT: li 5, 0
+; CHECK-NEXT: std 5, 0(3)
+; CHECK-NEXT: crnot 20, 6
+; CHECK-NEXT: bc 4, 1, .LBB0_2
+; CHECK-NEXT: # %bb.1: # %bb1
+; CHECK-NEXT: std 4, 0(3)
+; CHECK-NEXT: .LBB0_2: # %bb2
+; CHECK-NEXT: bclr 12, 20, 0
+; CHECK-NEXT: # %bb.3: # %bb3
+; CHECK-NEXT: std 6, 0(3)
+; CHECK-NEXT: blr
+ store i64 0, i64* %p1, align 8
+ %ext = zext i8 %v2 to i64
+ %shift = shl nuw i64 %v1, 8
+ %merge = or i64 %shift, %ext
+ %not0 = icmp ne i64 %merge, 0
+ %bit0 = and i64 %ext, 1 ; and & icmp instructions can be combined
+ %cond1 = icmp eq i64 %bit0, 0 ; to and. and generates condition code to
+ br i1 %cond1, label %bb2, label %bb1 ; be used by this conditional branch
+
+bb1:
+ store i64 %v1, i64* %p1, align 8
+ br label %bb2
+
+bb2:
+ br i1 %not0, label %exit, label %bb3
+
+bb3:
+ store i64 %v3, i64* %p1, align 8
+ br label %exit
+
+exit:
+ ret void
+}
More information about the llvm-commits
mailing list