mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[PowerPC] Do not emit record-form rotates when record-form andi/andis 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
This commit is contained in:
parent
a59795bace
commit
2d74f410d9
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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]]
|
||||
@ -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
|
||||
@ -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) {
|
||||
|
@ -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]]
|
||||
@ -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]]
|
||||
@ -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]]
|
||||
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user