Skip to content

Commit b85a9b3

Browse files
author
esmeyi
committed
[PowerPC] Try to use less instructions to materialize 64-bit constant when High32=Low32.
Summary: Materialization a 64-bit constant with High32=Low32 only requires 2 instructions instead of 3 when Low32 can be materialized in 1 instruction. Reviewed By: qiucf Differential Revision: https://reviews.llvm.org/D158495
1 parent 28fe1a4 commit b85a9b3

File tree

2 files changed

+28
-18
lines changed

2 files changed

+28
-18
lines changed

llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,6 +1166,31 @@ static SDNode *selectI64ImmDirect(SelectionDAG *CurDAG, const SDLoc &dl,
11661166
return CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, SDValue(Result, 0),
11671167
getI32Imm(Shift), getI32Imm(0));
11681168
}
1169+
// 2-7) Patterns : High word == Low word
1170+
// This may require 2 to 3 instructions, depending on whether Lo32 can be
1171+
// materialized in 1 instruction.
1172+
if (Hi32 == Lo32) {
1173+
// Handle the first 32 bits.
1174+
uint64_t ImmHi16 = (Lo32 >> 16) & 0xffff;
1175+
uint64_t ImmLo16 = Lo32 & 0xffff;
1176+
if (isInt<16>(Lo32))
1177+
Result =
1178+
CurDAG->getMachineNode(PPC::LI8, dl, MVT::i64, getI32Imm(ImmLo16));
1179+
else if (!ImmLo16)
1180+
Result =
1181+
CurDAG->getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(ImmHi16));
1182+
else {
1183+
InstCnt = 3;
1184+
Result =
1185+
CurDAG->getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(ImmHi16));
1186+
Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64,
1187+
SDValue(Result, 0), getI32Imm(ImmLo16));
1188+
}
1189+
// Use rldimi to insert the Low word into High word.
1190+
SDValue Ops[] = {SDValue(Result, 0), SDValue(Result, 0), getI32Imm(32),
1191+
getI32Imm(0)};
1192+
return CurDAG->getMachineNode(PPC::RLDIMI, dl, MVT::i64, Ops);
1193+
}
11691194

11701195
// Following patterns use 3 instructions to materialize the Imm.
11711196
InstCnt = 3;
@@ -1216,20 +1241,7 @@ static SDNode *selectI64ImmDirect(SelectionDAG *CurDAG, const SDLoc &dl,
12161241
return CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, SDValue(Result, 0),
12171242
getI32Imm(TO), getI32Imm(LZ));
12181243
}
1219-
// 3-4) Patterns : High word == Low word
1220-
if (Hi32 == Lo32) {
1221-
// Handle the first 32 bits.
1222-
uint64_t ImmHi16 = (Lo32 >> 16) & 0xffff;
1223-
unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1224-
Result = CurDAG->getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1225-
Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, SDValue(Result, 0),
1226-
getI32Imm(Lo32 & 0xffff));
1227-
// Use rldimi to insert the Low word into High word.
1228-
SDValue Ops[] = {SDValue(Result, 0), SDValue(Result, 0), getI32Imm(32),
1229-
getI32Imm(0)};
1230-
return CurDAG->getMachineNode(PPC::RLDIMI, dl, MVT::i64, Ops);
1231-
}
1232-
// 3-5) Patterns : {******}{33 zeros}{******}
1244+
// 3-4) Patterns : {******}{33 zeros}{******}
12331245
// {******}{33 ones}{******}
12341246
// If the Imm contains 33 consecutive zeros/ones, it means that a total of 31
12351247
// bits remain on both sides. Rotate right the Imm to construct an int<32>

llvm/test/CodeGen/PowerPC/constants-i64.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -427,9 +427,8 @@ entry:
427427
define i64 @imm23() {
428428
; CHECK-LABEL: imm23:
429429
; CHECK: # %bb.0: # %entry
430-
; CHECK-NEXT: lis 3, -2
431-
; CHECK-NEXT: ori 3, 3, 0
432-
; CHECK-NEXT: rldicl 3, 3, 15, 17
430+
; CHECK-NEXT: li 3, 32767
431+
; CHECK-NEXT: rldimi 3, 3, 32, 0
433432
; CHECK-NEXT: blr
434433
entry:
435434
ret i64 140733193420799 ;0x00007FFF00007FFF
@@ -439,7 +438,6 @@ define i64 @imm24() {
439438
; CHECK-LABEL: imm24:
440439
; CHECK: # %bb.0: # %entry
441440
; CHECK-NEXT: lis 3, -9
442-
; CHECK-NEXT: ori 3, 3, 0
443441
; CHECK-NEXT: rldimi 3, 3, 32, 0
444442
; CHECK-NEXT: blr
445443
entry:

0 commit comments

Comments
 (0)