diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp @@ -302,32 +302,34 @@ TmpSeq.push_back(RISCVMatInt::Inst(Opc, 0)); if (TmpSeq.size() < Res.size()) Res = TmpSeq; - } - // Try to use LUI+SH*ADD+ADDI. - int64_t Hi52 = ((uint64_t)Val + 0x800ull) & ~0xfffull; - int64_t Lo12 = SignExtend64<12>(Val); - Div = 0; - if (isInt<32>(Hi52 / 3) && (Hi52 % 3) == 0) { - Div = 3; - Opc = RISCV::SH1ADD; - } else if (isInt<32>(Hi52 / 5) && (Hi52 % 5) == 0) { - Div = 5; - Opc = RISCV::SH2ADD; - } else if (isInt<32>(Hi52 / 9) && (Hi52 % 9) == 0) { - Div = 9; - Opc = RISCV::SH3ADD; - } - // Build the new instruction sequence. - if (Div > 0) { - // For Val that has zero Lo12 (implies Val equals to Hi52) should has - // already been processed to LUI+SH*ADD by previous optimization. - assert(Lo12 != 0 && - "unexpected instruction sequence for immediate materialisation"); - generateInstSeqImpl(Hi52 / Div, ActiveFeatures, TmpSeq); - TmpSeq.push_back(RISCVMatInt::Inst(Opc, 0)); - TmpSeq.push_back(RISCVMatInt::Inst(RISCV::ADDI, Lo12)); - if (TmpSeq.size() < Res.size()) - Res = TmpSeq; + } else { + // Try to use LUI+SH*ADD+ADDI. + int64_t Hi52 = ((uint64_t)Val + 0x800ull) & ~0xfffull; + int64_t Lo12 = SignExtend64<12>(Val); + Div = 0; + if (isInt<32>(Hi52 / 3) && (Hi52 % 3) == 0) { + Div = 3; + Opc = RISCV::SH1ADD; + } else if (isInt<32>(Hi52 / 5) && (Hi52 % 5) == 0) { + Div = 5; + Opc = RISCV::SH2ADD; + } else if (isInt<32>(Hi52 / 9) && (Hi52 % 9) == 0) { + Div = 9; + Opc = RISCV::SH3ADD; + } + // Build the new instruction sequence. + if (Div > 0) { + // For Val that has zero Lo12 (implies Val equals to Hi52) should has + // already been processed to LUI+SH*ADD by previous optimization. + assert(Lo12 != 0 && + "unexpected instruction sequence for immediate materialisation"); + assert(TmpSeq.empty() && "Expected empty TmpSeq"); + generateInstSeqImpl(Hi52 / Div, ActiveFeatures, TmpSeq); + TmpSeq.push_back(RISCVMatInt::Inst(Opc, 0)); + TmpSeq.push_back(RISCVMatInt::Inst(RISCV::ADDI, Lo12)); + if (TmpSeq.size() < Res.size()) + Res = TmpSeq; + } } } diff --git a/llvm/test/CodeGen/RISCV/imm.ll b/llvm/test/CodeGen/RISCV/imm.ll --- a/llvm/test/CodeGen/RISCV/imm.ll +++ b/llvm/test/CodeGen/RISCV/imm.ll @@ -2401,3 +2401,39 @@ ; RV64IZBS-NEXT: ret ret i64 -2281701377 } + +; This used to assert when compiled with Zba. +define i64 @PR54812() { +; RV32I-LABEL: PR54812: +; RV32I: # %bb.0: +; RV32I-NEXT: lui a0, 521599 +; RV32I-NEXT: li a1, -1 +; RV32I-NEXT: ret +; +; RV64I-LABEL: PR54812: +; RV64I: # %bb.0: +; RV64I-NEXT: lui a0, 1048447 +; RV64I-NEXT: addiw a0, a0, 1407 +; RV64I-NEXT: slli a0, a0, 12 +; RV64I-NEXT: ret +; +; RV64IZBA-LABEL: PR54812: +; RV64IZBA: # %bb.0: +; RV64IZBA-NEXT: lui a0, 872917 +; RV64IZBA-NEXT: sh1add a0, a0, a0 +; RV64IZBA-NEXT: ret +; +; RV64IZBB-LABEL: PR54812: +; RV64IZBB: # %bb.0: +; RV64IZBB-NEXT: lui a0, 1048447 +; RV64IZBB-NEXT: addiw a0, a0, 1407 +; RV64IZBB-NEXT: slli a0, a0, 12 +; RV64IZBB-NEXT: ret +; +; RV64IZBS-LABEL: PR54812: +; RV64IZBS: # %bb.0: +; RV64IZBS-NEXT: lui a0, 1045887 +; RV64IZBS-NEXT: bclri a0, a0, 31 +; RV64IZBS-NEXT: ret + ret i64 -2158497792; +}