blt
blt
rs1, rs2, label
if (rs1 < rs2) goto label
R
31–25funct7
24–20rs2
19–15rs1
14–12funct3
11–7rd
6–0opcode
I
31–20imm[11:0]
19–15rs1
14–12funct3
11–7rd
6–0opcode
S
31–25imm[11:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:0]
6–0opcode
B
31–25imm[12,10:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:1,11]
6–0opcode
U
31–12imm[31:12]
11–7rd
6–0opcode
J
31–12imm[20,10:1,11,19:12]
11–7rd
6–0opcode

Where beq and bne test whether two values are equal, blt tests which is *bigger*. The name is branch if less than: blt rs1, rs2, label jumps to the labelled position when rs1 is less than rs2, and otherwise continues to the next instruction. (The beq page covers branches, labels, and how a jump works, if those are new.)

This comparison is signed, meaning the values are read as numbers that can be negative: -1 counts as less than 0, and a negative number is less than any positive one. That signed reading is the defining feature, and it is why a separate instruction bltu exists for the unsigned case — the two can disagree completely on values whose top bit is set.

The everyday use is controlling a counting loop: blt t0, t1, loop keeps repeating as long as a counter t0 is still below its limit t1. The moment the counter reaches the limit, the branch stops firing and the loop ends. The other common use is bounds-checking — making sure a number stays under some maximum before trusting it.

You may notice RISC-V offers no branch if greater. None is needed: to ask whether a is greater than b, just compare the other way and ask whether b is less than a. The assembler even provides a bgt shorthand that does this swap for you behind the scenes.