[llvm] r342478 - [PowerPC] Do not emit record-form rotates when record-form andi/andis suffices
Nemanja Ivanovic via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 18 06:43:16 PDT 2018
Author: nemanjai
Date: Tue Sep 18 06:43:16 2018
New Revision: 342478
URL: http://llvm.org/viewvc/llvm-project?rev=342478&view=rev
Log:
[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
Modified:
llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp
llvm/trunk/test/CodeGen/PowerPC/noPermuteFormasking.ll
llvm/trunk/test/CodeGen/PowerPC/tail-dup-break-cfg.ll
llvm/trunk/test/CodeGen/PowerPC/tail-dup-layout.ll
Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp?rev=342478&r1=342477&r2=342478&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp Tue Sep 18 06:43:16 2018
@@ -1913,14 +1913,36 @@ bool PPCInstrInfo::optimizeCompareInstr(
// 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);
Modified: llvm/trunk/test/CodeGen/PowerPC/noPermuteFormasking.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/noPermuteFormasking.ll?rev=342478&r1=342477&r2=342478&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/noPermuteFormasking.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/noPermuteFormasking.ll Tue Sep 18 06:43:16 2018
@@ -40,3 +40,64 @@ for.body.i.i.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
+}
Modified: llvm/trunk/test/CodeGen/PowerPC/tail-dup-break-cfg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/tail-dup-break-cfg.ll?rev=342478&r1=342477&r2=342478&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/tail-dup-break-cfg.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/tail-dup-break-cfg.ll Tue Sep 18 06:43:16 2018
@@ -15,12 +15,12 @@ target triple = "powerpc64le-grtev4-linu
;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) {
Modified: llvm/trunk/test/CodeGen/PowerPC/tail-dup-layout.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/tail-dup-layout.ll?rev=342478&r1=342477&r2=342478&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/tail-dup-layout.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/tail-dup-layout.ll Tue Sep 18 06:43:16 2018
@@ -28,24 +28,24 @@ target triple = "powerpc64le-grtev4-linu
;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
More information about the llvm-commits
mailing list