Skip to content

Commit c4449df

Browse files
committedAug 23, 2017
[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
1 parent 0884b73 commit c4449df

File tree

2 files changed

+147
-0
lines changed

2 files changed

+147
-0
lines changed
 

‎llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp

+51
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,12 @@ namespace {
133133
void PreprocessISelDAG() override;
134134
void PostprocessISelDAG() override;
135135

136+
/// getI16Imm - Return a target constant with the specified value, of type
137+
/// i16.
138+
inline SDValue getI16Imm(unsigned Imm, const SDLoc &dl) {
139+
return CurDAG->getTargetConstant(Imm, dl, MVT::i16);
140+
}
141+
136142
/// getI32Imm - Return a target constant with the specified value, of type
137143
/// i32.
138144
inline SDValue getI32Imm(unsigned Imm, const SDLoc &dl) {
@@ -450,6 +456,12 @@ static bool isInt32Immediate(SDValue N, unsigned &Imm) {
450456
return isInt32Immediate(N.getNode(), Imm);
451457
}
452458

459+
/// isInt64Immediate - This method tests to see if the value is a 64-bit
460+
/// constant operand. If so Imm will receive the 64-bit value.
461+
static bool isInt64Immediate(SDValue N, uint64_t &Imm) {
462+
return isInt64Immediate(N.getNode(), Imm);
463+
}
464+
453465
static unsigned getBranchHint(unsigned PCC, FunctionLoweringInfo *FuncInfo,
454466
const SDValue &DestMBB) {
455467
assert(isa<BasicBlockSDNode>(DestMBB));
@@ -3375,12 +3387,51 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
33753387
}
33763388
}
33773389

3390+
// OR with a 32-bit immediate can be handled by ori + oris
3391+
// without creating an immediate in a GPR.
3392+
uint64_t Imm64 = 0;
3393+
bool IsPPC64 = PPCSubTarget->isPPC64();
3394+
if (IsPPC64 && isInt64Immediate(N->getOperand(1), Imm64) &&
3395+
(Imm64 & ~0xFFFFFFFFuLL) == 0) {
3396+
// If ImmHi (ImmHi) is zero, only one ori (oris) is generated later.
3397+
uint64_t ImmHi = Imm64 >> 16;
3398+
uint64_t ImmLo = Imm64 & 0xFFFF;
3399+
if (ImmHi != 0 && ImmLo != 0) {
3400+
SDNode *Lo = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64,
3401+
N->getOperand(0),
3402+
getI16Imm(ImmLo, dl));
3403+
SDValue Ops1[] = { SDValue(Lo, 0), getI16Imm(ImmHi, dl)};
3404+
CurDAG->SelectNodeTo(N, PPC::ORIS8, MVT::i64, Ops1);
3405+
return;
3406+
}
3407+
}
3408+
33783409
// Other cases are autogenerated.
33793410
break;
33803411
}
33813412
case ISD::XOR: {
33823413
if (tryLogicOpOfCompares(N))
33833414
return;
3415+
3416+
// XOR with a 32-bit immediate can be handled by xori + xoris
3417+
// without creating an immediate in a GPR.
3418+
uint64_t Imm64 = 0;
3419+
bool IsPPC64 = PPCSubTarget->isPPC64();
3420+
if (IsPPC64 && isInt64Immediate(N->getOperand(1), Imm64) &&
3421+
(Imm64 & ~0xFFFFFFFFuLL) == 0) {
3422+
// If ImmHi (ImmHi) is zero, only one xori (xoris) is generated later.
3423+
uint64_t ImmHi = Imm64 >> 16;
3424+
uint64_t ImmLo = Imm64 & 0xFFFF;
3425+
if (ImmHi != 0 && ImmLo != 0) {
3426+
SDNode *Lo = CurDAG->getMachineNode(PPC::XORI8, dl, MVT::i64,
3427+
N->getOperand(0),
3428+
getI16Imm(ImmLo, dl));
3429+
SDValue Ops1[] = { SDValue(Lo, 0), getI16Imm(ImmHi, dl)};
3430+
CurDAG->SelectNodeTo(N, PPC::XORIS8, MVT::i64, Ops1);
3431+
return;
3432+
}
3433+
}
3434+
33843435
break;
33853436
}
33863437
case ISD::ADD: {
+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
; RUN: llc -verify-machineinstrs < %s -march=ppc64le | FileCheck %s
2+
; RUN: llc -verify-machineinstrs < %s -march=ppc64 | FileCheck %s
3+
4+
define i64 @ori_test_a(i64 %a) {
5+
entry:
6+
; CHECK-LABEL: @ori_test_a
7+
; CHECK-DAG: ori 3, 3, 65535
8+
; CHECK-DAG: oris 3, 3, 65535
9+
; CHECK-NEXT: blr
10+
%or = or i64 %a, 4294967295
11+
ret i64 %or
12+
}
13+
14+
define i64 @ori_test_b(i64 %a) {
15+
entry:
16+
; CHECK-LABEL: @ori_test_b
17+
; CHECK: or 3, 3, {{[0-9]+}}
18+
; CHECK-NEXT: blr
19+
%or = or i64 %a, 4294967296
20+
ret i64 %or
21+
}
22+
23+
define i64 @ori_test_c(i64 %a) {
24+
entry:
25+
; CHECK-LABEL: @ori_test_c
26+
; CHECK: ori 3, 3, 65535
27+
; CHECK-NEXT: blr
28+
%or = or i64 %a, 65535
29+
ret i64 %or
30+
}
31+
32+
define i64 @ori_test_d(i64 %a) {
33+
entry:
34+
; CHECK-LABEL: @ori_test_d
35+
; CHECK: oris 3, 3, 1
36+
; CHECK-NEXT: blr
37+
%or = or i64 %a, 65536
38+
ret i64 %or
39+
}
40+
41+
define zeroext i32 @ori_test_e(i32 zeroext %a) {
42+
entry:
43+
; CHECK-LABEL: @ori_test_e
44+
; CHECK-DAG: ori 3, 3, 65535
45+
; CHECK-DAG: oris 3, 3, 255
46+
; CHECK-NEXT: blr
47+
%or = or i32 %a, 16777215
48+
ret i32 %or
49+
}
50+
51+
define i64 @xori_test_a(i64 %a) {
52+
entry:
53+
; CHECK-LABEL: @xori_test_a
54+
; CHECK-DAG: xori 3, 3, 65535
55+
; CHECK-DAG: xoris 3, 3, 65535
56+
; CHECK-NEXT: blr
57+
%xor = xor i64 %a, 4294967295
58+
ret i64 %xor
59+
}
60+
61+
define i64 @xori_test_b(i64 %a) {
62+
entry:
63+
; CHECK-LABEL: @xori_test_b
64+
; CHECK: xor 3, 3, {{[0-9]+}}
65+
; CHECK-NEXT: blr
66+
%xor = xor i64 %a, 4294967296
67+
ret i64 %xor
68+
}
69+
70+
define i64 @xori_test_c(i64 %a) {
71+
entry:
72+
; CHECK-LABEL: @xori_test_c
73+
; CHECK: xori 3, 3, 65535
74+
; CHECK-NEXT: blr
75+
%xor = xor i64 %a, 65535
76+
ret i64 %xor
77+
}
78+
79+
define i64 @xori_test_d(i64 %a) {
80+
entry:
81+
; CHECK-LABEL: @xori_test_d
82+
; CHECK: xoris 3, 3, 1
83+
; CHECK-NEXT: blr
84+
%xor = xor i64 %a, 65536
85+
ret i64 %xor
86+
}
87+
88+
define zeroext i32 @xori_test_e(i32 zeroext %a) {
89+
entry:
90+
; CHECK-LABEL: @xori_test_e
91+
; CHECK-DAG: xori 3, 3, 65535
92+
; CHECK-DAG: xoris 3, 3, 255
93+
; CHECK-NEXT: blr
94+
%xor = xor i32 %a, 16777215
95+
ret i32 %xor
96+
}

0 commit comments

Comments
 (0)
Please sign in to comment.