Skip to content

Commit 8a5858c

Browse files
author
Kai Luo
committed
[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
1 parent ed956b4 commit 8a5858c

File tree

2 files changed

+61
-13
lines changed

2 files changed

+61
-13
lines changed

llvm/lib/CodeGen/TwoAddressInstructionPass.cpp

+14-13
Original file line numberDiff line numberDiff line change
@@ -936,10 +936,10 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi,
936936
if (!KillMI->isSafeToMove(AA, SeenStore))
937937
return false;
938938

939-
SmallSet<unsigned, 2> Uses;
940-
SmallSet<unsigned, 2> Kills;
941-
SmallSet<unsigned, 2> Defs;
942-
SmallSet<unsigned, 2> LiveDefs;
939+
SmallVector<unsigned, 2> Uses;
940+
SmallVector<unsigned, 2> Kills;
941+
SmallVector<unsigned, 2> Defs;
942+
SmallVector<unsigned, 2> LiveDefs;
943943
for (const MachineOperand &MO : KillMI->operands()) {
944944
if (!MO.isReg())
945945
continue;
@@ -952,13 +952,13 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi,
952952
bool isKill = MO.isKill() || (LIS && isPlainlyKilled(KillMI, MOReg, LIS));
953953
if (MOReg == Reg && !isKill)
954954
return false;
955-
Uses.insert(MOReg);
955+
Uses.push_back(MOReg);
956956
if (isKill && MOReg != Reg)
957-
Kills.insert(MOReg);
957+
Kills.push_back(MOReg);
958958
} else if (Register::isPhysicalRegister(MOReg)) {
959-
Defs.insert(MOReg);
959+
Defs.push_back(MOReg);
960960
if (!MO.isDead())
961-
LiveDefs.insert(MOReg);
961+
LiveDefs.push_back(MOReg);
962962
}
963963
}
964964

@@ -984,11 +984,11 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi,
984984
if (!MOReg)
985985
continue;
986986
if (MO.isUse()) {
987-
if (Defs.count(MOReg))
987+
if (regOverlapsSet(Defs, MOReg, TRI))
988988
// Moving KillMI can clobber the physical register if the def has
989989
// not been seen.
990990
return false;
991-
if (Kills.count(MOReg))
991+
if (regOverlapsSet(Kills, MOReg, TRI))
992992
// Don't want to extend other live ranges and update kills.
993993
return false;
994994
if (&OtherMI != MI && MOReg == Reg &&
@@ -1002,12 +1002,13 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi,
10021002

10031003
for (unsigned i = 0, e = OtherDefs.size(); i != e; ++i) {
10041004
unsigned MOReg = OtherDefs[i];
1005-
if (Uses.count(MOReg))
1005+
if (regOverlapsSet(Uses, MOReg, TRI))
10061006
return false;
1007-
if (Register::isPhysicalRegister(MOReg) && LiveDefs.count(MOReg))
1007+
if (Register::isPhysicalRegister(MOReg) &&
1008+
regOverlapsSet(LiveDefs, MOReg, TRI))
10081009
return false;
10091010
// Physical register def is seen.
1010-
Defs.erase(MOReg);
1011+
Defs.erase(std::remove(Defs.begin(), Defs.end(), MOReg), Defs.end());
10111012
}
10121013
}
10131014

llvm/test/CodeGen/PowerPC/pr47707.ll

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -simplify-mir -verify-machineinstrs < %s | FileCheck %s
3+
4+
target datalayout = "e-m:e-i64:64-n32:64"
5+
target triple = "powerpc64le-grtev4-linux-gnu"
6+
7+
define void @foo(i64* %p1, i64 %v1, i8 %v2, i64 %v3) {
8+
; CHECK-LABEL: foo:
9+
; CHECK: # %bb.0:
10+
; CHECK-NEXT: mr 7, 5
11+
; CHECK-NEXT: rldimi. 7, 4, 8, 0
12+
; CHECK-NEXT: mcrf 1, 0
13+
; CHECK-NEXT: andi. 5, 5, 1
14+
; CHECK-NEXT: li 5, 0
15+
; CHECK-NEXT: std 5, 0(3)
16+
; CHECK-NEXT: crnot 20, 6
17+
; CHECK-NEXT: bc 4, 1, .LBB0_2
18+
; CHECK-NEXT: # %bb.1: # %bb1
19+
; CHECK-NEXT: std 4, 0(3)
20+
; CHECK-NEXT: .LBB0_2: # %bb2
21+
; CHECK-NEXT: bclr 12, 20, 0
22+
; CHECK-NEXT: # %bb.3: # %bb3
23+
; CHECK-NEXT: std 6, 0(3)
24+
; CHECK-NEXT: blr
25+
store i64 0, i64* %p1, align 8
26+
%ext = zext i8 %v2 to i64
27+
%shift = shl nuw i64 %v1, 8
28+
%merge = or i64 %shift, %ext
29+
%not0 = icmp ne i64 %merge, 0
30+
%bit0 = and i64 %ext, 1 ; and & icmp instructions can be combined
31+
%cond1 = icmp eq i64 %bit0, 0 ; to and. and generates condition code to
32+
br i1 %cond1, label %bb2, label %bb1 ; be used by this conditional branch
33+
34+
bb1:
35+
store i64 %v1, i64* %p1, align 8
36+
br label %bb2
37+
38+
bb2:
39+
br i1 %not0, label %exit, label %bb3
40+
41+
bb3:
42+
store i64 %v3, i64* %p1, align 8
43+
br label %exit
44+
45+
exit:
46+
ret void
47+
}

0 commit comments

Comments
 (0)