1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[PowerPC] Materialize more constants with CR-field set in late peephole

Revision r322373 fixed a bug in how we materialize constants when the CR-field
needs to be set.

However the fix is overly conservative. It will only do the transform if
AND-ing the input with the new constant produces the same new constant.
This is of course correct, but not necessarily required.

If there are no futher uses of the constant, the constant can be changed.
If there are no uses of the GPR result, the final result of the materialization
isn't important other than it needs to compare to zero correctly (lt, gt, eq).

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

llvm-svn: 337008
This commit is contained in:
Nemanja Ivanovic 2018-07-13 15:21:03 +00:00
parent 9249622410
commit 165362eb26
3 changed files with 450 additions and 8 deletions

View File

@ -2480,8 +2480,6 @@ bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI,
Is64BitLI = Opc != PPC::RLDICL_32;
NewImm = InVal.getSExtValue();
SetCR = Opc == PPC::RLDICLo;
if (SetCR && (SExtImm & NewImm) != NewImm)
return false;
break;
}
return false;
@ -2495,7 +2493,7 @@ bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI,
int64_t ME = MI.getOperand(4).getImm();
APInt InVal(32, SExtImm, true);
InVal = InVal.rotl(SH);
// Set the bits ( MB + 32 ) to ( ME + 32 ).
// Set the bits ( MB + 32 ) to ( ME + 32 ).
uint64_t Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1);
InVal &= Mask;
// Can't replace negative values with an LI as that will sign-extend
@ -2509,8 +2507,6 @@ bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI,
Is64BitLI = Opc == PPC::RLWINM8 || Opc == PPC::RLWINM8o;
NewImm = InVal.getSExtValue();
SetCR = Opc == PPC::RLWINMo || Opc == PPC::RLWINM8o;
if (SetCR && (SExtImm & NewImm) != NewImm)
return false;
break;
}
return false;
@ -2536,6 +2532,33 @@ bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI,
}
if (ReplaceWithLI) {
// We need to be careful with CR-setting instructions we're replacing.
if (SetCR) {
// We don't know anything about uses when we're out of SSA, so only
// replace if the new immediate will be reproduced.
bool ImmChanged = (SExtImm & NewImm) != NewImm;
if (PostRA && ImmChanged)
return false;
if (!PostRA) {
// If the defining load-immediate has no other uses, we can just replace
// the immediate with the new immediate.
if (MRI->hasOneUse(DefMI->getOperand(0).getReg()))
DefMI->getOperand(1).setImm(NewImm);
// If we're not using the GPR result of the CR-setting instruction, we
// just need to and with zero/non-zero depending on the new immediate.
else if (MRI->use_empty(MI.getOperand(0).getReg())) {
if (NewImm) {
assert(Immediate && "Transformation converted zero to non-zero?");
NewImm = Immediate;
}
}
else if (ImmChanged)
return false;
}
}
LLVM_DEBUG(dbgs() << "Replacing instruction:\n");
LLVM_DEBUG(MI.dump());
LLVM_DEBUG(dbgs() << "Fed by:\n");

View File

@ -3982,7 +3982,8 @@ body: |
%1 = COPY $x4
%0 = LI8 200
%2 = RLDICLo %0, 61, 3, implicit-def $cr0
; CHECK-NOT: ANDI
; CHECK: LI8 25
; CHECK: ANDIo8 %0, 25
; CHECK-LATE-NOT: andi.
%3 = COPY killed $cr0
%4 = ISEL8 %1, %2, %3.sub_eq
@ -4298,7 +4299,8 @@ body: |
%2 = COPY %1.sub_32
%3 = LI -22
%4 = RLWINMo %3, 0, 24, 31, implicit-def $cr0
; CHECK: ANDIo %3, 234
; CHECK: LI -22
; CHECK: ANDIo %3, 65514
; CHECK-LATE: li 3, -22
; CHECK-LATE: andi. 5, 3, 234
%5 = COPY killed $cr0
@ -4362,7 +4364,8 @@ body: |
%2 = COPY %1.sub_32
%3 = LI -22
%4 = RLWINMo %3, 5, 24, 31, implicit-def $cr0
; CHECK-NOT: ANDI
; CHECK: LI -22
; CHECK-NOT: ANDIo8 %3, 65514
; CHECK-LATE-NOT: andi.
%5 = COPY killed $cr0
%6 = ISEL %2, %3, %5.sub_eq

View File

@ -0,0 +1,416 @@
# RUN: llc -run-pass ppc-mi-peepholes -ppc-convert-rr-to-ri %s -o - | FileCheck %s
# RUN: llc -start-after ppc-mi-peepholes -ppc-late-peephole %s -o - | FileCheck %s --check-prefix=CHECK-LATE
--- |
; ModuleID = 'rlwinm_rldicl_to_andi.ll'
source_filename = "rlwinm_rldicl_to_andi.c"
target datalayout = "e-m:e-i64:64-n32:64"
target triple = "powerpc64le-unknown-linux-gnu"
; Function Attrs: norecurse nounwind readnone
define signext i32 @testRLWINMSingleUseDef(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {
entry:
%shl.mask = and i32 %a, 1048575
%tobool = icmp eq i32 %shl.mask, 0
%cond = select i1 %tobool, i32 %a, i32 %b
ret i32 %cond
}
; Function Attrs: norecurse nounwind readnone
define signext i32 @testRLWINMNoGPRUseZero(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {
entry:
%shl.mask = and i32 %a, 1048575
%tobool = icmp eq i32 %shl.mask, 0
%cond = select i1 %tobool, i32 %a, i32 %b
ret i32 %cond
}
; Function Attrs: norecurse nounwind readnone
define signext i32 @testRLWINMNoGPRUseNonZero(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {
entry:
%shl.mask = and i32 %a, 1048575
%tobool = icmp eq i32 %shl.mask, 0
%cond = select i1 %tobool, i32 %a, i32 %b
ret i32 %cond
}
; Function Attrs: norecurse nounwind readnone
define i64 @testRLDICLSingleUseDef(i64 %a, i64 %b) local_unnamed_addr #0 {
entry:
%shl.mask = and i64 %a, 4503599627370495
%tobool = icmp eq i64 %shl.mask, 0
%cond = select i1 %tobool, i64 %a, i64 %b
ret i64 %cond
}
; Function Attrs: norecurse nounwind readnone
define i64 @testRLDICLNoGPRUseZero(i64 %a, i64 %b) local_unnamed_addr #0 {
entry:
%shl.mask = and i64 %a, 4503599627370495
%tobool = icmp eq i64 %shl.mask, 0
%cond = select i1 %tobool, i64 %a, i64 %b
ret i64 %cond
}
; Function Attrs: norecurse nounwind readnone
define i64 @testRLDICLNoGPRUseNonZero(i64 %a, i64 %b) local_unnamed_addr #0 {
entry:
%shl.mask = and i64 %a, 4503599627370495
%tobool = icmp eq i64 %shl.mask, 0
%cond = select i1 %tobool, i64 %a, i64 %b
ret i64 %cond
}
attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="ppc64le" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+vsx,-power9-vector,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.module.flags = !{!0, !1}
!llvm.ident = !{!2}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 7, !"PIC Level", i32 2}
!2 = !{!"clang version 7.0.0 (trunk 322378)"}
...
---
name: testRLWINMSingleUseDef
# CHECK: testRLWINMSingleUseDef
# CHECK-LATE: testRLWINMSingleUseDef
alignment: 4
exposesReturnsTwice: false
legalized: false
regBankSelected: false
selected: false
tracksRegLiveness: true
registers:
- { id: 0, class: g8rc, preferred-register: '' }
- { id: 1, class: g8rc, preferred-register: '' }
- { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
- { id: 3, class: gprc, preferred-register: '' }
- { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' }
- { id: 5, class: crrc, preferred-register: '' }
- { id: 6, class: gprc, preferred-register: '' }
- { id: 7, class: g8rc, preferred-register: '' }
liveins:
- { reg: '$x3', virtual-reg: '%0' }
- { reg: '$x4', virtual-reg: '%1' }
frameInfo:
isFrameAddressTaken: false
isReturnAddressTaken: false
hasStackMap: false
hasPatchPoint: false
stackSize: 0
offsetAdjustment: 0
maxAlignment: 0
adjustsStack: false
hasCalls: false
stackProtector: ''
maxCallFrameSize: 4294967295
hasOpaqueSPAdjustment: false
hasVAStart: false
hasMustTailInVarArgFunc: false
savePoint: ''
restorePoint: ''
fixedStack:
stack:
constants:
body: |
bb.0.entry:
liveins: $x3, $x4
%1:g8rc = COPY $x4
%0:g8rc = COPY $x3
%2:gprc_and_gprc_nor0 = COPY %1.sub_32
%3:gprc = LI -11
%4:gprc_and_gprc_nor0 = RLWINMo %3, 2, 20, 31, implicit-def $cr0
; CHECK: LI 4055
; CHECK: ANDIo %3, 4055
; CHECK-LATE-NOT: andi.
; CHECK-LATE: rlwinm.
%5:crrc = COPY killed $cr0
%6:gprc = ISEL %4, %2, %5.sub_eq
%7:g8rc = EXTSW_32_64 killed %6
$x3 = COPY %7
BLR8 implicit $lr8, implicit $rm, implicit $x3
...
---
name: testRLWINMNoGPRUseZero
alignment: 4
exposesReturnsTwice: false
legalized: false
regBankSelected: false
selected: false
tracksRegLiveness: true
registers:
- { id: 0, class: g8rc, preferred-register: '' }
- { id: 1, class: g8rc, preferred-register: '' }
- { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
- { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }
- { id: 4, class: gprc, preferred-register: '' }
- { id: 5, class: crrc, preferred-register: '' }
- { id: 6, class: gprc, preferred-register: '' }
- { id: 7, class: g8rc, preferred-register: '' }
liveins:
- { reg: '$x3', virtual-reg: '%0' }
- { reg: '$x4', virtual-reg: '%1' }
frameInfo:
isFrameAddressTaken: false
isReturnAddressTaken: false
hasStackMap: false
hasPatchPoint: false
stackSize: 0
offsetAdjustment: 0
maxAlignment: 0
adjustsStack: false
hasCalls: false
stackProtector: ''
maxCallFrameSize: 4294967295
hasOpaqueSPAdjustment: false
hasVAStart: false
hasMustTailInVarArgFunc: false
savePoint: ''
restorePoint: ''
fixedStack:
stack:
constants:
body: |
bb.0.entry:
liveins: $x3, $x4
%1:g8rc = COPY $x4
%0:g8rc = COPY $x3
%2:gprc_and_gprc_nor0 = COPY %1.sub_32
%3:gprc_and_gprc_nor0 = LI 1
%4:gprc = RLWINMo %3, 21, 20, 31, implicit-def $cr0
; CHECK: LI 1
; CHECK: ANDIo %3, 0
; CHECK-LATE: li [[IMM:[0-9]+]], 1
; CHECK-LATE: andi. {{[0-9]+}}, [[IMM]], 0
%5:crrc = COPY killed $cr0
%6:gprc = ISEL %3, %2, %5.sub_eq
%7:g8rc = EXTSW_32_64 killed %6
$x3 = COPY %7
BLR8 implicit $lr8, implicit $rm, implicit $x3
...
---
name: testRLWINMNoGPRUseNonZero
alignment: 4
exposesReturnsTwice: false
legalized: false
regBankSelected: false
selected: false
tracksRegLiveness: true
registers:
- { id: 0, class: g8rc, preferred-register: '' }
- { id: 1, class: g8rc, preferred-register: '' }
- { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
- { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }
- { id: 4, class: gprc, preferred-register: '' }
- { id: 5, class: crrc, preferred-register: '' }
- { id: 6, class: gprc, preferred-register: '' }
- { id: 7, class: g8rc, preferred-register: '' }
liveins:
- { reg: '$x3', virtual-reg: '%0' }
- { reg: '$x4', virtual-reg: '%1' }
frameInfo:
isFrameAddressTaken: false
isReturnAddressTaken: false
hasStackMap: false
hasPatchPoint: false
stackSize: 0
offsetAdjustment: 0
maxAlignment: 0
adjustsStack: false
hasCalls: false
stackProtector: ''
maxCallFrameSize: 4294967295
hasOpaqueSPAdjustment: false
hasVAStart: false
hasMustTailInVarArgFunc: false
savePoint: ''
restorePoint: ''
fixedStack:
stack:
constants:
body: |
bb.0.entry:
liveins: $x3, $x4
%1:g8rc = COPY $x4
%0:g8rc = COPY $x3
%2:gprc_and_gprc_nor0 = COPY %1.sub_32
%3:gprc_and_gprc_nor0 = LI -11
%4:gprc = RLWINMo %3, 2, 20, 31, implicit-def $cr0
; CHECK: LI -11
; CHECK: ANDIo %3, 65525
; CHECK-LATE-NOT: andi.
; CHECK-LATE: rlwinm.
%5:crrc = COPY killed $cr0
%6:gprc = ISEL %3, %2, %5.sub_eq
%7:g8rc = EXTSW_32_64 killed %6
$x3 = COPY %7
BLR8 implicit $lr8, implicit $rm, implicit $x3
...
---
name: testRLDICLSingleUseDef
alignment: 4
exposesReturnsTwice: false
legalized: false
regBankSelected: false
selected: false
tracksRegLiveness: true
registers:
- { id: 0, class: g8rc, preferred-register: '' }
- { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' }
- { id: 2, class: g8rc_and_g8rc_nox0, preferred-register: '' }
- { id: 3, class: crrc, preferred-register: '' }
- { id: 4, class: g8rc, preferred-register: '' }
liveins:
- { reg: '$x3', virtual-reg: '%0' }
- { reg: '$x4', virtual-reg: '%1' }
frameInfo:
isFrameAddressTaken: false
isReturnAddressTaken: false
hasStackMap: false
hasPatchPoint: false
stackSize: 0
offsetAdjustment: 0
maxAlignment: 0
adjustsStack: false
hasCalls: false
stackProtector: ''
maxCallFrameSize: 4294967295
hasOpaqueSPAdjustment: false
hasVAStart: false
hasMustTailInVarArgFunc: false
savePoint: ''
restorePoint: ''
fixedStack:
stack:
constants:
body: |
bb.0.entry:
liveins: $x3, $x4
%1:g8rc_and_g8rc_nox0 = COPY $x4
%0:g8rc = LI8 -11
%2:g8rc_and_g8rc_nox0 = RLDICLo %0, 2, 49, implicit-def $cr0
; CHECK: LI8 32727
; CHECK: ANDIo8 %0, 32727
; CHECK-LATE-NOT: andi.
; CHECK-LATE: rldicl.
%3:crrc = COPY killed $cr0
%4:g8rc = ISEL8 %2, %1, %3.sub_eq
$x3 = COPY %4
BLR8 implicit $lr8, implicit $rm, implicit $x3
...
---
name: testRLDICLNoGPRUseZero
alignment: 4
exposesReturnsTwice: false
legalized: false
regBankSelected: false
selected: false
tracksRegLiveness: true
registers:
- { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
- { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' }
- { id: 2, class: g8rc, preferred-register: '' }
- { id: 3, class: crrc, preferred-register: '' }
- { id: 4, class: g8rc, preferred-register: '' }
liveins:
- { reg: '$x3', virtual-reg: '%0' }
- { reg: '$x4', virtual-reg: '%1' }
frameInfo:
isFrameAddressTaken: false
isReturnAddressTaken: false
hasStackMap: false
hasPatchPoint: false
stackSize: 0
offsetAdjustment: 0
maxAlignment: 0
adjustsStack: false
hasCalls: false
stackProtector: ''
maxCallFrameSize: 4294967295
hasOpaqueSPAdjustment: false
hasVAStart: false
hasMustTailInVarArgFunc: false
savePoint: ''
restorePoint: ''
fixedStack:
stack:
constants:
body: |
bb.0.entry:
liveins: $x3, $x4
%1:g8rc_and_g8rc_nox0 = COPY $x4
%0:g8rc_and_g8rc_nox0 = LI8 1
%2:g8rc = RLDICLo %0, 32, 33, implicit-def $cr0
; CHECK: LI8 1
; CHECK: ANDIo8 %0, 0
; CHECK-LATE: li [[IMM:[0-9]+]], 1
; CHECK-LATE: andi. {{[0-9]+}}, [[IMM]], 0
%3:crrc = COPY killed $cr0
%4:g8rc = ISEL8 %0, %1, %3.sub_eq
$x3 = COPY %4
BLR8 implicit $lr8, implicit $rm, implicit $x3
...
---
name: testRLDICLNoGPRUseNonZero
alignment: 4
exposesReturnsTwice: false
legalized: false
regBankSelected: false
selected: false
tracksRegLiveness: true
registers:
- { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
- { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' }
- { id: 2, class: g8rc, preferred-register: '' }
- { id: 3, class: crrc, preferred-register: '' }
- { id: 4, class: g8rc, preferred-register: '' }
liveins:
- { reg: '$x3', virtual-reg: '%0' }
- { reg: '$x4', virtual-reg: '%1' }
frameInfo:
isFrameAddressTaken: false
isReturnAddressTaken: false
hasStackMap: false
hasPatchPoint: false
stackSize: 0
offsetAdjustment: 0
maxAlignment: 0
adjustsStack: false
hasCalls: false
stackProtector: ''
maxCallFrameSize: 4294967295
hasOpaqueSPAdjustment: false
hasVAStart: false
hasMustTailInVarArgFunc: false
savePoint: ''
restorePoint: ''
fixedStack:
stack:
constants:
body: |
bb.0.entry:
liveins: $x3, $x4
%1:g8rc_and_g8rc_nox0 = COPY $x4
%0:g8rc_and_g8rc_nox0 = LI8 -11
%2:g8rc = RLDICLo %0, 2, 49, implicit-def $cr0
; CHECK: LI8 -11
; CHECK: ANDIo8 %0, 65525
; CHECK-LATE-NOT: andi.
; CHECK-LATE: rldicl.
%3:crrc = COPY killed $cr0
%4:g8rc = ISEL8 %0, %1, %3.sub_eq
$x3 = COPY %4
BLR8 implicit $lr8, implicit $rm, implicit $x3
...