forked from OSchip/llvm-project
[PowerPC] better instruction selection for OR (XOR) with a 32-bit immediate
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: 311526
This commit is contained in:
parent
0884b73220
commit
c4449df1b0
|
@ -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: {
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
; RUN: llc -verify-machineinstrs < %s -march=ppc64le | FileCheck %s
|
||||
; RUN: llc -verify-machineinstrs < %s -march=ppc64 | FileCheck %s
|
||||
|
||||
define i64 @ori_test_a(i64 %a) {
|
||||
entry:
|
||||
; CHECK-LABEL: @ori_test_a
|
||||
; CHECK-DAG: ori 3, 3, 65535
|
||||
; CHECK-DAG: oris 3, 3, 65535
|
||||
; CHECK-NEXT: blr
|
||||
%or = or i64 %a, 4294967295
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
define i64 @ori_test_b(i64 %a) {
|
||||
entry:
|
||||
; CHECK-LABEL: @ori_test_b
|
||||
; CHECK: or 3, 3, {{[0-9]+}}
|
||||
; CHECK-NEXT: blr
|
||||
%or = or i64 %a, 4294967296
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
define i64 @ori_test_c(i64 %a) {
|
||||
entry:
|
||||
; CHECK-LABEL: @ori_test_c
|
||||
; CHECK: ori 3, 3, 65535
|
||||
; CHECK-NEXT: blr
|
||||
%or = or i64 %a, 65535
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
define i64 @ori_test_d(i64 %a) {
|
||||
entry:
|
||||
; CHECK-LABEL: @ori_test_d
|
||||
; CHECK: oris 3, 3, 1
|
||||
; CHECK-NEXT: blr
|
||||
%or = or i64 %a, 65536
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
define zeroext i32 @ori_test_e(i32 zeroext %a) {
|
||||
entry:
|
||||
; CHECK-LABEL: @ori_test_e
|
||||
; CHECK-DAG: ori 3, 3, 65535
|
||||
; CHECK-DAG: oris 3, 3, 255
|
||||
; CHECK-NEXT: blr
|
||||
%or = or i32 %a, 16777215
|
||||
ret i32 %or
|
||||
}
|
||||
|
||||
define i64 @xori_test_a(i64 %a) {
|
||||
entry:
|
||||
; CHECK-LABEL: @xori_test_a
|
||||
; CHECK-DAG: xori 3, 3, 65535
|
||||
; CHECK-DAG: xoris 3, 3, 65535
|
||||
; CHECK-NEXT: blr
|
||||
%xor = xor i64 %a, 4294967295
|
||||
ret i64 %xor
|
||||
}
|
||||
|
||||
define i64 @xori_test_b(i64 %a) {
|
||||
entry:
|
||||
; CHECK-LABEL: @xori_test_b
|
||||
; CHECK: xor 3, 3, {{[0-9]+}}
|
||||
; CHECK-NEXT: blr
|
||||
%xor = xor i64 %a, 4294967296
|
||||
ret i64 %xor
|
||||
}
|
||||
|
||||
define i64 @xori_test_c(i64 %a) {
|
||||
entry:
|
||||
; CHECK-LABEL: @xori_test_c
|
||||
; CHECK: xori 3, 3, 65535
|
||||
; CHECK-NEXT: blr
|
||||
%xor = xor i64 %a, 65535
|
||||
ret i64 %xor
|
||||
}
|
||||
|
||||
define i64 @xori_test_d(i64 %a) {
|
||||
entry:
|
||||
; CHECK-LABEL: @xori_test_d
|
||||
; CHECK: xoris 3, 3, 1
|
||||
; CHECK-NEXT: blr
|
||||
%xor = xor i64 %a, 65536
|
||||
ret i64 %xor
|
||||
}
|
||||
|
||||
define zeroext i32 @xori_test_e(i32 zeroext %a) {
|
||||
entry:
|
||||
; CHECK-LABEL: @xori_test_e
|
||||
; CHECK-DAG: xori 3, 3, 65535
|
||||
; CHECK-DAG: xoris 3, 3, 255
|
||||
; CHECK-NEXT: blr
|
||||
%xor = xor i32 %a, 16777215
|
||||
ret i32 %xor
|
||||
}
|
Loading…
Reference in New Issue