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 @@ -442,8 +442,11 @@ RelaxCandidate = true; break; } - } else if (Kind == MCExpr::SymbolRef && - cast(Expr)->getKind() == MCSymbolRefExpr::VK_None) { + } else if ((Kind == MCExpr::SymbolRef && + cast(Expr)->getKind() == + MCSymbolRefExpr::VK_None) || + Kind == MCExpr::Binary) { + // FIXME: Sub kind binary exprs have chance of underflow. if (MIFrm == RISCVII::InstFormatJ) { FixupKind = RISCV::fixup_riscv_jal; } else if (MIFrm == RISCVII::InstFormatB) { diff --git a/llvm/test/MC/RISCV/fixups-binary-expression.s b/llvm/test/MC/RISCV/fixups-binary-expression.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/fixups-binary-expression.s @@ -0,0 +1,31 @@ +# RUN: llvm-mc -triple riscv32 -mattr=+c -riscv-no-aliases < %s -show-encoding \ +# RUN: | FileCheck -check-prefix=CHECK-FIXUP %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+c < %s \ +# RUN: | llvm-objdump -M no-aliases -d - \ +# RUN: | FileCheck -check-prefix=CHECK-INSTR %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+c,+relax < %s \ +# RUN: | llvm-readobj -r - | FileCheck -check-prefix=CHECK-RELOC %s + +.LBB0: + +.LBB1: + +jal zero, .LBB0+16 +# CHECK-FIXUP: fixup A - offset: 0, value: .LBB0+16, kind: fixup_riscv_jal +# CHECK-INSTR: jal zero, 0x10 +# CHECK-RELOC: R_RISCV_JAL + +beq a0, a1, .LBB1+32 +# CHECK-FIXUP: fixup A - offset: 0, value: .LBB1+32, kind: fixup_riscv_branch +# CHECK-INSTR: beq a0, a1, 0x20 +# CHECK-RELOC: R_RISCV_BRANCH + +c.j .+32 +# CHECK: fixup A - offset: 0, value: .Ltmp0+32, kind: fixup_riscv_rvc_jump +# CHECK-INSTR: c.j 0x28 +# CHECK-RELOC: R_RISCV_RVC_JUMP + +c.beqz a0, .-2 +# CHECK-FIXUP: fixup A - offset: 0, value: .Ltmp1-2, kind: fixup_riscv_rvc_branch +# CHECK-INSTR: c.beqz a0, 0x8 +# CHECK-RELOC: R_RISCV_RVC_BRANCH 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