Author: Pengcheng Wang Date: 2026-03-23T03:12:38Z New Revision: 8efb87ae5a53383d3ea3bc6e8a7ed851c31b45d7
URL: https://github.com/llvm/llvm-project/commit/8efb87ae5a53383d3ea3bc6e8a7ed851c31b45d7 DIFF: https://github.com/llvm/llvm-project/commit/8efb87ae5a53383d3ea3bc6e8a7ed851c31b45d7.diff LOG: [RISCV] Relax out of range Zibi conditional branches (#186965) If `.Label` is not within +-4KiB range, we convert ``` beqi/bnei reg, imm, .Label ``` to ``` bnei/beqi reg, imm, 8 j .Label ``` This is similar to what is done for the RISCV conditional branches and `Xqcibi` conditional branches. --------- Co-authored-by: Sudharsan Veeravalli <[email protected]> Added: llvm/test/MC/RISCV/zibi-long-conditional-jump.s Modified: llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp llvm/lib/Target/RISCV/RISCVInstrInfo.td llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td llvm/lib/Target/RISCV/RISCVInstrInfoZibi.td Removed: ################################################################################ diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp index 584c000519b20..03ee683fd3ef3 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -196,6 +196,10 @@ static unsigned getRelaxedOpcode(unsigned Opcode, ArrayRef<MCOperand> Operands, return RISCV::PseudoLongBEQ; case RISCV::BNE: return RISCV::PseudoLongBNE; + case RISCV::BEQI: + return RISCV::PseudoLongBEQI; + case RISCV::BNEI: + return RISCV::PseudoLongBNEI; case RISCV::BLT: return RISCV::PseudoLongBLT; case RISCV::BGE: @@ -285,6 +289,8 @@ void RISCVAsmBackend::relaxInstruction(MCInst &Inst, } case RISCV::BEQ: case RISCV::BNE: + case RISCV::BEQI: + case RISCV::BNEI: case RISCV::BLT: case RISCV::BGE: case RISCV::BLTU: diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp index 5cf1f296d4f72..da63bb47c6311 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -255,6 +255,10 @@ static unsigned getInvertedBranchOp(unsigned BrOp) { return RISCV::BNE; case RISCV::PseudoLongBNE: return RISCV::BEQ; + case RISCV::PseudoLongBEQI: + return RISCV::BNEI; + case RISCV::PseudoLongBNEI: + return RISCV::BEQI; case RISCV::PseudoLongBLT: return RISCV::BGE; case RISCV::PseudoLongBGE: @@ -297,14 +301,15 @@ void RISCVMCCodeEmitter::expandLongCondBr(const MCInst &MI, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { MCRegister SrcReg1 = MI.getOperand(0).getReg(); - MCRegister SrcReg2 = MI.getOperand(1).getReg(); - MCOperand SrcSymbol = MI.getOperand(2); + const MCOperand &Src2 = MI.getOperand(1); + const MCOperand &SrcSymbol = MI.getOperand(2); unsigned Opcode = MI.getOpcode(); bool IsEqTest = Opcode == RISCV::PseudoLongBNE || Opcode == RISCV::PseudoLongBEQ; bool UseCompressedBr = false; if (IsEqTest && STI.hasFeature(RISCV::FeatureStdExtZca)) { + MCRegister SrcReg2 = Src2.getReg(); if (RISCV::X8 <= SrcReg1.id() && SrcReg1.id() <= RISCV::X15 && SrcReg2.id() == RISCV::X0) { UseCompressedBr = true; @@ -326,7 +331,7 @@ void RISCVMCCodeEmitter::expandLongCondBr(const MCInst &MI, } else { unsigned InvOpc = getInvertedBranchOp(Opcode); MCInst TmpInst = - MCInstBuilder(InvOpc).addReg(SrcReg1).addReg(SrcReg2).addImm(8); + MCInstBuilder(InvOpc).addReg(SrcReg1).addOperand(Src2).addImm(8); uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); support::endian::write(CB, Binary, llvm::endianness::little); Offset = 4; @@ -429,6 +434,8 @@ void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI, return; case RISCV::PseudoLongBEQ: case RISCV::PseudoLongBNE: + case RISCV::PseudoLongBEQI: + case RISCV::PseudoLongBNEI: case RISCV::PseudoLongBLT: case RISCV::PseudoLongBGE: case RISCV::PseudoLongBLTU: diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index 708414496f4b6..ff582b8e741cd 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -1744,6 +1744,20 @@ class LongBccPseudo : Pseudo<(outs), let hasNoSchedulingInfo = 1; } +class LongBcciPseudo<DAGOperand InTyImm, int size> + : Pseudo<(outs), + (ins GPR:$rs1, InTyImm:$imm, simm21_lsb0_jal:$imm20), + []> { + let Size = size; + let isBarrier = 1; + let isBranch = 1; + let hasSideEffects = 0; + let mayStore = 0; + let mayLoad = 0; + let isAsmParserOnly = 1; + let hasNoSchedulingInfo = 1; +} + def PseudoLongBEQ : LongBccPseudo; def PseudoLongBNE : LongBccPseudo; def PseudoLongBLT : LongBccPseudo; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td index eae92c43aae39..74e987d88f19d 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td @@ -1335,19 +1335,6 @@ let EmitPriority = 1 in { // Pseudo-instructions //===----------------------------------------------------------------------===// -class LongBcciPseudo<DAGOperand InTyImm, int size> - : Pseudo<(outs), (ins GPR:$rs1, InTyImm:$imm, simm21_lsb0_jal:$imm20), []> -{ - let Size = size; - let isBarrier = 1; - let isBranch = 1; - let hasSideEffects = 0; - let mayStore = 0; - let mayLoad = 0; - let isAsmParserOnly = 1; - let hasNoSchedulingInfo = 1; -} - // This will be expanded into either: // QC.BXXX(4 bytes) + JAL(4 bytes) // or diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZibi.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZibi.td index 412bb08b00929..0ffb6b963790b 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZibi.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZibi.td @@ -41,6 +41,11 @@ class Branch_imm<bits<3> funct3, string opcodestr> let Predicates = [HasStdExtZibi] in { def BEQI : Branch_imm<0b010, "beqi">; def BNEI : Branch_imm<0b011, "bnei">; + + // For long branch relaxation. + // This will be expanded into BEQI/BNEI(4 bytes) + JAL(4 bytes). + def PseudoLongBEQI : LongBcciPseudo<imm5_zibi, 8>; + def PseudoLongBNEI : LongBcciPseudo<imm5_zibi, 8>; } // Predicates = [HasStdExtZibi] multiclass BccImmPat<CondCode Cond, Branch_imm Inst> { diff --git a/llvm/test/MC/RISCV/zibi-long-conditional-jump.s b/llvm/test/MC/RISCV/zibi-long-conditional-jump.s new file mode 100644 index 0000000000000..dc90a5d0b9055 --- /dev/null +++ b/llvm/test/MC/RISCV/zibi-long-conditional-jump.s @@ -0,0 +1,110 @@ +# RUN: llvm-mc -filetype=obj --mattr=+experimental-zibi -triple=riscv32 %s \ +# RUN: | llvm-objdump --mattr=+experimental-zibi -d -M no-aliases - \ +# RUN: | FileCheck --check-prefix=CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+relax,+experimental-zibi %s \ +# RUN: | llvm-objdump --mattr=+experimental-zibi -dr -M no-aliases - \ +# RUN: | FileCheck --check-prefix=CHECK-INST-RELAX %s + +# Tests that are forward in range. + +# CHECK-INST-LABEL: beqi_in_range_forward +# CHECK-INST: beqi a0, 0xa, {{.*}} + +# CHECK-INST-RELAX-LABEL: beqi_in_range_forward +# CHECK-INST-RELAX: beqi a0, 0xa, {{.*}} +beqi_in_range_forward: + beqi a0, 10, .L1 + .fill 1000, 4, 0 +.L1: + ret + +# CHECK-INST-LABEL: bnei_in_range_forward +# CHECK-INST: bnei a0, 0xa, {{.*}} + +# CHECK-INST-RELAX-LABEL: bnei_in_range_forward +# CHECK-INST-RELAX: bnei a0, 0xa, {{.*}} +bnei_in_range_forward: + bnei a0, 10, .L2 + .fill 1000, 4, 0 +.L2: + ret + +# Tests that are backward in range. + +# CHECK-INST-LABEL: beqi_in_range_backward +# CHECK-INST: beqi a0, 0xa, {{.*}} + +# CHECK-INST-RELAX-LABEL: beqi_in_range_backward +# CHECK-INST-RELAX: beqi a0, 0xa, {{.*}} +beqi_in_range_backward: +.L3: + .fill 1000, 4, 0 + beqi a0, 10, .L3 + ret + +# CHECK-INST-LABEL: bnei_in_range_backward +# CHECK-INST: bnei a0, 0xa, {{.*}} + +# CHECK-INST-RELAX-LABEL: bnei_in_range_backward +# CHECK-INST-RELAX: bnei a0, 0xa, {{.*}} +bnei_in_range_backward: +.L4: + .fill 1000, 4, 0 + bnei a0, 10, .L4 + ret + +# Tests that are forward out of range. + +# CHECK-INST-LABEL: beqi_out_of_range_forward +# CHECK-INST: bnei a0, 0xa, {{.*}}+0x8 +# CHECK-INST-NEXT: jal zero, {{.*}} + +# CHECK-INST-RELAX-LABEL: beqi_out_of_range_forward +# CHECK-INST-RELAX: bnei a0, 0xa, {{.*}}+0x8 +# CHECK-INST-RELAX-NEXT: jal zero, {{.*}} +beqi_out_of_range_forward: + beqi a0, 10, .L5 + .fill 1300, 4, 0 +.L5: + ret + +# CHECK-INST-LABEL: bnei_out_of_range_forward +# CHECK-INST: beqi a0, 0xa, {{.*}}+0x8 +# CHECK-INST-NEXT: jal zero, {{.*}} + +# CHECK-INST-RELAX-LABEL: bnei_out_of_range_forward +# CHECK-INST-RELAX: beqi a0, 0xa, {{.*}}+0x8 +# CHECK-INST-RELAX-NEXT: jal zero, {{.*}} +bnei_out_of_range_forward: + bnei a0, 10, .L6 + .fill 1300, 4, 0 +.L6: + ret + +# Tests that are backward out of range. + +# CHECK-INST-LABEL: beqi_out_of_range_backward +# CHECK-INST: bnei a0, 0xa, {{.*}}+0x1458 +# CHECK-INST-NEXT: jal zero, {{.*}} + +# CHECK-INST-RELAX-LABEL: beqi_out_of_range_backward +# CHECK-INST-RELAX: bnei a0, 0xa, {{.*}}+0x1458 +# CHECK-INST-RELAX-NEXT: jal zero, {{.*}} +beqi_out_of_range_backward: +.L7: + .fill 1300, 4, 0 + beqi a0, 10, .L7 + ret + +# CHECK-INST-LABEL: bnei_out_of_range_backward +# CHECK-INST: beqi a0, 0xa, {{.*}}+0x1458 +# CHECK-INST-NEXT: jal zero, {{.*}} + +# CHECK-INST-RELAX-LABEL: bnei_out_of_range_backward +# CHECK-INST-RELAX: beqi a0, 0xa, {{.*}}+0x1458 +# CHECK-INST-RELAX-NEXT: jal zero, {{.*}} +bnei_out_of_range_backward: +.L8: + .fill 1300, 4, 0 + bnei a0, 10, .L8 + ret _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
