Skip to content

Commit

Permalink
[PowerPC] Do not emit record-form rotates when record-form andi/andis…
Browse files Browse the repository at this point in the history
… suffices

This is a follow-up to the previous patch that eliminated some of the rotates.
With this addition, we will also emit the record-form andis.

This patch increases the number of record-form rotates we eliminate by
more than 70%.

Differential revision: https://reviews.llvm.org/D44897

llvm-svn: 342478
  • Loading branch information
nemanjai committed Sep 18, 2018
1 parent 5e1c0e7 commit 87c31a6
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 28 deletions.
34 changes: 28 additions & 6 deletions llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
Expand Up @@ -1913,14 +1913,36 @@ bool PPCInstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg,
// compare).

// Rotates are expensive instructions. If we're emitting a record-form
// rotate that can just be an andi, we should just emit the andi.
if ((MIOpC == PPC::RLWINM || MIOpC == PPC::RLWINM8) &&
MI->getOperand(2).getImm() == 0) {
// rotate that can just be an andi/andis, we should just emit that.
if (MIOpC == PPC::RLWINM || MIOpC == PPC::RLWINM8) {
unsigned GPRRes = MI->getOperand(0).getReg();
int64_t SH = MI->getOperand(2).getImm();
int64_t MB = MI->getOperand(3).getImm();
int64_t ME = MI->getOperand(4).getImm();
if (MB < ME && MB >= 16) {
uint64_t Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1);
NewOpC = MIOpC == PPC::RLWINM ? PPC::ANDIo : PPC::ANDIo8;
// We can only do this if both the start and end of the mask are in the
// same halfword.
bool MBInLoHWord = MB >= 16;
bool MEInLoHWord = ME >= 16;
uint64_t Mask = ~0LLU;

if (MB <= ME && MBInLoHWord == MEInLoHWord && SH == 0) {
Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1);
// The mask value needs to shift right 16 if we're emitting andis.
Mask >>= MBInLoHWord ? 0 : 16;
NewOpC = MIOpC == PPC::RLWINM ?
(MBInLoHWord ? PPC::ANDIo : PPC::ANDISo) :
(MBInLoHWord ? PPC::ANDIo8 :PPC::ANDISo8);
} else if (MRI->use_empty(GPRRes) && (ME == 31) &&
(ME - MB + 1 == SH) && (MB >= 16)) {
// If we are rotating by the exact number of bits as are in the mask
// and the mask is in the least significant bits of the register,
// that's just an andis. (as long as the GPR result has no uses).
Mask = ((1LLU << 32) - 1) & ~((1LLU << (32 - SH)) - 1);
Mask >>= 16;
NewOpC = MIOpC == PPC::RLWINM ? PPC::ANDISo :PPC::ANDISo8;
}
// If we've set the mask, we can transform.
if (Mask != ~0LLU) {
MI->RemoveOperand(4);
MI->RemoveOperand(3);
MI->getOperand(2).setImm(Mask);
Expand Down
61 changes: 61 additions & 0 deletions llvm/test/CodeGen/PowerPC/noPermuteFormasking.ll
Expand Up @@ -40,3 +40,64 @@ for.body.i.i.i.i.i.i.i: ; preds = %for.body.i.i.i.i.i.
exitBB: ; preds = %for.body.i.i.i.i.i.i.i.prol.loopexit
ret void
}

define signext i32 @andis_bot(i32 signext %a, i32 signext %b) {
; CHECK-LABEL: andis_bot:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: andis. 5, 3, 1
; CHECK-NEXT: li 5, 1
; CHECK-NEXT: isel 4, 4, 5, 2
; CHECK-NEXT: mullw 3, 4, 3
; CHECK-NEXT: extsw 3, 3
; CHECK-NEXT: blr
entry:
%and = and i32 %a, 65536
%tobool = icmp eq i32 %and, 0
%mul = select i1 %tobool, i32 %b, i32 1
%cond = mul nsw i32 %mul, %a
ret i32 %cond
}

; Function Attrs: norecurse nounwind readnone
define signext i32 @andis_mid(i32 signext %a, i32 signext %b) {
; CHECK-LABEL: andis_mid:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: andis. 5, 3, 252
; CHECK-NEXT: li 5, 1
; CHECK-NEXT: isel 4, 4, 5, 2
; CHECK-NEXT: mullw 3, 4, 3
; CHECK-NEXT: extsw 3, 3
; CHECK-NEXT: blr
entry:
%and = and i32 %a, 16515072
%tobool = icmp eq i32 %and, 0
%mul = select i1 %tobool, i32 %b, i32 1
%cond = mul nsw i32 %mul, %a
ret i32 %cond
}

; Function Attrs: norecurse nounwind readnone
define signext i32 @andis_top(i32 signext %a, i32 signext %b) {
; CHECK-LABEL: andis_top:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: andis. 5, 3, 64512
; CHECK-NEXT: li 5, 1
; CHECK-NEXT: isel 4, 4, 5, 2
; CHECK-NEXT: mullw 3, 4, 3
; CHECK-NEXT: extsw 3, 3
; CHECK-NEXT: blr
entry:
%tobool = icmp ugt i32 %a, 67108863
%mul = select i1 %tobool, i32 1, i32 %b
%cond = mul nsw i32 %mul, %a
ret i32 %cond
}

define i64 @andis_no_cmp(i64 %a, i64 %b) {
entry:
%and = and i64 %a, 65536
%tobool = icmp eq i64 %and, 0
%mul = select i1 %tobool, i64 %b, i64 1
%cond = mul nsw i64 %mul, %a
ret i64 %cond
}
8 changes: 4 additions & 4 deletions llvm/test/CodeGen/PowerPC/tail-dup-break-cfg.ll
Expand Up @@ -15,12 +15,12 @@ target triple = "powerpc64le-grtev4-linux-gnu"
;CHECK: andi. {{[0-9]+}}, [[TAGREG]], 1
;CHECK-NEXT: bc 12, 1, [[BODY1LABEL:[._0-9A-Za-z]+]]
;CHECK-NEXT: # %test2
;CHECK-NEXT: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 30, 30
;CHECK-NEXT: andi. {{[0-9]+}}, [[TAGREG]], 2
;CHECK-NEXT: bne 0, [[BODY2LABEL:[._0-9A-Za-z]+]]
;CHECK: [[EXITLABEL:[._0-9A-Za-z]+]]: # %exit
;CHECK: blr
;CHECK-NEXT: [[BODY1LABEL]]
;CHECK: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 30, 30
;CHECK: andi. {{[0-9]+}}, [[TAGREG]], 2
;CHECK-NEXT: beq 0, [[EXITLABEL]]
;CHECK-NEXT: [[BODY2LABEL:[._0-9A-Za-z]+]]:
;CHECK: b [[EXITLABEL]]
Expand Down Expand Up @@ -58,7 +58,7 @@ exit:
;CHECK-NEXT: bc 4, 1, [[TEST2LABEL:[._0-9A-Za-z]+]]
;CHECK-NEXT: # %body1
;CHECK: [[TEST2LABEL]]: # %test2
;CHECK-NEXT: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 30, 30
;CHECK-NEXT: andi. {{[0-9]+}}, [[TAGREG]], 2
;CHECK-NEXT: beq 0, [[EXITLABEL:[._0-9A-Za-z]+]]
;CHECK-NEXT: # %body2
;CHECK: [[EXITLABEL:[._0-9A-Za-z]+]]: # %exit
Expand Down Expand Up @@ -106,7 +106,7 @@ declare void @d()
; CHECK: # %succ
; CHECK: # %c
; CHECK: bl c
; CHECK: rlwinm. {{[0-9]+}}, {{[0-9]+}}, 0, 29, 29
; CHECK: andi. {{[0-9]+}}, {{[0-9]+}}, 4
; CHECK: beq
; CHECK: b
define void @tail_dup_no_succ(i32 %tag) {
Expand Down
36 changes: 18 additions & 18 deletions llvm/test/CodeGen/PowerPC/tail-dup-layout.ll
Expand Up @@ -28,24 +28,24 @@ target triple = "powerpc64le-grtev4-linux-gnu"
;CHECK: andi. {{[0-9]+}}, [[TAGREG:[0-9]+]], 1
;CHECK-NEXT: bc 12, 1, .[[OPT1LABEL:[_0-9A-Za-z]+]]
;CHECK-NEXT: # %test2
;CHECK-NEXT: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 30, 30
;CHECK-NEXT: andi. {{[0-9]+}}, [[TAGREG]], 2
;CHECK-NEXT: bne 0, .[[OPT2LABEL:[_0-9A-Za-z]+]]
;CHECK-NEXT: .[[TEST3LABEL:[_0-9A-Za-z]+]]: # %test3
;CHECK-NEXT: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 29, 29
;CHECK-NEXT: andi. {{[0-9]+}}, [[TAGREG]], 4
;CHECK-NEXT: bne 0, .[[OPT3LABEL:[_0-9A-Za-z]+]]
;CHECK-NEXT: .[[TEST4LABEL:[_0-9A-Za-z]+]]: # %test4
;CHECK-NEXT: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 28, 28
;CHECK-NEXT: andi. {{[0-9]+}}, [[TAGREG]], 8
;CHECK-NEXT: bne 0, .[[OPT4LABEL:[_0-9A-Za-z]+]]
;CHECK-NEXT: .[[EXITLABEL:[_0-9A-Za-z]+]]: # %exit
;CHECK: blr
;CHECK-NEXT: .[[OPT1LABEL]]:
;CHECK: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 30, 30
;CHECK: andi. {{[0-9]+}}, [[TAGREG]], 2
;CHECK-NEXT: beq 0, .[[TEST3LABEL]]
;CHECK-NEXT: .[[OPT2LABEL]]:
;CHECK: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 29, 29
;CHECK: andi. {{[0-9]+}}, [[TAGREG]], 4
;CHECK-NEXT: beq 0, .[[TEST4LABEL]]
;CHECK-NEXT: .[[OPT3LABEL]]:
;CHECK: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 28, 28
;CHECK: andi. {{[0-9]+}}, [[TAGREG]], 8
;CHECK-NEXT: beq 0, .[[EXITLABEL]]
;CHECK-NEXT: .[[OPT4LABEL]]:
;CHECK: b .[[EXITLABEL]]
Expand Down Expand Up @@ -119,18 +119,18 @@ exit:
;CHECK: andi. {{[0-9]+}}, [[TAGREG]], 1
;CHECK-NEXT: bc 12, 1, .[[OPT1LABEL:[_0-9A-Za-z]+]]
;CHECK-NEXT: # %test2
;CHECK-NEXT: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 30, 30
;CHECK-NEXT: andi. {{[0-9]+}}, [[TAGREG]], 2
;CHECK-NEXT: bne 0, .[[OPT2LABEL:[_0-9A-Za-z]+]]
;CHECK-NEXT: .[[TEST3LABEL:[_0-9A-Za-z]+]]: # %test3
;CHECK-NEXT: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 29, 29
;CHECK-NEXT: andi. {{[0-9]+}}, [[TAGREG]], 4
;CHECK-NEXT: bne 0, .[[OPT3LABEL:[_0-9A-Za-z]+]]
;CHECK-NEXT: .[[EXITLABEL:[_0-9A-Za-z]+]]: # %exit
;CHECK: blr
;CHECK-NEXT: .[[OPT1LABEL]]:
;CHECK: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 30, 30
;CHECK: andi. {{[0-9]+}}, [[TAGREG]], 2
;CHECK-NEXT: beq 0, .[[TEST3LABEL]]
;CHECK-NEXT: .[[OPT2LABEL]]:
;CHECK: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 29, 29
;CHECK: andi. {{[0-9]+}}, [[TAGREG]], 4
;CHECK-NEXT: beq 0, .[[EXITLABEL]]
;CHECK-NEXT: .[[OPT3LABEL]]:
;CHECK: b .[[EXITLABEL]]
Expand Down Expand Up @@ -285,23 +285,23 @@ exit:
;CHECK: andi. {{[0-9]+}}, [[TAGREG]], 1
;CHECK-NEXT: bc 12, 1, .[[OPT1LABEL:[._0-9A-Za-z]+]]
;CHECK-NEXT: # %test2
;CHECK: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 30, 30
;CHECK: andi. {{[0-9]+}}, [[TAGREG]], 2
;CHECK-NEXT: bne 0, .[[OPT2LABEL:[._0-9A-Za-z]+]]
;CHECK-NEXT: .[[TEST3LABEL:[._0-9A-Za-z]+]]: # %test3
;CHECK: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 29, 29
;CHECK: andi. {{[0-9]+}}, [[TAGREG]], 4
;CHECK-NEXT: bne 0, .[[OPT3LABEL:[._0-9A-Za-z]+]]
;CHECK-NEXT: .[[TEST4LABEL:[._0-9A-Za-z]+]]: # %{{(test4|optional3)}}
;CHECK: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 28, 28
;CHECK: andi. {{[0-9]+}}, [[TAGREG]], 8
;CHECK-NEXT: beq 0, .[[LATCHLABEL]]
;CHECK-NEXT: b .[[OPT4LABEL:[._0-9A-Za-z]+]]
;CHECK: [[OPT1LABEL]]
;CHECK: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 30, 30
;CHECK: andi. {{[0-9]+}}, [[TAGREG]], 2
;CHECK-NEXT: beq 0, .[[TEST3LABEL]]
;CHECK-NEXT: .[[OPT2LABEL]]
;CHECK: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 29, 29
;CHECK: andi. {{[0-9]+}}, [[TAGREG]], 4
;CHECK-NEXT: beq 0, .[[TEST4LABEL]]
;CHECK-NEXT: .[[OPT3LABEL]]
;CHECK: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 28, 28
;CHECK: andi. {{[0-9]+}}, [[TAGREG]], 8
;CHECK-NEXT: beq 0, .[[LATCHLABEL]]
;CHECK: [[OPT4LABEL]]:
;CHECK: b .[[LATCHLABEL]]
Expand Down Expand Up @@ -375,12 +375,12 @@ exit:
; Make sure then2 falls through from test2
; CHECK-NOT: # %{{[-_a-zA-Z0-9]+}}
; CHECK: # %bb.{{[0-9]+}}: # %then2
; CHECK: rlwinm. {{[0-9]+}}, {{[0-9]+}}, 0, 29, 29
; CHECK: andi. {{[0-9]+}}, {{[0-9]+}}, 4
; CHECK: # %else1
; CHECK: bl a
; CHECK: bl a
; Make sure then2 was copied into else1
; CHECK: rlwinm. {{[0-9]+}}, {{[0-9]+}}, 0, 29, 29
; CHECK: andi. {{[0-9]+}}, {{[0-9]+}}, 4
; CHECK: # %end1
; CHECK: bl d
; CHECK: # %else2
Expand Down

0 comments on commit 87c31a6

Please sign in to comment.