mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
After 3-addressifying a two-address instruction, update the register maps; add a missing check when considering whether it's profitable to commute. rdar://8977508.
llvm-svn: 125259
This commit is contained in:
parent
c86930fa03
commit
5a42a6a20f
@ -110,7 +110,7 @@ namespace {
|
||||
bool ConvertInstTo3Addr(MachineBasicBlock::iterator &mi,
|
||||
MachineBasicBlock::iterator &nmi,
|
||||
MachineFunction::iterator &mbbi,
|
||||
unsigned RegB, unsigned Dist);
|
||||
unsigned RegA, unsigned RegB, unsigned Dist);
|
||||
|
||||
typedef std::pair<std::pair<unsigned, bool>, MachineInstr*> NewKill;
|
||||
bool canUpdateDeletedKills(SmallVector<unsigned, 4> &Kills,
|
||||
@ -550,7 +550,7 @@ TwoAddressInstructionPass::isProfitableToCommute(unsigned regB, unsigned regC,
|
||||
unsigned FromRegC = getMappedReg(regC, SrcRegMap);
|
||||
unsigned ToRegB = getMappedReg(regB, DstRegMap);
|
||||
unsigned ToRegC = getMappedReg(regC, DstRegMap);
|
||||
if (!regsAreCompatible(FromRegB, ToRegB, TRI) &&
|
||||
if ((FromRegB && ToRegB && !regsAreCompatible(FromRegB, ToRegB, TRI)) &&
|
||||
((!FromRegC && !ToRegC) ||
|
||||
regsAreCompatible(FromRegB, ToRegC, TRI) ||
|
||||
regsAreCompatible(FromRegC, ToRegB, TRI)))
|
||||
@ -633,7 +633,8 @@ bool
|
||||
TwoAddressInstructionPass::ConvertInstTo3Addr(MachineBasicBlock::iterator &mi,
|
||||
MachineBasicBlock::iterator &nmi,
|
||||
MachineFunction::iterator &mbbi,
|
||||
unsigned RegB, unsigned Dist) {
|
||||
unsigned RegA, unsigned RegB,
|
||||
unsigned Dist) {
|
||||
MachineInstr *NewMI = TII->convertToThreeAddress(mbbi, mi, LV);
|
||||
if (NewMI) {
|
||||
DEBUG(dbgs() << "2addr: CONVERTING 2-ADDR: " << *mi);
|
||||
@ -653,6 +654,10 @@ TwoAddressInstructionPass::ConvertInstTo3Addr(MachineBasicBlock::iterator &mi,
|
||||
mi = NewMI;
|
||||
nmi = llvm::next(mi);
|
||||
}
|
||||
|
||||
// Update source and destination register maps.
|
||||
SrcRegMap.erase(RegA);
|
||||
DstRegMap.erase(RegB);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -887,7 +892,7 @@ TryInstructionTransform(MachineBasicBlock::iterator &mi,
|
||||
// three-address instruction. Check if it is profitable.
|
||||
if (!regBKilled || isProfitableToConv3Addr(regA)) {
|
||||
// Try to convert it.
|
||||
if (ConvertInstTo3Addr(mi, nmi, mbbi, regB, Dist)) {
|
||||
if (ConvertInstTo3Addr(mi, nmi, mbbi, regA, regB, Dist)) {
|
||||
++NumConvertedTo3Addr;
|
||||
return true; // Done with this instruction.
|
||||
}
|
||||
|
@ -5,20 +5,32 @@
|
||||
;; allocator turns the shift into an LEA. This also occurs for ADD.
|
||||
|
||||
; Check that the shift gets turned into an LEA.
|
||||
; RUN: llc < %s -march=x86 -x86-asm-syntax=intel | \
|
||||
; RUN: not grep {mov E.X, E.X}
|
||||
; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s
|
||||
|
||||
@G = external global i32 ; <i32*> [#uses=3]
|
||||
@G = external global i32
|
||||
|
||||
define i32 @test1(i32 %X, i32 %Y) {
|
||||
%Z = add i32 %X, %Y ; <i32> [#uses=1]
|
||||
volatile store i32 %Y, i32* @G
|
||||
define i32 @test1(i32 %X) nounwind {
|
||||
; CHECK: test1:
|
||||
; CHECK-NOT: mov
|
||||
; CHECK: leal 1(%rdi)
|
||||
%Z = add i32 %X, 1
|
||||
volatile store i32 %Z, i32* @G
|
||||
ret i32 %X
|
||||
}
|
||||
|
||||
define i32 @test2(i32 %X) {
|
||||
%Z = add i32 %X, 1 ; <i32> [#uses=1]
|
||||
volatile store i32 %Z, i32* @G
|
||||
ret i32 %X
|
||||
; rdar://8977508
|
||||
; The second add should not be transformed to leal nor should it be
|
||||
; commutted (which would require inserting a copy).
|
||||
define i32 @test2(i32 inreg %a, i32 inreg %b, i32 %c, i32 %d) nounwind {
|
||||
entry:
|
||||
; CHECK: test2:
|
||||
; CHECK: leal
|
||||
; CHECK-NOT: leal
|
||||
; CHECK-NOT: mov
|
||||
; CHECK-NEXT: addl
|
||||
; CHECK-NEXT: ret
|
||||
%add = add i32 %b, %a
|
||||
%add3 = add i32 %add, %c
|
||||
%add5 = add i32 %add3, %d
|
||||
ret i32 %add5
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user