Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit e703b24

Browse files
committed
[PowerPC] Use record-form instruction for Less-or-Equal -1 and Greater-or-Equal 1
Currently a record-form instruction is used for comparison of "greater than -1" and "less than 1" by modifying the predicate (e.g. LT 1 into LE 0) in addition to the naive case of comparison against 0. This patch also enables emitting a record-form instruction for "less than or equal to -1" (i.e. "less than 0") and "greater than or equal to 1" (i.e. "greater than 0") to increase the optimization opportunities. Differential Revision: https://reviews.llvm.org/D38941 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316647 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent ddfb984 commit e703b24

File tree

2 files changed

+75
-30
lines changed

2 files changed

+75
-30
lines changed

lib/Target/PowerPC/PPCInstrInfo.cpp

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,38 +1715,47 @@ bool PPCInstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg,
17151715
else if (MI->getParent() != CmpInstr.getParent())
17161716
return false;
17171717
else if (Value != 0) {
1718-
// The record-form instructions set CR bit based on signed comparison against 0.
1719-
// We try to convert a compare against 1 or -1 into a compare against 0.
1720-
bool Success = false;
1721-
if (!equalityOnly && MRI->hasOneUse(CRReg)) {
1722-
MachineInstr *UseMI = &*MRI->use_instr_begin(CRReg);
1723-
if (UseMI->getOpcode() == PPC::BCC) {
1724-
PPC::Predicate Pred = (PPC::Predicate)UseMI->getOperand(0).getImm();
1725-
unsigned PredCond = PPC::getPredicateCondition(Pred);
1726-
unsigned PredHint = PPC::getPredicateHint(Pred);
1727-
int16_t Immed = (int16_t)Value;
1728-
1729-
// When modyfing the condition in the predicate, we propagate hint bits
1730-
// from the original predicate to the new one.
1731-
if (Immed == -1 && PredCond == PPC::PRED_GT) {
1732-
// We convert "greater than -1" into "greater than or equal to 0",
1733-
// since we are assuming signed comparison by !equalityOnly
1734-
PredsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(0)),
1735-
PPC::getPredicate(PPC::PRED_GE, PredHint)));
1736-
Success = true;
1737-
}
1738-
else if (Immed == 1 && PredCond == PPC::PRED_LT) {
1739-
// We convert "less than 1" into "less than or equal to 0".
1740-
PredsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(0)),
1741-
PPC::getPredicate(PPC::PRED_LE, PredHint)));
1742-
Success = true;
1743-
}
1744-
}
1745-
}
1718+
// The record-form instructions set CR bit based on signed comparison
1719+
// against 0. We try to convert a compare against 1 or -1 into a compare
1720+
// against 0 to exploit record-form instructions. For example, we change
1721+
// the condition "greater than -1" into "greater than or equal to 0"
1722+
// and "less than 1" into "less than or equal to 0".
1723+
1724+
// Since we optimize comparison based on a specific branch condition,
1725+
// we don't optimize if condition code is used by more than once.
1726+
if (equalityOnly || !MRI->hasOneUse(CRReg))
1727+
return false;
1728+
1729+
MachineInstr *UseMI = &*MRI->use_instr_begin(CRReg);
1730+
if (UseMI->getOpcode() != PPC::BCC)
1731+
return false;
17461732

1747-
// PPC does not have a record-form SUBri.
1748-
if (!Success)
1733+
PPC::Predicate Pred = (PPC::Predicate)UseMI->getOperand(0).getImm();
1734+
PPC::Predicate NewPred = Pred;
1735+
unsigned PredCond = PPC::getPredicateCondition(Pred);
1736+
unsigned PredHint = PPC::getPredicateHint(Pred);
1737+
int16_t Immed = (int16_t)Value;
1738+
1739+
// When modyfing the condition in the predicate, we propagate hint bits
1740+
// from the original predicate to the new one.
1741+
if (Immed == -1 && PredCond == PPC::PRED_GT)
1742+
// We convert "greater than -1" into "greater than or equal to 0",
1743+
// since we are assuming signed comparison by !equalityOnly
1744+
NewPred = PPC::getPredicate(PPC::PRED_GE, PredHint);
1745+
else if (Immed == -1 && PredCond == PPC::PRED_LE)
1746+
// We convert "less than or equal to -1" into "less than 0".
1747+
NewPred = PPC::getPredicate(PPC::PRED_LT, PredHint);
1748+
else if (Immed == 1 && PredCond == PPC::PRED_LT)
1749+
// We convert "less than 1" into "less than or equal to 0".
1750+
NewPred = PPC::getPredicate(PPC::PRED_LE, PredHint);
1751+
else if (Immed == 1 && PredCond == PPC::PRED_GE)
1752+
// We convert "greater than or equal to 1" into "greater than 0".
1753+
NewPred = PPC::getPredicate(PPC::PRED_GT, PredHint);
1754+
else
17491755
return false;
1756+
1757+
PredsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(0)),
1758+
NewPred));
17501759
}
17511760

17521761
// Search for Sub.

test/CodeGen/PowerPC/opt-cmp-inst-cr0-live.ll

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
; RUN: llc -verify-machineinstrs -print-before=peephole-opt -print-after=peephole-opt -mtriple=powerpc64-unknown-linux-gnu -o /dev/null 2>&1 < %s | FileCheck %s
2+
; RUN: llc -verify-machineinstrs -print-before=peephole-opt -print-after=peephole-opt -mtriple=powerpc64le-unknown-linux-gnu -o /dev/null 2>&1 < %s | FileCheck %s
23

34
; CHECK-LABEL: fn1
45
define signext i32 @fn1(i32 %baz) {
@@ -99,3 +100,38 @@ foo:
99100
bar:
100101
ret i32 0
101102
}
103+
104+
; This test confirms record-form instructions are emitted for comparison
105+
; against a non-zero value.
106+
107+
; CHECK-LABEL: fn6
108+
define i8* @fn6(i8* readonly %p) {
109+
; CHECK: LBZU
110+
; CHECK: EXTSBo
111+
; CHECK-NOT: CMP
112+
; CHECK: BCC
113+
; CHECK: LBZU
114+
; CHECK: EXTSBo
115+
; CHECK-NOT: CMP
116+
; CHECK: BCC
117+
118+
entry:
119+
%incdec.ptr = getelementptr inbounds i8, i8* %p, i64 -1
120+
%0 = load i8, i8* %incdec.ptr
121+
%cmp = icmp sgt i8 %0, -1
122+
br i1 %cmp, label %out, label %if.end
123+
124+
if.end:
125+
%incdec.ptr2 = getelementptr inbounds i8, i8* %p, i64 -2
126+
%1 = load i8, i8* %incdec.ptr2
127+
%cmp4 = icmp sgt i8 %1, -1
128+
br i1 %cmp4, label %out, label %cleanup
129+
130+
out:
131+
%p.addr.0 = phi i8* [ %incdec.ptr, %entry ], [ %incdec.ptr2, %if.end ]
132+
br label %cleanup
133+
134+
cleanup:
135+
%retval.0 = phi i8* [ %p.addr.0, %out ], [ null, %if.end ]
136+
ret i8* %retval.0
137+
}

0 commit comments

Comments
 (0)