[RISCV] Optimize immediate materialisation with SH*ADD

Use SH1ADD/SH2ADD/SH3ADD along with LUI+ADDI to compose int32*3,
int32*5 and int32*9.

Reviewed By: craig.topper, luismarques

Differential Revision: https://reviews.llvm.org/D111484
This commit is contained in:
Ben Shi 2021-10-15 06:44:28 +00:00
parent 81e9c90686
commit 4fe5ab4b00
6 changed files with 99 additions and 24 deletions

View File

@ -2269,6 +2269,11 @@ void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t Value,
.addReg(DestReg) .addReg(DestReg)
.addReg(SrcReg) .addReg(SrcReg)
.addReg(RISCV::X0)); .addReg(RISCV::X0));
} else if (Inst.Opc == RISCV::SH1ADD || Inst.Opc == RISCV::SH2ADD ||
Inst.Opc == RISCV::SH3ADD) {
emitToStreamer(
Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addReg(
SrcReg));
} else { } else {
emitToStreamer( emitToStreamer(
Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm( Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm(

View File

@ -250,6 +250,33 @@ InstSeq generateInstSeq(int64_t Val, const FeatureBitset &ActiveFeatures) {
} }
} }
// Perform optimization with SH*ADD in the Zba extension.
if (Res.size() > 2 && ActiveFeatures[RISCV::FeatureStdExtZba]) {
assert(ActiveFeatures[RISCV::Feature64Bit] &&
"Expected RV32 to only need 2 instructions");
int64_t Div = 0;
unsigned Opc = 0;
RISCVMatInt::InstSeq TmpSeq;
// Select the opcode and divisor.
if ((Val % 3) == 0 && isInt<32>(Val / 3)) {
Div = 3;
Opc = RISCV::SH1ADD;
} else if ((Val % 5) == 0 && isInt<32>(Val / 5)) {
Div = 5;
Opc = RISCV::SH2ADD;
} else if ((Val % 9) == 0 && isInt<32>(Val / 9)) {
Div = 9;
Opc = RISCV::SH3ADD;
}
// Build the new instruction sequence.
if (Div > 0) {
generateInstSeqImpl(Val / Div, ActiveFeatures, TmpSeq);
TmpSeq.push_back(RISCVMatInt::Inst(Opc, 0));
if (TmpSeq.size() < Res.size())
Res = TmpSeq;
}
}
return Res; return Res;
} }

View File

@ -140,6 +140,9 @@ static SDNode *selectImm(SelectionDAG *CurDAG, const SDLoc &DL, int64_t Imm,
else if (Inst.Opc == RISCV::ADDUW) else if (Inst.Opc == RISCV::ADDUW)
Result = CurDAG->getMachineNode(RISCV::ADDUW, DL, XLenVT, SrcReg, Result = CurDAG->getMachineNode(RISCV::ADDUW, DL, XLenVT, SrcReg,
CurDAG->getRegister(RISCV::X0, XLenVT)); CurDAG->getRegister(RISCV::X0, XLenVT));
else if (Inst.Opc == RISCV::SH1ADD || Inst.Opc == RISCV::SH2ADD ||
Inst.Opc == RISCV::SH3ADD)
Result = CurDAG->getMachineNode(Inst.Opc, DL, XLenVT, SrcReg, SrcReg);
else else
Result = CurDAG->getMachineNode(Inst.Opc, DL, XLenVT, SrcReg, SDImm); Result = CurDAG->getMachineNode(Inst.Opc, DL, XLenVT, SrcReg, SDImm);

View File

@ -458,6 +458,12 @@ void RISCVInstrInfo::movImm(MachineBasicBlock &MBB,
.addReg(SrcReg, RegState::Kill) .addReg(SrcReg, RegState::Kill)
.addReg(RISCV::X0) .addReg(RISCV::X0)
.setMIFlag(Flag); .setMIFlag(Flag);
} else if (Inst.Opc == RISCV::SH1ADD || Inst.Opc == RISCV::SH2ADD ||
Inst.Opc == RISCV::SH3ADD) {
BuildMI(MBB, MBBI, DL, get(Inst.Opc), Result)
.addReg(SrcReg, RegState::Kill)
.addReg(SrcReg, RegState::Kill)
.setMIFlag(Flag);
} else { } else {
BuildMI(MBB, MBBI, DL, get(Inst.Opc), Result) BuildMI(MBB, MBBI, DL, get(Inst.Opc), Result)
.addReg(SrcReg, RegState::Kill) .addReg(SrcReg, RegState::Kill)

View File

@ -959,10 +959,9 @@ define i64 @imm_neg_5372288229() {
; ;
; RV64IZBA-LABEL: imm_neg_5372288229: ; RV64IZBA-LABEL: imm_neg_5372288229:
; RV64IZBA: # %bb.0: ; RV64IZBA: # %bb.0:
; RV64IZBA-NEXT: lui a0, 1048416 ; RV64IZBA-NEXT: lui a0, 611378
; RV64IZBA-NEXT: addiw a0, a0, -437 ; RV64IZBA-NEXT: addiw a0, a0, 265
; RV64IZBA-NEXT: slli a0, a0, 13 ; RV64IZBA-NEXT: sh1add a0, a0, a0
; RV64IZBA-NEXT: addi a0, a0, 795
; RV64IZBA-NEXT: ret ; RV64IZBA-NEXT: ret
; ;
; RV64IZBS-LABEL: imm_neg_5372288229: ; RV64IZBS-LABEL: imm_neg_5372288229:
@ -992,10 +991,9 @@ define i64 @imm_8953813715() {
; ;
; RV64IZBA-LABEL: imm_8953813715: ; RV64IZBA-LABEL: imm_8953813715:
; RV64IZBA: # %bb.0: ; RV64IZBA: # %bb.0:
; RV64IZBA-NEXT: lui a0, 267 ; RV64IZBA-NEXT: lui a0, 437198
; RV64IZBA-NEXT: addiw a0, a0, -637 ; RV64IZBA-NEXT: addiw a0, a0, -265
; RV64IZBA-NEXT: slli a0, a0, 13 ; RV64IZBA-NEXT: sh2add a0, a0, a0
; RV64IZBA-NEXT: addi a0, a0, -1325
; RV64IZBA-NEXT: ret ; RV64IZBA-NEXT: ret
; ;
; RV64IZBS-LABEL: imm_8953813715: ; RV64IZBS-LABEL: imm_8953813715:
@ -1025,10 +1023,9 @@ define i64 @imm_neg_8953813715() {
; ;
; RV64IZBA-LABEL: imm_neg_8953813715: ; RV64IZBA-LABEL: imm_neg_8953813715:
; RV64IZBA: # %bb.0: ; RV64IZBA: # %bb.0:
; RV64IZBA-NEXT: lui a0, 1048309 ; RV64IZBA-NEXT: lui a0, 611378
; RV64IZBA-NEXT: addiw a0, a0, 637 ; RV64IZBA-NEXT: addiw a0, a0, 265
; RV64IZBA-NEXT: slli a0, a0, 13 ; RV64IZBA-NEXT: sh2add a0, a0, a0
; RV64IZBA-NEXT: addi a0, a0, 1325
; RV64IZBA-NEXT: ret ; RV64IZBA-NEXT: ret
; ;
; RV64IZBS-LABEL: imm_neg_8953813715: ; RV64IZBS-LABEL: imm_neg_8953813715:
@ -1058,10 +1055,9 @@ define i64 @imm_16116864687() {
; ;
; RV64IZBA-LABEL: imm_16116864687: ; RV64IZBA-LABEL: imm_16116864687:
; RV64IZBA: # %bb.0: ; RV64IZBA: # %bb.0:
; RV64IZBA-NEXT: lui a0, 961 ; RV64IZBA-NEXT: lui a0, 437198
; RV64IZBA-NEXT: addiw a0, a0, -1475 ; RV64IZBA-NEXT: addiw a0, a0, -265
; RV64IZBA-NEXT: slli a0, a0, 12 ; RV64IZBA-NEXT: sh3add a0, a0, a0
; RV64IZBA-NEXT: addi a0, a0, 1711
; RV64IZBA-NEXT: ret ; RV64IZBA-NEXT: ret
; ;
; RV64IZBS-LABEL: imm_16116864687: ; RV64IZBS-LABEL: imm_16116864687:
@ -1092,10 +1088,9 @@ define i64 @imm_neg_16116864687() {
; ;
; RV64IZBA-LABEL: imm_neg_16116864687: ; RV64IZBA-LABEL: imm_neg_16116864687:
; RV64IZBA: # %bb.0: ; RV64IZBA: # %bb.0:
; RV64IZBA-NEXT: lui a0, 1047615 ; RV64IZBA-NEXT: lui a0, 611378
; RV64IZBA-NEXT: addiw a0, a0, 1475 ; RV64IZBA-NEXT: addiw a0, a0, 265
; RV64IZBA-NEXT: slli a0, a0, 12 ; RV64IZBA-NEXT: sh3add a0, a0, a0
; RV64IZBA-NEXT: addi a0, a0, -1711
; RV64IZBA-NEXT: ret ; RV64IZBA-NEXT: ret
; ;
; RV64IZBS-LABEL: imm_neg_16116864687: ; RV64IZBS-LABEL: imm_neg_16116864687:
@ -1447,10 +1442,9 @@ define i64 @imm_neg_2863311530() {
; ;
; RV64IZBA-LABEL: imm_neg_2863311530: ; RV64IZBA-LABEL: imm_neg_2863311530:
; RV64IZBA: # %bb.0: ; RV64IZBA: # %bb.0:
; RV64IZBA-NEXT: lui a0, 1048405 ; RV64IZBA-NEXT: lui a0, 908766
; RV64IZBA-NEXT: addiw a0, a0, 1365 ; RV64IZBA-NEXT: addiw a0, a0, -546
; RV64IZBA-NEXT: slli a0, a0, 12 ; RV64IZBA-NEXT: sh2add a0, a0, a0
; RV64IZBA-NEXT: addi a0, a0, 1366
; RV64IZBA-NEXT: ret ; RV64IZBA-NEXT: ret
; ;
; RV64IZBS-LABEL: imm_neg_2863311530: ; RV64IZBS-LABEL: imm_neg_2863311530:

View File

@ -46,3 +46,43 @@ li x5, 0xbbbbb0007bb
# CHECK-S-OBJ: lui t0, 768955 # CHECK-S-OBJ: lui t0, 768955
# CHECK-S-OBJ-NEXT: slli.uw t0, t0, 4 # CHECK-S-OBJ-NEXT: slli.uw t0, t0, 4
li x5, 0xbbbbb0000 li x5, 0xbbbbb0000
# CHECK-S-OBJ-NOALIAS: lui t1, 611378
# CHECK-S-OBJ-NOALIAS-NEXT: addiw t1, t1, 265
# CHECK-S-OBJ-NOALIAS-NEXT: sh1add t1, t1, t1
# CHECK-S-OBJ: lui t1, 611378
# CHECK-S-OBJ-NEXT: addiw t1, t1, 265
# CHECK-S-OBJ-NEXT: sh1add t1, t1, t1
li x6, -5372288229
# CHECK-S-OBJ-NOALIAS: lui t1, 437198
# CHECK-S-OBJ-NOALIAS-NEXT: addiw t1, t1, -265
# CHECK-S-OBJ-NOALIAS-NEXT: sh2add t1, t1, t1
# CHECK-S-OBJ: lui t1, 437198
# CHECK-S-OBJ-NEXT: addiw t1, t1, -265
# CHECK-S-OBJ-NEXT: sh2add t1, t1, t1
li x6, 8953813715
# CHECK-S-OBJ-NOALIAS: lui t1, 611378
# CHECK-S-OBJ-NOALIAS-NEXT: addiw t1, t1, 265
# CHECK-S-OBJ-NOALIAS-NEXT: sh2add t1, t1, t1
# CHECK-S-OBJ: lui t1, 611378
# CHECK-S-OBJ-NEXT: addiw t1, t1, 265
# CHECK-S-OBJ-NEXT: sh2add t1, t1, t1
li x6, -8953813715
# CHECK-S-OBJ-NOALIAS: lui t1, 437198
# CHECK-S-OBJ-NOALIAS-NEXT: addiw t1, t1, -265
# CHECK-S-OBJ-NOALIAS-NEXT: sh3add t1, t1, t1
# CHECK-S-OBJ: lui t1, 437198
# CHECK-S-OBJ-NEXT: addiw t1, t1, -265
# CHECK-S-OBJ-NEXT: sh3add t1, t1, t1
li x6, 16116864687
# CHECK-S-OBJ-NOALIAS: lui t1, 611378
# CHECK-S-OBJ-NOALIAS-NEXT: addiw t1, t1, 265
# CHECK-S-OBJ-NOALIAS-NEXT: sh3add t1, t1, t1
# CHECK-S-OBJ: lui t1, 611378
# CHECK-S-OBJ-NEXT: addiw t1, t1, 265
# CHECK-S-OBJ-NEXT: sh3add t1, t1, t1
li x6, -16116864687