Index: llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp =================================================================== --- llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp +++ llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -204,6 +204,7 @@ const MCExpr *Expr = MO.getExpr(); MCExpr::ExprKind Kind = Expr->getKind(); RISCV::Fixups FixupKind = RISCV::fixup_riscv_invalid; + bool RelaxCandidate = false; if (Kind == MCExpr::Target) { const RISCVMCExpr *RVExpr = cast(Expr); @@ -218,9 +219,11 @@ FixupKind = RISCV::fixup_riscv_lo12_s; else llvm_unreachable("VK_RISCV_LO used with unexpected instruction format"); + RelaxCandidate = true; break; case RISCVMCExpr::VK_RISCV_HI: FixupKind = RISCV::fixup_riscv_hi20; + RelaxCandidate = true; break; case RISCVMCExpr::VK_RISCV_PCREL_LO: if (MIFrm == RISCVII::InstFormatI) @@ -230,12 +233,15 @@ else llvm_unreachable( "VK_RISCV_PCREL_LO used with unexpected instruction format"); + RelaxCandidate = true; break; case RISCVMCExpr::VK_RISCV_PCREL_HI: FixupKind = RISCV::fixup_riscv_pcrel_hi20; + RelaxCandidate = true; break; case RISCVMCExpr::VK_RISCV_CALL: FixupKind = RISCV::fixup_riscv_call; + RelaxCandidate = true; break; } } else if (Kind == MCExpr::SymbolRef && @@ -257,13 +263,15 @@ MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc())); ++MCNumFixups; - if (EnableRelax) { - if (FixupKind == RISCV::fixup_riscv_call) { - Fixups.push_back( - MCFixup::create(0, Expr, MCFixupKind(RISCV::fixup_riscv_relax), - MI.getLoc())); - ++MCNumFixups; - } + // Ensure an R_RISCV_RELAX relocation will be emitted if linker relaxation is + // enabled and the current fixup will result in a relocation that may be + // relaxed. + if (EnableRelax && RelaxCandidate) { + const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx); + Fixups.push_back( + MCFixup::create(0, Dummy, MCFixupKind(RISCV::fixup_riscv_relax), + MI.getLoc())); + ++MCNumFixups; } return 0; Index: llvm/trunk/test/MC/RISCV/linker-relaxation.s =================================================================== --- llvm/trunk/test/MC/RISCV/linker-relaxation.s +++ llvm/trunk/test/MC/RISCV/linker-relaxation.s @@ -18,9 +18,58 @@ # NORELAX-RELOC: R_RISCV_CALL foo 0x0 # NORELAX-RELOC-NOT: R_RISCV_RELAX # RELAX-RELOC: R_RISCV_CALL foo 0x0 -# RELAX-RELOC: R_RISCV_RELAX foo 0x0 +# RELAX-RELOC: R_RISCV_RELAX - 0x0 # RELAX-FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_call -# RELAX-FIXUP: fixup B - offset: 0, value: foo, kind: fixup_riscv_relax +# RELAX-FIXUP: fixup B - offset: 0, value: 0, kind: fixup_riscv_relax beq s1, s1, .L1 # RELAX-RELOC: R_RISCV_BRANCH .L1 0x0 # RELAX-FIXUP: fixup A - offset: 0, value: .L1, kind: fixup_riscv_branch +# RELAX-FIXUP-NOT: fixup B - offset: 0, value: 0, kind: fixup_riscv_relax + +lui t1, %hi(foo) +# NORELAX-RELOC: R_RISCV_HI20 foo 0x0 +# NORELAX-RELOC-NOT: R_RISCV_RELAX +# RELOC: R_RISCV_HI20 foo 0x0 +# RELAX-RELOC: R_RISCV_RELAX - 0x0 +# RELAX-FIXUP: fixup A - offset: 0, value: %hi(foo), kind: fixup_riscv_hi20 +# RELAX-FIXUP: fixup B - offset: 0, value: 0, kind: fixup_riscv_relax + +addi t1, t1, %lo(foo) +# NORELAX-RELOC: R_RISCV_LO12_I foo 0x0 +# NORELAX-RELOC-NOT: R_RISCV_RELAX +# RELOC: R_RISCV_LO12_I foo 0x0 +# RELAX-RELOC: R_RISCV_RELAX - 0x0 +# RELAX-FIXUP: fixup A - offset: 0, value: %lo(foo), kind: fixup_riscv_lo12_i +# RELAX-FIXUP: fixup B - offset: 0, value: 0, kind: fixup_riscv_relax + +sb t1, %lo(foo)(a2) +# NORELAX-RELOC: R_RISCV_LO12_S foo 0x0 +# NORELAX-RELOC-NOT: R_RISCV_RELAX +# RELOC: R_RISCV_LO12_S foo 0x0 +# RELAX-RELOC: R_RISCV_RELAX - 0x0 +# RELAX-FIXUP: fixup A - offset: 0, value: %lo(foo), kind: fixup_riscv_lo12_s +# RELAX-FIXUP: fixup B - offset: 0, value: 0, kind: fixup_riscv_relax + +auipc t1, %pcrel_hi(foo) +# NORELAX-RELOC: R_RISCV_PCREL_HI20 foo 0x0 +# NORELAX-RELOC-NOT: R_RISCV_RELAX +# RELOC: R_RISCV_PCREL_HI20 foo 0x0 +# RELAX-RELOC: R_RISCV_RELAX - 0x0 +# RELAX-FIXUP: fixup A - offset: 0, value: %pcrel_hi(foo), kind: fixup_riscv_pcrel_hi20 +# RELAX-FIXUP: fixup B - offset: 0, value: 0, kind: fixup_riscv_relax + +addi t1, t1, %pcrel_lo(foo) +# NORELAX-RELOC: R_RISCV_PCREL_LO12_I foo 0x0 +# NORELAX-RELOC-NOT: R_RISCV_RELAX +# RELOC: R_RISCV_PCREL_LO12_I foo 0x0 +# RELAX-RELOC: R_RISCV_RELAX - 0x0 +# RELAX-FIXUP: fixup A - offset: 0, value: %pcrel_lo(foo), kind: fixup_riscv_pcrel_lo12_i +# RELAX-FIXUP: fixup B - offset: 0, value: 0, kind: fixup_riscv_relax + +sb t1, %pcrel_lo(foo)(a2) +# NORELAX-RELOC: R_RISCV_PCREL_LO12_S foo 0x0 +# NORELAX-RELOC-NOT: R_RISCV_RELAX +# RELOC: R_RISCV_PCREL_LO12_S foo 0x0 +# RELAX-RELOC: R_RISCV_RELAX - 0x0 +# RELAX-FIXUP: fixup A - offset: 0, value: %pcrel_lo(foo), kind: fixup_riscv_pcrel_lo12_s +# RELAX-FIXUP: fixup B - offset: 0, value: 0, kind: fixup_riscv_relax Index: llvm/trunk/test/MC/RISCV/option-pushpop.s =================================================================== --- llvm/trunk/test/MC/RISCV/option-pushpop.s +++ llvm/trunk/test/MC/RISCV/option-pushpop.s @@ -21,7 +21,7 @@ # CHECK-INST: call foo # CHECK-RELOC: R_RISCV_CALL foo 0x0 -# CHECK-RELOC-NOT: R_RISCV_RELAX foo 0x0 +# CHECK-RELOC-NOT: R_RISCV_RELAX - 0x0 call foo # CHECK-INST: addi s0, sp, 1020 @@ -36,7 +36,7 @@ # CHECK-INST: .option relax # CHECK-INST: call bar # CHECK-RELOC-NEXT: R_RISCV_CALL bar 0x0 -# CHECK-RELOC-NEXT: R_RISCV_RELAX bar 0x0 +# CHECK-RELOC-NEXT: R_RISCV_RELAX - 0x0 call bar .option push # Push relax=true, rvc=false @@ -58,14 +58,14 @@ # CHECK-INST: call bar # CHECK-RELOC-NEXT: R_RISCV_CALL bar 0x0 -# CHECK-RELOC-NEXT: R_RISCV_RELAX bar 0x0 +# CHECK-RELOC-NEXT: R_RISCV_RELAX - 0x0 call bar .option pop # Pop relax=false, rvc=false # CHECK-INST: .option pop # CHECK-INST: call baz # CHECK-RELOC: R_RISCV_CALL baz 0x0 -# CHECK-RELOC-NOT: R_RISCV_RELAX baz 0x0 +# CHECK-RELOC-NOT: R_RISCV_RELAX - 0x0 call baz # CHECK-INST: addi s0, sp, 1020 Index: llvm/trunk/test/MC/RISCV/option-relax.s =================================================================== --- llvm/trunk/test/MC/RISCV/option-relax.s +++ llvm/trunk/test/MC/RISCV/option-relax.s @@ -21,7 +21,7 @@ # CHECK-INST: call foo # CHECK-RELOC: R_RISCV_CALL foo 0x0 -# CHECK-RELOC-NOT: R_RISCV_RELAX foo 0x0 +# CHECK-RELOC-NOT: R_RISCV_RELAX - 0x0 call foo # CHECK-RELOC-NEXT: R_RISCV_ADD64 @@ -38,7 +38,7 @@ # CHECK-INST: call bar # CHECK-RELOC-NEXT: R_RISCV_CALL bar 0x0 -# CHECK-RELOC-NEXT: R_RISCV_RELAX bar 0x0 +# CHECK-RELOC-NEXT: R_RISCV_RELAX - 0x0 call bar # CHECK-RELOC-NEXT: R_RISCV_ADD64 @@ -54,7 +54,7 @@ # CHECK-INST: call baz # CHECK-RELOC-NEXT: R_RISCV_CALL baz 0x0 -# CHECK-RELOC-NOT: R_RISCV_RELAX baz 0x0 +# CHECK-RELOC-NOT: R_RISCV_RELAX - 0x0 call baz # CHECK-RELOC-NEXT: R_RISCV_ADD64