Author: Craig Topper Date: 2022-04-25T15:30:48-07:00 New Revision: 50c6ba751fa2c3ae8854ba09229bda62b3617c55
URL: https://github.com/llvm/llvm-project/commit/50c6ba751fa2c3ae8854ba09229bda62b3617c55 DIFF: https://github.com/llvm/llvm-project/commit/50c6ba751fa2c3ae8854ba09229bda62b3617c55.diff LOG: [RISCV] Only try LUI+SH*ADD+ADDI for int materialization if LUI+ADDI+SH*ADD failed. There's an assert in LUI+SH*ADD+ADDI materialization that makes sure the lower 12 bits aren't zero since that case should have been handled as LUI+ADDI+SH*ADD. But nothing prevented the LUI+SH*ADD+ADDI checks from running after the earlier code handled it. The sequence would be the same length or longer so it wouldn't replace the earlier sequence, but the assert happened before that was checked. The vector holding the sequence also wasn't reset before the second check so that guaranteed the sequence would never be found to be shorter. This patch fixes this by only trying the second expansion when the earlier fails. Fixes PR54812. Reviewed By: benshi001 Differential Revision: https://reviews.llvm.org/D123406 (cherry picked from commit 70046438d02ba1ec6bc2e2fc496b610cc1068b0f) Added: Modified: llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp llvm/test/CodeGen/RISCV/imm.ll Removed: ################################################################################ diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp index e935179e5f9b0..4adcd25600f20 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp @@ -302,32 +302,34 @@ InstSeq generateInstSeq(int64_t Val, const FeatureBitset &ActiveFeatures) { 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 index 5de49d8a7f2cb..9fa688b6f75d5 100644 --- a/llvm/test/CodeGen/RISCV/imm.ll +++ b/llvm/test/CodeGen/RISCV/imm.ll @@ -2401,3 +2401,39 @@ define i64 @li_rori_3() { ; 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; +} _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits