Skip to content

Commit 29f6f9b

Browse files
author
czhengsz
committed
[PowerPC] combine rlwinm+rlwinm to rlwinm
combine x3 = rlwinm x3, 27, 5, 31 x3 = rlwinm x3, 19, 0, 12 to x3 = rlwinm x3, 14, 0, 12 Reviewed by: steven.zhang Differential Revision: https://reviews.llvm.org/D70374
1 parent 085d784 commit 29f6f9b

File tree

3 files changed

+215
-6
lines changed

3 files changed

+215
-6
lines changed

llvm/lib/Target/PowerPC/PPCMIPeephole.cpp

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
//
1919
//===---------------------------------------------------------------------===//
2020

21+
#include "MCTargetDesc/PPCMCTargetDesc.h"
2122
#include "MCTargetDesc/PPCPredicates.h"
2223
#include "PPC.h"
2324
#include "PPCInstrBuilder.h"
@@ -806,6 +807,105 @@ bool PPCMIPeephole::simplifyCode(void) {
806807
combineSEXTAndSHL(MI, ToErase);
807808
break;
808809
}
810+
case PPC::RLWINM:
811+
case PPC::RLWINMo:
812+
case PPC::RLWINM8:
813+
case PPC::RLWINM8o: {
814+
unsigned FoldingReg = MI.getOperand(1).getReg();
815+
if (!Register::isVirtualRegister(FoldingReg))
816+
break;
817+
818+
MachineInstr *SrcMI = MRI->getVRegDef(FoldingReg);
819+
if (SrcMI->getOpcode() != PPC::RLWINM &&
820+
SrcMI->getOpcode() != PPC::RLWINMo &&
821+
SrcMI->getOpcode() != PPC::RLWINM8 &&
822+
SrcMI->getOpcode() != PPC::RLWINM8o)
823+
break;
824+
assert((MI.getOperand(2).isImm() && MI.getOperand(3).isImm() &&
825+
MI.getOperand(4).isImm() && SrcMI->getOperand(2).isImm() &&
826+
SrcMI->getOperand(3).isImm() && SrcMI->getOperand(4).isImm()) &&
827+
"Invalid PPC::RLWINM Instruction!");
828+
uint64_t SHSrc = SrcMI->getOperand(2).getImm();
829+
uint64_t SHMI = MI.getOperand(2).getImm();
830+
uint64_t MBSrc = SrcMI->getOperand(3).getImm();
831+
uint64_t MBMI = MI.getOperand(3).getImm();
832+
uint64_t MESrc = SrcMI->getOperand(4).getImm();
833+
uint64_t MEMI = MI.getOperand(4).getImm();
834+
835+
assert((MEMI < 32 && MESrc < 32 && MBMI < 32 && MBSrc < 32) &&
836+
"Invalid PPC::RLWINM Instruction!");
837+
838+
APInt MaskSrc =
839+
APInt::getBitsSetWithWrap(32, 32 - MESrc - 1, 32 - MBSrc);
840+
APInt MaskMI = APInt::getBitsSetWithWrap(32, 32 - MEMI - 1, 32 - MBMI);
841+
842+
APInt RotatedSrcMask = MaskSrc.rotl(SHMI);
843+
APInt FinalMask = RotatedSrcMask & MaskMI;
844+
uint32_t NewMB, NewME;
845+
846+
// If final mask is 0, MI result should be 0 too.
847+
if (FinalMask.isNullValue()) {
848+
bool Is64Bit = (MI.getOpcode() == PPC::RLWINM8 ||
849+
MI.getOpcode() == PPC::RLWINM8o);
850+
851+
LLVM_DEBUG(dbgs() << "Replace Instr: ");
852+
LLVM_DEBUG(MI.dump());
853+
854+
if (MI.getOpcode() == PPC::RLWINM || MI.getOpcode() == PPC::RLWINM8) {
855+
// Replace MI with "LI 0"
856+
MI.RemoveOperand(4);
857+
MI.RemoveOperand(3);
858+
MI.RemoveOperand(2);
859+
MI.getOperand(1).ChangeToImmediate(0);
860+
MI.setDesc(TII->get(Is64Bit ? PPC::LI8 : PPC::LI));
861+
} else {
862+
// Replace MI with "ANDIo reg, 0"
863+
MI.RemoveOperand(4);
864+
MI.RemoveOperand(3);
865+
MI.getOperand(2).setImm(0);
866+
MI.setDesc(TII->get(Is64Bit ? PPC::ANDIo8 : PPC::ANDIo));
867+
}
868+
Simplified = true;
869+
NumRotatesCollapsed++;
870+
871+
LLVM_DEBUG(dbgs() << "With: ");
872+
LLVM_DEBUG(MI.dump());
873+
} else if (isRunOfOnes((unsigned)(FinalMask.getZExtValue()), NewMB,
874+
NewME)) {
875+
876+
// If FoldingReg has only one use and it it not RLWINMo and
877+
// RLWINM8o, safe to delete its def SrcMI. Otherwise keep it.
878+
if (MRI->hasOneNonDBGUse(FoldingReg) &&
879+
(SrcMI->getOpcode() == PPC::RLWINM ||
880+
SrcMI->getOpcode() == PPC::RLWINM8)) {
881+
ToErase = SrcMI;
882+
LLVM_DEBUG(dbgs() << "Delete dead instruction: ");
883+
LLVM_DEBUG(SrcMI->dump());
884+
}
885+
886+
LLVM_DEBUG(dbgs() << "Converting Instr: ");
887+
LLVM_DEBUG(MI.dump());
888+
889+
uint16_t NewSH = (SHSrc + SHMI) % 32;
890+
MI.getOperand(2).setImm(NewSH);
891+
MI.getOperand(3).setImm(NewMB);
892+
MI.getOperand(4).setImm(NewME);
893+
MI.getOperand(1).setReg(SrcMI->getOperand(1).getReg());
894+
if (SrcMI->getOperand(1).isKill()) {
895+
MI.getOperand(1).setIsKill(true);
896+
SrcMI->getOperand(1).setIsKill(false);
897+
} else
898+
// About to replace MI.getOperand(1), clear its kill flag.
899+
MI.getOperand(1).setIsKill(false);
900+
901+
Simplified = true;
902+
NumRotatesCollapsed++;
903+
904+
LLVM_DEBUG(dbgs() << "To: ");
905+
LLVM_DEBUG(MI.dump());
906+
}
907+
break;
908+
}
809909
}
810910
}
811911

llvm/test/CodeGen/PowerPC/fold-rlwinm-1.ll

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ define void @foo(i32 signext %var1) {
1111
; CHECK-NEXT: xori r3, r3, 1
1212
; CHECK-NEXT: addis r4, r2, res@toc@ha
1313
; CHECK-NEXT: cntlzw r3, r3
14-
; CHECK-NEXT: srwi r3, r3, 5
15-
; CHECK-NEXT: slwi r3, r3, 19
14+
; CHECK-NEXT: rlwinm r3, r3, 14, 0, 12
1615
; CHECK-NEXT: stw r3, res@toc@l(r4)
1716
; CHECK-NEXT: blr
1817
entry:
@@ -30,10 +29,10 @@ define void @foo_multiple_use(i32 signext %var1) {
3029
; CHECK-NEXT: addis r4, r2, res2@toc@ha
3130
; CHECK-NEXT: addis r6, r2, res@toc@ha
3231
; CHECK-NEXT: cntlzw r3, r3
33-
; CHECK-NEXT: srwi r3, r3, 5
34-
; CHECK-NEXT: slwi r5, r3, 19
35-
; CHECK-NEXT: stw r3, res2@toc@l(r4)
36-
; CHECK-NEXT: stw r5, res@toc@l(r6)
32+
; CHECK-NEXT: srwi r5, r3, 5
33+
; CHECK-NEXT: rlwinm r3, r3, 14, 0, 12
34+
; CHECK-NEXT: stw r5, res2@toc@l(r4)
35+
; CHECK-NEXT: stw r3, res@toc@l(r6)
3736
; CHECK-NEXT: blr
3837
entry:
3938
%cmp = icmp eq i32 %var1, 1
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# RUN: llc -ppc-asm-full-reg-names -mtriple=powerpc64le-unknown-linux-gnu \
2+
# RUN: -run-pass ppc-mi-peepholes %s -o - -verify-machineinstrs | FileCheck %s
3+
4+
---
5+
name: testFoldRLWINM
6+
#CHECK : name : testFoldRLWINM
7+
tracksRegLiveness: true
8+
body: |
9+
bb.0.entry:
10+
liveins: $x3
11+
%0:g8rc = COPY $x3
12+
%1:gprc = COPY %0.sub_32:g8rc
13+
%2:gprc = RLWINM %1:gprc, 27, 5, 31
14+
; CHECK-NOT: %2:gprc = RLWINM %1:gprc, 27, 5, 31
15+
%3:gprc = RLWINM %2:gprc, 19, 0, 12
16+
; CHECK: %3:gprc = RLWINM %1, 14, 0, 12
17+
BLR8 implicit $lr8, implicit $rm
18+
...
19+
---
20+
name: testFoldRLWINMSrcWrapped
21+
#CHECK : name : testFoldRLWINMSrcWrapped
22+
tracksRegLiveness: true
23+
body: |
24+
bb.0.entry:
25+
liveins: $x3
26+
%0:g8rc = COPY $x3
27+
%1:gprc = COPY %0.sub_32:g8rc
28+
%2:gprc = RLWINM %1:gprc, 27, 30, 10
29+
; CHECK-NOT: %2:gprc = RLWINM %1:gprc, 27, 30 ,10
30+
%3:gprc = RLWINM %2:gprc, 19, 0, 12
31+
; CHECK: %3:gprc = RLWINM %1, 14, 11, 12
32+
BLR8 implicit $lr8, implicit $rm
33+
...
34+
---
35+
name: testFoldRLWINMUserWrapped
36+
#CHECK : name : testFoldRLWINMUserWrapped
37+
tracksRegLiveness: true
38+
body: |
39+
bb.0.entry:
40+
liveins: $x3
41+
%0:g8rc = COPY $x3
42+
%1:gprc = COPY %0.sub_32:g8rc
43+
%2:gprc = RLWINM %1:gprc, 10, 5, 31
44+
; CHECK-NOT: %2:gprc = RLWINM %1:gprc, 10, 5, 31
45+
%3:gprc = RLWINM %2:gprc, 10, 30, 5
46+
; CHECK: %3:gprc = RLWINM %1, 20, 30, 5
47+
BLR8 implicit $lr8, implicit $rm
48+
...
49+
---
50+
name: testFoldRLWINMMultipleUses
51+
#CHECK : name : testFoldRLWINMMultipleUses
52+
tracksRegLiveness: true
53+
body: |
54+
bb.0.entry:
55+
liveins: $x3
56+
%0:g8rc = COPY $x3
57+
%1:gprc = COPY %0.sub_32:g8rc
58+
%2:gprc = RLWINM killed %1:gprc, 27, 5, 31
59+
; CHECK: %2:gprc = RLWINM %1, 27, 5, 31
60+
%3:gprc = RLWINM %2:gprc, 19, 0, 12
61+
; CHECK: %3:gprc = RLWINM killed %1, 14, 0, 12
62+
STW %3:gprc, %2:gprc, 100
63+
; CHECK: STW %3, %2, 100
64+
BLR8 implicit $lr8, implicit $rm
65+
...
66+
---
67+
name: testFoldRLWINMToZero
68+
#CHECK : name : testFoldRLWINMToZero
69+
tracksRegLiveness: true
70+
body: |
71+
bb.0.entry:
72+
liveins: $x3
73+
%0:g8rc = COPY $x3
74+
%1:gprc = COPY %0.sub_32:g8rc
75+
%2:gprc = RLWINM %1:gprc, 27, 5, 10
76+
; CHECK-NOT: %2:gprc = RLWINM %1:gprc, 27, 5, 10
77+
%3:gprc = RLWINM %2:gprc, 8, 5, 10
78+
; CHECK: %3:gprc = LI 0
79+
BLR8 implicit $lr8, implicit $rm
80+
...
81+
---
82+
name: testFoldRLWINMoToZero
83+
#CHECK : name : testFoldRLWINMoToZero
84+
tracksRegLiveness: true
85+
body: |
86+
bb.0.entry:
87+
liveins: $x3
88+
%0:g8rc = COPY $x3
89+
%1:gprc = COPY %0.sub_32:g8rc
90+
%2:gprc = RLWINM %1:gprc, 27, 5, 10
91+
; CHECK-NOT: %2:gprc = RLWINM %1:gprc, 27, 5, 10
92+
%3:gprc = RLWINMo %2:gprc, 8, 5, 10, implicit-def $cr0
93+
; CHECK: %3:gprc = ANDIo %2, 0, implicit-def $cr0
94+
BLR8 implicit $lr8, implicit $rm
95+
...
96+
---
97+
name: testFoldRLWINMInvalidMask
98+
#CHECK : name : testFoldRLWINMInvalidMask
99+
tracksRegLiveness: true
100+
body: |
101+
bb.0.entry:
102+
liveins: $x3
103+
%0:g8rc = COPY $x3
104+
%1:gprc = COPY %0.sub_32:g8rc
105+
%2:gprc = RLWINM %1:gprc, 20, 5, 31
106+
; CHECK: %2:gprc = RLWINM %1, 20, 5, 31
107+
%3:gprc = RLWINM %2:gprc, 19, 10, 20
108+
; CHECK: %3:gprc = RLWINM %2, 19, 10, 20
109+
BLR8 implicit $lr8, implicit $rm
110+
...

0 commit comments

Comments
 (0)