diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -455,6 +455,11 @@ } else if (MIFrm == RISCVII::InstFormatI) { FixupKind = RISCV::fixup_riscv_12_i; } + } else if (Kind == MCExpr::Binary && + cast(Expr)->getOpcode() == MCBinaryExpr::Sub) { + // Needed to support "li xi, a-b" which is translated to "addi xi, x0, a-b" + if (MIFrm == RISCVII::InstFormatI) + FixupKind = RISCV::fixup_riscv_12_i; } assert(FixupKind != RISCV::fixup_riscv_invalid && "Unhandled expression!"); diff --git a/llvm/test/MC/RISCV/fixups-invalid.s b/llvm/test/MC/RISCV/fixups-invalid.s --- a/llvm/test/MC/RISCV/fixups-invalid.s +++ b/llvm/test/MC/RISCV/fixups-invalid.s @@ -13,3 +13,5 @@ .equ CONST, .Lbuf_end - .Lbuf # CHECK: error: operand must be a constant 12-bit integer li a0, CONST +# CHECK: error: operand must be a constant 12-bit integer +li a0, .Lbuf_end - .Lbuf diff --git a/llvm/test/MC/RISCV/rv32i-aliases-valid.s b/llvm/test/MC/RISCV/rv32i-aliases-valid.s --- a/llvm/test/MC/RISCV/rv32i-aliases-valid.s +++ b/llvm/test/MC/RISCV/rv32i-aliases-valid.s @@ -113,6 +113,11 @@ # CHECK-OBJ-NOALIAS: addi a0, zero, 8 li a0, CONST +# CHECK-ASM: addi a0, zero, .Lbuf_end-.Lbuf +# CHECK-ASM-NOALIAS: addi a0, zero, .Lbuf_end-.Lbuf +# CHECK-OBJ-NOALIAS: addi a0, zero, 8 +li a0, .Lbuf_end - .Lbuf + # CHECK-INST: addi a0, zero, 0 # CHECK-ALIAS: li a0, 0 la x10, 0 diff --git a/llvm/test/MC/RISCV/rv64i-aliases-valid.s b/llvm/test/MC/RISCV/rv64i-aliases-valid.s --- a/llvm/test/MC/RISCV/rv64i-aliases-valid.s +++ b/llvm/test/MC/RISCV/rv64i-aliases-valid.s @@ -225,6 +225,11 @@ # CHECK-OBJ-NOALIAS: addi a0, zero, 8 li a0, CONST +# CHECK-ASM: addi a0, zero, .Lbuf_end-.Lbuf +# CHECK-ASM-NOALIAS: addi a0, zero, .Lbuf_end-.Lbuf +# CHECK-OBJ-NOALIAS: addi a0, zero, 8 +li a0, .Lbuf_end - .Lbuf + # CHECK-INST: addi a0, zero, 0 # CHECK-ALIAS: li a0, 0 la x10, 0