Index: llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp =================================================================== --- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -2269,6 +2269,11 @@ .addReg(DestReg) .addReg(SrcReg) .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 { emitToStreamer( Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm( Index: llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp =================================================================== --- llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp +++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp @@ -182,6 +182,33 @@ } } + // Try to generate (SH*ADD r, r), in which r is an int32. + 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; } Index: llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp =================================================================== --- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -140,6 +140,9 @@ else if (Inst.Opc == RISCV::ADDUW) Result = CurDAG->getMachineNode(RISCV::ADDUW, DL, XLenVT, SrcReg, 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 Result = CurDAG->getMachineNode(Inst.Opc, DL, XLenVT, SrcReg, SDImm); Index: llvm/lib/Target/RISCV/RISCVInstrInfo.cpp =================================================================== --- llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -458,6 +458,12 @@ .addReg(SrcReg, RegState::Kill) .addReg(RISCV::X0) .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 { BuildMI(MBB, MBBI, DL, get(Inst.Opc), Result) .addReg(SrcReg, RegState::Kill) Index: llvm/test/CodeGen/RISCV/imm.ll =================================================================== --- llvm/test/CodeGen/RISCV/imm.ll +++ llvm/test/CodeGen/RISCV/imm.ll @@ -928,10 +928,9 @@ ; ; RV64IZBA-LABEL: imm_5372288229: ; RV64IZBA: # %bb.0: -; RV64IZBA-NEXT: lui a0, 160 -; RV64IZBA-NEXT: addiw a0, a0, 437 -; RV64IZBA-NEXT: slli a0, a0, 13 -; RV64IZBA-NEXT: addi a0, a0, -795 +; RV64IZBA-NEXT: lui a0, 437198 +; RV64IZBA-NEXT: addiw a0, a0, -265 +; RV64IZBA-NEXT: sh1add a0, a0, a0 ; RV64IZBA-NEXT: ret ; ; RV64IZBS-LABEL: imm_5372288229: @@ -962,10 +961,9 @@ ; ; RV64IZBA-LABEL: imm_neg_5372288229: ; RV64IZBA: # %bb.0: -; RV64IZBA-NEXT: lui a0, 1048416 -; RV64IZBA-NEXT: addiw a0, a0, -437 -; RV64IZBA-NEXT: slli a0, a0, 13 -; RV64IZBA-NEXT: addi a0, a0, 795 +; RV64IZBA-NEXT: lui a0, 611378 +; RV64IZBA-NEXT: addiw a0, a0, 265 +; RV64IZBA-NEXT: sh1add a0, a0, a0 ; RV64IZBA-NEXT: ret ; ; RV64IZBS-LABEL: imm_neg_5372288229: @@ -996,10 +994,9 @@ ; ; RV64IZBA-LABEL: imm_8953813715: ; RV64IZBA: # %bb.0: -; RV64IZBA-NEXT: lui a0, 267 -; RV64IZBA-NEXT: addiw a0, a0, -637 -; RV64IZBA-NEXT: slli a0, a0, 13 -; RV64IZBA-NEXT: addi a0, a0, -1325 +; RV64IZBA-NEXT: lui a0, 437198 +; RV64IZBA-NEXT: addiw a0, a0, -265 +; RV64IZBA-NEXT: sh2add a0, a0, a0 ; RV64IZBA-NEXT: ret ; ; RV64IZBS-LABEL: imm_8953813715: @@ -1030,10 +1027,9 @@ ; ; RV64IZBA-LABEL: imm_neg_8953813715: ; RV64IZBA: # %bb.0: -; RV64IZBA-NEXT: lui a0, 1048309 -; RV64IZBA-NEXT: addiw a0, a0, 637 -; RV64IZBA-NEXT: slli a0, a0, 13 -; RV64IZBA-NEXT: addi a0, a0, 1325 +; RV64IZBA-NEXT: lui a0, 611378 +; RV64IZBA-NEXT: addiw a0, a0, 265 +; RV64IZBA-NEXT: sh2add a0, a0, a0 ; RV64IZBA-NEXT: ret ; ; RV64IZBS-LABEL: imm_neg_8953813715: @@ -1064,10 +1060,9 @@ ; ; RV64IZBA-LABEL: imm_16116864687: ; RV64IZBA: # %bb.0: -; RV64IZBA-NEXT: lui a0, 961 -; RV64IZBA-NEXT: addiw a0, a0, -1475 -; RV64IZBA-NEXT: slli a0, a0, 12 -; RV64IZBA-NEXT: addi a0, a0, 1711 +; RV64IZBA-NEXT: lui a0, 437198 +; RV64IZBA-NEXT: addiw a0, a0, -265 +; RV64IZBA-NEXT: sh3add a0, a0, a0 ; RV64IZBA-NEXT: ret ; ; RV64IZBS-LABEL: imm_16116864687: @@ -1098,10 +1093,9 @@ ; ; RV64IZBA-LABEL: imm_neg_16116864687: ; RV64IZBA: # %bb.0: -; RV64IZBA-NEXT: lui a0, 1047615 -; RV64IZBA-NEXT: addiw a0, a0, 1475 -; RV64IZBA-NEXT: slli a0, a0, 12 -; RV64IZBA-NEXT: addi a0, a0, -1711 +; RV64IZBA-NEXT: lui a0, 611378 +; RV64IZBA-NEXT: addiw a0, a0, 265 +; RV64IZBA-NEXT: sh3add a0, a0, a0 ; RV64IZBA-NEXT: ret ; ; RV64IZBS-LABEL: imm_neg_16116864687: @@ -1470,10 +1464,9 @@ ; ; RV64IZBA-LABEL: imm_neg_2863311530: ; RV64IZBA: # %bb.0: -; RV64IZBA-NEXT: lui a0, 1048405 -; RV64IZBA-NEXT: addiw a0, a0, 1365 -; RV64IZBA-NEXT: slli a0, a0, 12 -; RV64IZBA-NEXT: addi a0, a0, 1366 +; RV64IZBA-NEXT: lui a0, 908766 +; RV64IZBA-NEXT: addiw a0, a0, -546 +; RV64IZBA-NEXT: sh2add a0, a0, a0 ; RV64IZBA-NEXT: ret ; ; RV64IZBS-LABEL: imm_neg_2863311530: Index: llvm/test/MC/RISCV/rv64zba-aliases-valid.s =================================================================== --- llvm/test/MC/RISCV/rv64zba-aliases-valid.s +++ llvm/test/MC/RISCV/rv64zba-aliases-valid.s @@ -32,3 +32,51 @@ # CHECK-S-OBJ-NEXT: addiw t2, t2, -1366 # CHECK-S-OBJ-NEXT: zext.w t2, t2 li x7, 0xaaaaaaaa + +# CHECK-S-OBJ-NOALIAS: lui t1, 437198 +# CHECK-S-OBJ-NOALIAS-NEXT: addiw t1, t1, -265 +# CHECK-S-OBJ-NOALIAS-NEXT: sh1add t1, t1, t1 +# CHECK-S-OBJ: lui t1, 437198 +# 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, 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