summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/PowerPC
diff options
context:
space:
mode:
authorHiroshi Inoue <inouehrs@jp.ibm.com>2017-08-23 08:55:18 +0000
committerHiroshi Inoue <inouehrs@jp.ibm.com>2017-08-23 08:55:18 +0000
commitcc555bd0acc7b8d2a0a8afb78a126639f93a5524 (patch)
tree4cd96419b1e5d4a88e6f203ed63370ced756dd56 /llvm/lib/Target/PowerPC
parentde2d1066ae608a7a3acd2f7d23a9daaecc983641 (diff)
downloadbcm5719-llvm-cc555bd0acc7b8d2a0a8afb78a126639f93a5524.tar.gz
bcm5719-llvm-cc555bd0acc7b8d2a0a8afb78a126639f93a5524.zip
[PowerPC] better instruction selection for OR (XOR) with a 32-bit immediate
- recommitting after fixing a test failure on MacOS On PPC64, OR (XOR) with a 32-bit immediate can be done with only two instructions, i.e. ori + oris. But the current LLVM generates three or four instructions for this purpose (and also it clobbers one GPR). This patch makes PPC backend generate ori + oris (xori + xoris) for OR (XOR) with a 32-bit immediate. e.g. (x | 0xFFFFFFFF) should be ori 3, 3, 65535 oris 3, 3, 65535 but LLVM generates without this patch li 4, 0 oris 4, 4, 65535 ori 4, 4, 65535 or 3, 3, 4 Differential Revision: https://reviews.llvm.org/D34757 llvm-svn: 311538
Diffstat (limited to 'llvm/lib/Target/PowerPC')
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp51
1 files changed, 51 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index 4867f77bdc5..2eba6c7fa99 100644
--- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -133,6 +133,12 @@ namespace {
void PreprocessISelDAG() override;
void PostprocessISelDAG() override;
+ /// getI16Imm - Return a target constant with the specified value, of type
+ /// i16.
+ inline SDValue getI16Imm(unsigned Imm, const SDLoc &dl) {
+ return CurDAG->getTargetConstant(Imm, dl, MVT::i16);
+ }
+
/// getI32Imm - Return a target constant with the specified value, of type
/// i32.
inline SDValue getI32Imm(unsigned Imm, const SDLoc &dl) {
@@ -450,6 +456,12 @@ static bool isInt32Immediate(SDValue N, unsigned &Imm) {
return isInt32Immediate(N.getNode(), Imm);
}
+/// isInt64Immediate - This method tests to see if the value is a 64-bit
+/// constant operand. If so Imm will receive the 64-bit value.
+static bool isInt64Immediate(SDValue N, uint64_t &Imm) {
+ return isInt64Immediate(N.getNode(), Imm);
+}
+
static unsigned getBranchHint(unsigned PCC, FunctionLoweringInfo *FuncInfo,
const SDValue &DestMBB) {
assert(isa<BasicBlockSDNode>(DestMBB));
@@ -3375,12 +3387,51 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
}
}
+ // OR with a 32-bit immediate can be handled by ori + oris
+ // without creating an immediate in a GPR.
+ uint64_t Imm64 = 0;
+ bool IsPPC64 = PPCSubTarget->isPPC64();
+ if (IsPPC64 && isInt64Immediate(N->getOperand(1), Imm64) &&
+ (Imm64 & ~0xFFFFFFFFuLL) == 0) {
+ // If ImmHi (ImmHi) is zero, only one ori (oris) is generated later.
+ uint64_t ImmHi = Imm64 >> 16;
+ uint64_t ImmLo = Imm64 & 0xFFFF;
+ if (ImmHi != 0 && ImmLo != 0) {
+ SDNode *Lo = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64,
+ N->getOperand(0),
+ getI16Imm(ImmLo, dl));
+ SDValue Ops1[] = { SDValue(Lo, 0), getI16Imm(ImmHi, dl)};
+ CurDAG->SelectNodeTo(N, PPC::ORIS8, MVT::i64, Ops1);
+ return;
+ }
+ }
+
// Other cases are autogenerated.
break;
}
case ISD::XOR: {
if (tryLogicOpOfCompares(N))
return;
+
+ // XOR with a 32-bit immediate can be handled by xori + xoris
+ // without creating an immediate in a GPR.
+ uint64_t Imm64 = 0;
+ bool IsPPC64 = PPCSubTarget->isPPC64();
+ if (IsPPC64 && isInt64Immediate(N->getOperand(1), Imm64) &&
+ (Imm64 & ~0xFFFFFFFFuLL) == 0) {
+ // If ImmHi (ImmHi) is zero, only one xori (xoris) is generated later.
+ uint64_t ImmHi = Imm64 >> 16;
+ uint64_t ImmLo = Imm64 & 0xFFFF;
+ if (ImmHi != 0 && ImmLo != 0) {
+ SDNode *Lo = CurDAG->getMachineNode(PPC::XORI8, dl, MVT::i64,
+ N->getOperand(0),
+ getI16Imm(ImmLo, dl));
+ SDValue Ops1[] = { SDValue(Lo, 0), getI16Imm(ImmHi, dl)};
+ CurDAG->SelectNodeTo(N, PPC::XORIS8, MVT::i64, Ops1);
+ return;
+ }
+ }
+
break;
}
case ISD::ADD: {
OpenPOWER on IntegriCloud