diff options
| author | Nemanja Ivanovic <nemanja.i.ibm@gmail.com> | 2018-09-18 13:43:16 +0000 |
|---|---|---|
| committer | Nemanja Ivanovic <nemanja.i.ibm@gmail.com> | 2018-09-18 13:43:16 +0000 |
| commit | 87c31a61134f523a09d4cd1cca09e4afe09afa7d (patch) | |
| tree | 263baace5eecee78210d919f6ef06c40979f3a84 /llvm | |
| parent | 5e1c0e7610406df5300be63e4b4cd5a05cc0a2a2 (diff) | |
| download | bcm5719-llvm-87c31a61134f523a09d4cd1cca09e4afe09afa7d.tar.gz bcm5719-llvm-87c31a61134f523a09d4cd1cca09e4afe09afa7d.zip | |
[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
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCInstrInfo.cpp | 34 | ||||
| -rw-r--r-- | llvm/test/CodeGen/PowerPC/noPermuteFormasking.ll | 61 | ||||
| -rw-r--r-- | llvm/test/CodeGen/PowerPC/tail-dup-break-cfg.ll | 8 | ||||
| -rw-r--r-- | llvm/test/CodeGen/PowerPC/tail-dup-layout.ll | 36 |
4 files changed, 111 insertions, 28 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp index c3a280ad9ae..f9d173699ec 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -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); diff --git a/llvm/test/CodeGen/PowerPC/noPermuteFormasking.ll b/llvm/test/CodeGen/PowerPC/noPermuteFormasking.ll index d4ce1a7ec66..8cd828f0a22 100644 --- a/llvm/test/CodeGen/PowerPC/noPermuteFormasking.ll +++ b/llvm/test/CodeGen/PowerPC/noPermuteFormasking.ll @@ -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 +} diff --git a/llvm/test/CodeGen/PowerPC/tail-dup-break-cfg.ll b/llvm/test/CodeGen/PowerPC/tail-dup-break-cfg.ll index f19b11f2ae4..62c1e068b84 100644 --- a/llvm/test/CodeGen/PowerPC/tail-dup-break-cfg.ll +++ b/llvm/test/CodeGen/PowerPC/tail-dup-break-cfg.ll @@ -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) { diff --git a/llvm/test/CodeGen/PowerPC/tail-dup-layout.ll b/llvm/test/CodeGen/PowerPC/tail-dup-layout.ll index a4e232941c8..bcae75f43cb 100644 --- a/llvm/test/CodeGen/PowerPC/tail-dup-layout.ll +++ b/llvm/test/CodeGen/PowerPC/tail-dup-layout.ll @@ -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 |

