[llvm] [AVR] Force relocations for jumps and calls (PR #118015)

Patryk Wychowaniec via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 28 07:20:33 PST 2024


https://github.com/Patryk27 created https://github.com/llvm/llvm-project/pull/118015

This commit changes `shouldForceRelocation()` to always return `true` for indirect jumps, direct jumps and calls.

# Motivation

Over https://github.com/Rahix/avr-hal/pull/585 it was found out that the AVR codegen sometimes crashes with the `out of range branch target` message - this turned out to be a fallout from https://github.com/llvm/llvm-project/pull/106722 related to the fact that linkers are smarter than they seem!

The issue stems from the `rjmp` instruction - even though it can only encode offsets in the +-4 kB range, it can be used to jump into further memory addresses by relying on the fact that AVR memory wraps around the boundaries. That is, for a CPU with 8 kB of flash, `rjmp 5000` (illegal) can be actually encoded as `rjmp -3192` (legal).

Linkers apply this trick automatically, but since over https://github.com/llvm/llvm-project/pull/106722 we've decided to go with the `let's avoid emitting relocations` route...

We would've caught this, but since the `branch-relaxation-long.ll` test generated only the textual assembly, it never went near the assertion - I've changed the test to use `-filetype=obj | llvm-objdump -dr` now (which causes it to crash on the main branch, but succeeds with my changes here).

# Alternatives

We could re-do the wrapping logic directly within the codegen - in fact, that's what I started with! I've taught `AVRDevices.td` about the flash sizes (relying on data from avr-gcc):

```
class Device<string Name, Family Fam, ELFArch Arch, int FlashSizeArg,
             list<SubtargetFeature> ExtraFeatures = []>
    : Processor<Name, NoItineraries, !listconcat([Fam, Arch], ExtraFeatures)> {
  int FlashSize = FlashSizeArg;
}

def : Device<"avr1", FamilyAVR1, ELFArchAVR1, 0x400>;
def : Device<"avr2", FamilyAVR2, ELFArchAVR2, 0x60000>;
def : Device<"avr25", FamilyAVR25, ELFArchAVR25, 0x2000>;
def : Device<"avr3", FamilyAVR3, ELFArchAVR3, 0x6000>;
/* ... */
```
... created a new TableGen emitter:
```cpp
static void EmitAVRTargetDef(RecordKeeper &RK, raw_ostream &OS) {
  OS << "// Autogenerated by AVRTargetDefEmitter.cpp\n\n";

  OS << "namespace llvm {\n";
  OS << "namespace AVR {\n";
  OS << "\n";
  OS << "static const std::map<StringRef, uint32_t> FlashSizes = {\n";

  for (const Record *Rec : RK.getAllDerivedDefinitions("Device")) {
    OS << "  { \"" << Rec->getValueAsString("Name") << "\", "
       << Rec->getValueAsInt("FlashSize") << " },\n";
  }

  OS << "};\n";
  OS << "\n";
  OS << "inline uint32_t getFlashSize(StringRef cpu) {\n";
  OS << "  return FlashSizes.at(cpu);\n";
  OS << "}\n";
  OS << "\n";
  OS << "} // end of namespace AVR\n";
  OS << "} // end of namespace llvm\n";
}

static TableGen::Emitter::Opt X("gen-avr-target-def", EmitAVRTargetDef,
                                "Generate the list of CPUs for AVR");
```
... adjusted `adjustRelativeBranch()` to access this brand new `AVR::getFlashSize()`: 
```cpp
/// Adjusts the value of a relative branch target before fixup application.
static void adjustRelativeBranch(unsigned Size, const MCFixup &Fixup,
                                 uint64_t &Value, MCContext *Ctx) {
  // Jumps are relative to the current instruction.
  Value -= 2;

  // We have one extra bit of precision because the value is rightshifted by
  // one.
  Size += 1;

  if (!isIntN(Size, Value)) {
    uint64_t FlashSize =
        AVR::getFlashSize(Ctx->getSubtargetInfo()->getCPU().data());

    uint64_t ReverseValue =
        Value > 0 ? (uint64_t)((int32_t)Value - (int32_t)FlashSize)
                  : (uint64_t)((int32_t)FlashSize + (int32_t)Value);

    if (isIntN(Size, ReverseValue)) {
      Value = ReverseValue;
    }
  }

  ensureSignedWidth(Size, Value, std::string("branch target"), Fixup, Ctx);

  AVR::fixups::adjustBranchTarget(Value);
}
```
... and it worked!

I've eventually settled on relocations, because that's both the simpler approach and what we'd like to have anyway (to resemble avr-gcc, as I remember from discussions from the past).

>From d51963651a47476613128814e607ca67c48ca1da Mon Sep 17 00:00:00 2001
From: Patryk Wychowaniec <pwychowaniec at pm.me>
Date: Thu, 28 Nov 2024 15:54:31 +0100
Subject: [PATCH] [AVR] Force relocations for jumps and calls

---
 llvm/lib/Target/AVR/AVRInstrInfo.cpp          |  22 ++-
 .../Target/AVR/MCTargetDesc/AVRAsmBackend.cpp | 155 +++---------------
 .../CodeGen/AVR/branch-relaxation-long.ll     |  74 +++++----
 llvm/test/CodeGen/AVR/jmp.ll                  |   5 +-
 llvm/test/MC/AVR/inst-brbc.s                  |  14 +-
 llvm/test/MC/AVR/inst-brbs.s                  |  14 +-
 llvm/test/MC/AVR/inst-brcc.s                  |  12 +-
 llvm/test/MC/AVR/inst-brcs.s                  |  12 +-
 llvm/test/MC/AVR/inst-breq.s                  |  12 +-
 llvm/test/MC/AVR/inst-brge.s                  |   9 +-
 llvm/test/MC/AVR/inst-brhc.s                  |   9 +-
 llvm/test/MC/AVR/inst-brhs.s                  |   9 +-
 llvm/test/MC/AVR/inst-brid.s                  |   9 +-
 llvm/test/MC/AVR/inst-brie.s                  |   9 +-
 llvm/test/MC/AVR/inst-brlo.s                  |   9 +-
 llvm/test/MC/AVR/inst-brlt.s                  |   9 +-
 llvm/test/MC/AVR/inst-brmi.s                  |   9 +-
 llvm/test/MC/AVR/inst-brne.s                  |  12 +-
 llvm/test/MC/AVR/inst-brpl.s                  |   9 +-
 llvm/test/MC/AVR/inst-brsh.s                  |   9 +-
 llvm/test/MC/AVR/inst-brtc.s                  |   9 +-
 llvm/test/MC/AVR/inst-brts.s                  |   9 +-
 llvm/test/MC/AVR/inst-brvc.s                  |   9 +-
 llvm/test/MC/AVR/inst-brvs.s                  |   9 +-
 llvm/test/MC/AVR/inst-rcall.s                 |  14 +-
 llvm/test/MC/AVR/inst-rjmp.s                  |  40 +++--
 26 files changed, 247 insertions(+), 265 deletions(-)

diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.cpp b/llvm/lib/Target/AVR/AVRInstrInfo.cpp
index 7d58ece95c869f..6f6da56367e0cb 100644
--- a/llvm/lib/Target/AVR/AVRInstrInfo.cpp
+++ b/llvm/lib/Target/AVR/AVRInstrInfo.cpp
@@ -557,17 +557,23 @@ void AVRInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
                                         MachineBasicBlock &RestoreBB,
                                         const DebugLoc &DL, int64_t BrOffset,
                                         RegScavenger *RS) const {
-  // This method inserts a *direct* branch (JMP), despite its name.
-  // LLVM calls this method to fixup unconditional branches; it never calls
-  // insertBranch or some hypothetical "insertDirectBranch".
-  // See lib/CodeGen/RegisterRelaxation.cpp for details.
-  // We end up here when a jump is too long for a RJMP instruction.
+  // When an instruction's jump target is too far away¹, the branch relaxation
+  // pass might split an existing, large basic block into two pieces - if that
+  // happens, this function gets called to create a new jump between the blocks.
+  //
+  // Since this new jump might be too large for an `rjmp` anyway, let's
+  // conservatively emit `jmp` and back off to `rjmp` only if the target arch
+  // doesn't support `jmp`.
+  //
+  // TODO maybe we could use `BrOffset` to determine whether it's safe to emit
+  //      `rjmp`? (it takes one byte less to encode, so it'd be a small win)
+  //
+  // ¹ "too far" in the sense of "the instruction encoding doesn't allow for an
+  //   offset that large"
+
   if (STI.hasJMPCALL())
     BuildMI(&MBB, DL, get(AVR::JMPk)).addMBB(&NewDestBB);
   else
-    // The RJMP may jump to a far place beyond its legal range. We let the
-    // linker to report 'out of range' rather than crash, or silently emit
-    // incorrect assembly code.
     BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(&NewDestBB);
 }
 
diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp b/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
index 17c48c2fc35ff8..be3ca4cfcd94f5 100644
--- a/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
+++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
@@ -27,129 +27,32 @@
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/raw_ostream.h"
 
-// FIXME: we should be doing checks to make sure asm operands
-// are not out of bounds.
-
 namespace adjust {
 
 using namespace llvm;
 
-static void signed_width(unsigned Width, uint64_t Value,
-                         std::string Description, const MCFixup &Fixup,
-                         MCContext *Ctx = nullptr) {
-  if (!isIntN(Width, Value)) {
-    std::string Diagnostic = "out of range " + Description;
-
-    int64_t Min = minIntN(Width);
-    int64_t Max = maxIntN(Width);
-
-    Diagnostic += " (expected an integer in the range " + std::to_string(Min) +
-                  " to " + std::to_string(Max) + ")";
-
-    if (Ctx) {
-      Ctx->reportError(Fixup.getLoc(), Diagnostic);
-    } else {
-      llvm_unreachable(Diagnostic.c_str());
-    }
-  }
-}
-
-static void unsigned_width(unsigned Width, uint64_t Value,
-                           std::string Description, const MCFixup &Fixup,
-                           MCContext *Ctx = nullptr) {
+static void ensureUnsignedWidth(unsigned Width, uint64_t Value,
+                                std::string Description, const MCFixup &Fixup,
+                                MCContext *Ctx) {
   if (!isUIntN(Width, Value)) {
     std::string Diagnostic = "out of range " + Description;
 
     int64_t Max = maxUIntN(Width);
 
-    Diagnostic +=
-        " (expected an integer in the range 0 to " + std::to_string(Max) + ")";
+    Diagnostic += " (expected an unsigned integer in the range 0 to " +
+                  std::to_string(Max) + ", got " + std::to_string(Value) + ")";
 
-    if (Ctx) {
-      Ctx->reportError(Fixup.getLoc(), Diagnostic);
-    } else {
-      llvm_unreachable(Diagnostic.c_str());
-    }
+    Ctx->reportError(Fixup.getLoc(), Diagnostic);
   }
 }
 
-/// Adjusts the value of a branch target before fixup application.
-static void adjustBranch(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
-                         MCContext *Ctx = nullptr) {
-  // We have one extra bit of precision because the value is rightshifted by
-  // one.
-  unsigned_width(Size + 1, Value, std::string("branch target"), Fixup, Ctx);
-
-  // Rightshifts the value by one.
-  AVR::fixups::adjustBranchTarget(Value);
-}
-
-/// Adjusts the value of a relative branch target before fixup application.
-static void adjustRelativeBranch(unsigned Size, const MCFixup &Fixup,
-                                 uint64_t &Value, MCContext *Ctx = nullptr) {
-  // Jumps are relative to the current instruction.
-  Value -= 2;
-
-  // We have one extra bit of precision because the value is rightshifted by
-  // one.
-  signed_width(Size + 1, Value, std::string("branch target"), Fixup, Ctx);
-
-  // Rightshifts the value by one.
-  AVR::fixups::adjustBranchTarget(Value);
-}
-
-/// 22-bit absolute fixup.
-///
-/// Resolves to:
-/// 1001 kkkk 010k kkkk kkkk kkkk 111k kkkk
-///
-/// Offset of 0 (so the result is left shifted by 3 bits before application).
-static void fixup_call(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
-                       MCContext *Ctx = nullptr) {
-  adjustBranch(Size, Fixup, Value, Ctx);
-
-  auto top = Value & (0xf00000 << 6);   // the top four bits
-  auto middle = Value & (0x1ffff << 5); // the middle 13 bits
-  auto bottom = Value & 0x1f;           // end bottom 5 bits
-
-  Value = (top << 6) | (middle << 3) | (bottom << 0);
-}
-
-/// 7-bit PC-relative fixup.
-///
-/// Resolves to:
-/// 0000 00kk kkkk k000
-/// Offset of 0 (so the result is left shifted by 3 bits before application).
-static void fixup_7_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
-                          MCContext *Ctx = nullptr) {
-  adjustRelativeBranch(Size, Fixup, Value, Ctx);
-
-  // Because the value may be negative, we must mask out the sign bits
-  Value &= 0x7f;
-}
-
-/// 12-bit PC-relative fixup.
-/// Yes, the fixup is 12 bits even though the name says otherwise.
-///
-/// Resolves to:
-/// 0000 kkkk kkkk kkkk
-/// Offset of 0 (so the result isn't left-shifted before application).
-static void fixup_13_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
-                           MCContext *Ctx = nullptr) {
-  adjustRelativeBranch(Size, Fixup, Value, Ctx);
-
-  // Because the value may be negative, we must mask out the sign bits
-  Value &= 0xfff;
-}
-
 /// 6-bit fixup for the immediate operand of the STD/LDD family of
 /// instructions.
 ///
 /// Resolves to:
 /// 10q0 qq10 0000 1qqq
-static void fixup_6(const MCFixup &Fixup, uint64_t &Value,
-                    MCContext *Ctx = nullptr) {
-  unsigned_width(6, Value, std::string("immediate"), Fixup, Ctx);
+static void fixup_6(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
+  ensureUnsignedWidth(6, Value, std::string("immediate"), Fixup, Ctx);
 
   Value = ((Value & 0x20) << 8) | ((Value & 0x18) << 7) | (Value & 0x07);
 }
@@ -160,8 +63,8 @@ static void fixup_6(const MCFixup &Fixup, uint64_t &Value,
 /// Resolves to:
 /// 0000 0000 kk00 kkkk
 static void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value,
-                         MCContext *Ctx = nullptr) {
-  unsigned_width(6, Value, std::string("immediate"), Fixup, Ctx);
+                         MCContext *Ctx) {
+  ensureUnsignedWidth(6, Value, std::string("immediate"), Fixup, Ctx);
 
   Value = ((Value & 0x30) << 2) | (Value & 0x0f);
 }
@@ -170,9 +73,8 @@ static void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value,
 ///
 /// Resolves to:
 /// 0000 0000 AAAA A000
-static void fixup_port5(const MCFixup &Fixup, uint64_t &Value,
-                        MCContext *Ctx = nullptr) {
-  unsigned_width(5, Value, std::string("port number"), Fixup, Ctx);
+static void fixup_port5(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
+  ensureUnsignedWidth(5, Value, std::string("port number"), Fixup, Ctx);
 
   Value &= 0x1f;
 
@@ -183,9 +85,8 @@ static void fixup_port5(const MCFixup &Fixup, uint64_t &Value,
 ///
 /// Resolves to:
 /// 1011 0AAd dddd AAAA
-static void fixup_port6(const MCFixup &Fixup, uint64_t &Value,
-                        MCContext *Ctx = nullptr) {
-  unsigned_width(6, Value, std::string("port number"), Fixup, Ctx);
+static void fixup_port6(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
+  ensureUnsignedWidth(6, Value, std::string("port number"), Fixup, Ctx);
 
   Value = ((Value & 0x30) << 5) | (Value & 0x0f);
 }
@@ -195,8 +96,8 @@ static void fixup_port6(const MCFixup &Fixup, uint64_t &Value,
 /// Resolves to:
 /// 1010 ikkk dddd kkkk
 static void fixup_lds_sts_16(const MCFixup &Fixup, uint64_t &Value,
-                             MCContext *Ctx = nullptr) {
-  unsigned_width(7, Value, std::string("immediate"), Fixup, Ctx);
+                             MCContext *Ctx) {
+  ensureUnsignedWidth(7, Value, std::string("immediate"), Fixup, Ctx);
   Value = ((Value & 0x70) << 8) | (Value & 0x0f);
 }
 
@@ -213,7 +114,7 @@ namespace ldi {
 /// 0000 KKKK 0000 KKKK
 /// Offset of 0 (so the result isn't left-shifted before application).
 static void fixup(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
-                  MCContext *Ctx = nullptr) {
+                  MCContext *Ctx) {
   uint64_t upper = Value & 0xf0;
   uint64_t lower = Value & 0x0f;
 
@@ -223,25 +124,25 @@ static void fixup(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
 static void neg(uint64_t &Value) { Value *= -1; }
 
 static void lo8(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
-                MCContext *Ctx = nullptr) {
+                MCContext *Ctx) {
   Value &= 0xff;
   ldi::fixup(Size, Fixup, Value, Ctx);
 }
 
 static void hi8(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
-                MCContext *Ctx = nullptr) {
+                MCContext *Ctx) {
   Value = (Value & 0xff00) >> 8;
   ldi::fixup(Size, Fixup, Value, Ctx);
 }
 
 static void hh8(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
-                MCContext *Ctx = nullptr) {
+                MCContext *Ctx) {
   Value = (Value & 0xff0000) >> 16;
   ldi::fixup(Size, Fixup, Value, Ctx);
 }
 
 static void ms8(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
-                MCContext *Ctx = nullptr) {
+                MCContext *Ctx) {
   Value = (Value & 0xff000000) >> 24;
   ldi::fixup(Size, Fixup, Value, Ctx);
 }
@@ -263,13 +164,9 @@ void AVRAsmBackend::adjustFixupValue(const MCFixup &Fixup,
   default:
     llvm_unreachable("unhandled fixup");
   case AVR::fixup_7_pcrel:
-    adjust::fixup_7_pcrel(Size, Fixup, Value, Ctx);
-    break;
   case AVR::fixup_13_pcrel:
-    adjust::fixup_13_pcrel(Size, Fixup, Value, Ctx);
-    break;
   case AVR::fixup_call:
-    adjust::fixup_call(Size, Fixup, Value, Ctx);
+    // Handled by linker, see `shouldForceRelocation()`
     break;
   case AVR::fixup_ldi:
     adjust::ldi::fixup(Size, Fixup, Value, Ctx);
@@ -330,13 +227,15 @@ void AVRAsmBackend::adjustFixupValue(const MCFixup &Fixup,
     adjust::ldi::ms8(Size, Fixup, Value, Ctx);
     break;
   case AVR::fixup_16:
-    adjust::unsigned_width(16, Value, std::string("port number"), Fixup, Ctx);
+    adjust::ensureUnsignedWidth(16, Value, std::string("port number"), Fixup,
+                                Ctx);
 
     Value &= 0xffff;
     break;
   case AVR::fixup_16_pm:
     Value >>= 1; // Flash addresses are always shifted.
-    adjust::unsigned_width(16, Value, std::string("port number"), Fixup, Ctx);
+    adjust::ensureUnsignedWidth(16, Value, std::string("port number"), Fixup,
+                                Ctx);
 
     Value &= 0xffff;
     break;
@@ -517,8 +416,6 @@ bool AVRAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
     return Fixup.getKind() >= FirstLiteralRelocationKind;
   case AVR::fixup_7_pcrel:
   case AVR::fixup_13_pcrel:
-    // Always resolve relocations for PC-relative branches
-    return false;
   case AVR::fixup_call:
     return true;
   }
diff --git a/llvm/test/CodeGen/AVR/branch-relaxation-long.ll b/llvm/test/CodeGen/AVR/branch-relaxation-long.ll
index bca505e5edd5f1..11c79dbccc1773 100644
--- a/llvm/test/CodeGen/AVR/branch-relaxation-long.ll
+++ b/llvm/test/CodeGen/AVR/branch-relaxation-long.ll
@@ -1,24 +1,25 @@
-; RUN: llc < %s -march=avr -mattr=avr3 | FileCheck %s
-; RUN: llc < %s -march=avr -mattr=avr2 | FileCheck --check-prefix=AVR2 %s
+; RUN: llc < %s -march=avr -mcpu=avr25 -filetype=obj -o - | llvm-objdump --mcpu=avr25 -dr --no-show-raw-insn --no-leading-addr - | FileCheck --check-prefix=AVR25 %s
+; RUN: llc < %s -march=avr -mcpu=avr3 -filetype=obj -o - | llvm-objdump --mcpu=avr3 -dr --no-show-raw-insn --no-leading-addr - | FileCheck --check-prefix=AVR3 %s
 
-; CHECK-LABEL: relax_to_jmp:
-; CHECK: cpi     r{{[0-9]+}}, 0
-; CHECK: brne    [[BB1:.LBB[0-9]+_[0-9]+]]
-; CHECK: jmp     [[BB2:.LBB[0-9]+_[0-9]+]]
-; CHECK: [[BB1]]:
-; CHECK: nop
-; CHECK: [[BB2]]:
+; AVR25: <relax_to_jmp>:
+; AVR25-NEXT: andi r24, 0x1
+; AVR25-NEXT: cpi r24, 0x0
+; AVR25-NEXT: brne .+0
+; AVR25-NEXT: R_AVR_7_PCREL .text+0x8
+; AVR25-NEXT: rjmp .+0
+; AVR25-NEXT: R_AVR_13_PCREL .text+0x100c
+; AVR25: ldi r24, 0x3
+; AVR25-NEXT: ret
 
-;; A `RJMP` is generated instead of expected `JMP` for AVR2,
-;; and it is up to the linker to report 'out of range' or
-;; 'exceed flash maximum size'.
-; AVR2-LABEL: relax_to_jmp:
-; AVR2: cpi     r{{[0-9]+}}, 0
-; AVR2: brne    [[BB1:.LBB[0-9]+_[0-9]+]]
-; AVR2: rjmp    [[BB2:.LBB[0-9]+_[0-9]+]]
-; AVR2: [[BB1]]:
-; AVR2: nop
-; AVR2: [[BB2]]:
+; AVR3: <relax_to_jmp>:
+; AVR3-NEXT: andi r24, 0x1
+; AVR3-NEXT: cpi r24, 0x0
+; AVR3-NEXT: brne .+0
+; AVR3-NEXT: R_AVR_7_PCREL .text+0xa
+; AVR3-NEXT: jmp 0x0
+; AVR3-NEXT: R_AVR_CALL .text+0x100e
+; AVR3: ldi r24, 0x3
+; AVR3-NEXT: ret
 
 define i8 @relax_to_jmp(i1 %a) {
 entry-block:
@@ -2081,24 +2082,25 @@ finished:
   ret i8 3
 }
 
-; CHECK-LABEL: relax_to_jmp_backwards:
-; CHECK: [[BB1:.LBB[0-9]+_[0-9]+]]
-; CHECK: nop
-; CHECK: cpi     r{{[0-9]+}}, 0
-; CHECK: breq    [[BB2:.LBB[0-9]+_[0-9]+]]
-; CHECK: jmp     [[BB1]]
-; CHECK: [[BB2]]:
+; AVR25: <relax_to_jmp_backwards>:
+; AVR25-NEXT: andi r24, 0x1
+; AVR25: cpi r24, 0x0
+; AVR25-NEXT: breq .+0
+; AVR25-NEXT: R_AVR_7_PCREL .text+0x201c
+; AVR25-NEXT: rjmp .+0
+; AVR25-NEXT: R_AVR_13_PCREL .text+0x1012
+; AVR25: ldi r24, 0x3
+; AVR25-NEXT: ret
 
-;; A `RJMP` is generated instead of expected `JMP` for AVR2,
-;; and it is up to the linker to report 'out of range' or
-;; 'exceed flash maximum size'.
-; AVR2-LABEL: relax_to_jmp_backwards:
-; AVR2: [[BB1:.LBB[0-9]+_[0-9]+]]
-; AVR2: nop
-; AVR2: cpi     r{{[0-9]+}}, 0
-; AVR2: breq    [[BB2:.LBB[0-9]+_[0-9]+]]
-; AVR2: rjmp    [[BB1]]
-; AVR2: [[BB2]]:
+; AVR3: <relax_to_jmp_backwards>:
+; AVR3-NEXT: andi r24, 0x1
+; AVR3: cpi r24, 0x0
+; AVR3-NEXT: breq .+0
+; AVR3-NEXT: R_AVR_7_PCREL .text+0x2020
+; AVR3-NEXT: jmp 0x0
+; AVR3-NEXT: R_AVR_CALL .text+0x1014
+; AVR3: ldi r24, 0x3
+; AVR3-NEXT: ret
 
 define i8 @relax_to_jmp_backwards(i1 %a) {
 entry-block:
diff --git a/llvm/test/CodeGen/AVR/jmp.ll b/llvm/test/CodeGen/AVR/jmp.ll
index 95dfff4836b4e8..f3d6724074e845 100644
--- a/llvm/test/CodeGen/AVR/jmp.ll
+++ b/llvm/test/CodeGen/AVR/jmp.ll
@@ -15,10 +15,11 @@ bb2:
 
 declare i8 @bar(i8);
 
-; CHECK: rcall   .-2
+; CHECK: rcall   .+0
 ; CHECK-NEXT: 00000000: R_AVR_13_PCREL bar
 ; CHECK-NEXT: cpi     r24, 0x7b
-; CHECK-NEXT: brne    .+4
+; CHECK-NEXT: brne    .+0
+; CHECK-NEXT: 00000004: R_AVR_7_PCREL .text+0xa
 ; CHECK-NEXT: ldi     r24, 0x64
 ; CHECK-NEXT: ret
 ; CHECK-NEXT: ldi     r24, 0xc8
diff --git a/llvm/test/MC/AVR/inst-brbc.s b/llvm/test/MC/AVR/inst-brbc.s
index 4edbbfd8580248..6df400068f1024 100644
--- a/llvm/test/MC/AVR/inst-brbc.s
+++ b/llvm/test/MC/AVR/inst-brbc.s
@@ -17,9 +17,11 @@ foo:
 ; CHECK-NEXT:                ; fixup A - offset: 0, value: (.Ltmp1-16)+2, kind: fixup_7_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: 23 f4   brvc .+8
-; INST-NEXT: c0 f7   brsh .-16
-; INST-NEXT: 59 f7   brne .-42
-; INST-NEXT: 52 f7   brpl .-44
-; INST-NEXT: 4c f7   brge .-46
-; INST-NEXT: c7 f4   brid .+48
+; INST-NEXT: 03 f4 brvc .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0xa
+; INST-NEXT: 00 f4 brsh .+0
+; INST-NEXT: R_AVR_7_PCREL .text-0xc
+; INST-NEXT: 59 f7 brne .-42
+; INST-NEXT: 52 f7 brpl .-44
+; INST-NEXT: 4c f7 brge .-46
+; INST-NEXT: c7 f4 brid .+48
diff --git a/llvm/test/MC/AVR/inst-brbs.s b/llvm/test/MC/AVR/inst-brbs.s
index 3f4b134aef682c..e6c14ce3c255ee 100644
--- a/llvm/test/MC/AVR/inst-brbs.s
+++ b/llvm/test/MC/AVR/inst-brbs.s
@@ -16,9 +16,11 @@ foo:
 ; CHECK-NEXT:                ; fixup A - offset: 0, value: (.Ltmp1-12)+2, kind: fixup_7_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: 23 f0   brvs .+8
-; INST-NEXT: d0 f3   brlo .-12
-; INST-NEXT: 59 f3   breq .-42
-; INST-NEXT: 52 f3   brmi .-44
-; INST-NEXT: 4c f3   brlt .-46
-; INST-NEXT: 77 f0   brie .+28
+; INST-NEXT: 03 f0 brvs .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0xa
+; INST-NEXT: 00 f0 brlo .+0
+; INST-NEXT: R_AVR_7_PCREL .text-0x8
+; INST-NEXT: 59 f3 breq .-42
+; INST-NEXT: 52 f3 brmi .-44
+; INST-NEXT: 4c f3 brlt .-46
+; INST-NEXT: 77 f0 brie .+28
diff --git a/llvm/test/MC/AVR/inst-brcc.s b/llvm/test/MC/AVR/inst-brcc.s
index dd1b2b11a6d306..e9482c5cf1e656 100644
--- a/llvm/test/MC/AVR/inst-brcc.s
+++ b/llvm/test/MC/AVR/inst-brcc.s
@@ -22,7 +22,11 @@ bar:
 ; CHECK-NEXT:                ;   fixup A - offset: 0, value: bar, kind: fixup_7_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: 08 f5      brsh .+66
-; INST-NEXT: a8 f7      brsh .-22
-; INST-NEXT: 08 f5      brsh .+66
-; INST-NEXT: 00 f4      brsh .+0
+; INST-NEXT: 00 f4 brsh .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x44
+; INST-NEXT: 00 f4 brsh .+0
+; INST-NEXT: R_AVR_7_PCREL .text-0x12
+; INST-NEXT: 00 f4 brsh .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x48
+; INST-NEXT: 00 f4 brsh .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x8
diff --git a/llvm/test/MC/AVR/inst-brcs.s b/llvm/test/MC/AVR/inst-brcs.s
index 3fafccdb49257c..52a20a8e334d28 100644
--- a/llvm/test/MC/AVR/inst-brcs.s
+++ b/llvm/test/MC/AVR/inst-brcs.s
@@ -22,7 +22,11 @@ bar:
 ; CHECK-NEXT:               ;   fixup A - offset: 0, value: bar, kind: fixup_7_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: 20 f0      brlo .+8
-; INST-NEXT: 10 f0      brlo .+4
-; INST-NEXT: 20 f0      brlo .+8
-; INST-NEXT: 00 f0      brlo .+0
+; INST-NEXT: 00 f0 brlo .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0xa
+; INST-NEXT: 00 f0 brlo .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x8
+; INST-NEXT: 00 f0 brlo .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0xe
+; INST-NEXT: 00 f0 brlo .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x8
diff --git a/llvm/test/MC/AVR/inst-breq.s b/llvm/test/MC/AVR/inst-breq.s
index 7a6eac6f01ad07..4e10438762daba 100644
--- a/llvm/test/MC/AVR/inst-breq.s
+++ b/llvm/test/MC/AVR/inst-breq.s
@@ -22,7 +22,11 @@ bar:
 ; CHECK-NEXT:                      ;   fixup A - offset: 0, value: bar, kind: fixup_7_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: b9 f3      breq .-18
-; INST-NEXT: d1 f3      breq .-12
-; INST-NEXT: b9 f3      breq .-18
-; INST-NEXT: 01 f0      breq .+0
+; INST-NEXT: 01 f0 breq .+0
+; INST-NEXT: R_AVR_7_PCREL .text-0x10
+; INST-NEXT: 01 f0 breq .+0
+; INST-NEXT: R_AVR_7_PCREL .text-0x8
+; INST-NEXT: 01 f0 breq .+0
+; INST-NEXT: R_AVR_7_PCREL .text-0xc
+; INST-NEXT: 01 f0 breq .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x8
diff --git a/llvm/test/MC/AVR/inst-brge.s b/llvm/test/MC/AVR/inst-brge.s
index 6cf79db4dbd659..9657413d14895b 100644
--- a/llvm/test/MC/AVR/inst-brge.s
+++ b/llvm/test/MC/AVR/inst-brge.s
@@ -19,6 +19,9 @@ bar:
 ; CHECK-NEXT:                ;   fixup A - offset: 0, value: bar, kind: fixup_7_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: cc f4      brge .+50
-; INST-NEXT: ac f4      brge .+42
-; INST-NEXT: 04 f4      brge .+0
+; INST-NEXT: 04 f4 brge .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x34
+; INST-NEXT: 04 f4 brge .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x2e
+; INST-NEXT: 04 f4 brge .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x6
diff --git a/llvm/test/MC/AVR/inst-brhc.s b/llvm/test/MC/AVR/inst-brhc.s
index 924895e4bf5df1..f6c2b66a89a66c 100644
--- a/llvm/test/MC/AVR/inst-brhc.s
+++ b/llvm/test/MC/AVR/inst-brhc.s
@@ -19,6 +19,9 @@ bar:
 ; CHECK-NEXT:                ;   fixup A - offset: 0, value: bar, kind: fixup_7_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: 35 f4      brhc .+12
-; INST-NEXT: 3d f4      brhc .+14
-; INST-NEXT: 05 f4      brhc .+0
+; INST-NEXT: 05 f4 brhc .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0xe
+; INST-NEXT: 05 f4 brhc .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x12
+; INST-NEXT: 05 f4 brhc .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x6
diff --git a/llvm/test/MC/AVR/inst-brhs.s b/llvm/test/MC/AVR/inst-brhs.s
index 9704ce5e7e5ac2..8e2a8a6bfdd964 100644
--- a/llvm/test/MC/AVR/inst-brhs.s
+++ b/llvm/test/MC/AVR/inst-brhs.s
@@ -19,6 +19,9 @@ bar:
 ; CHECK-NEXT:                ;   fixup A - offset: 0, value: bar, kind: fixup_7_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: fd f2      brhs .-66
-; INST-NEXT: 3d f0      brhs .+14
-; INST-NEXT: 05 f0      brhs .+0
+; INST-NEXT: 05 f0 brhs .+0
+; INST-NEXT: R_AVR_7_PCREL .text-0x40
+; INST-NEXT: 05 f0 brhs .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x12
+; INST-NEXT: 05 f0 brhs .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x6
diff --git a/llvm/test/MC/AVR/inst-brid.s b/llvm/test/MC/AVR/inst-brid.s
index e03c293677887b..beb0f5135ac020 100644
--- a/llvm/test/MC/AVR/inst-brid.s
+++ b/llvm/test/MC/AVR/inst-brid.s
@@ -19,6 +19,9 @@ bar:
 ; CHECK-NEXT:                ;   fixup A - offset: 0, value: bar, kind: fixup_7_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: af f4      brid .+42
-; INST-NEXT: ff f4      brid .+62
-; INST-NEXT: 07 f4      brid .+0
+; INST-NEXT: 07 f4 brid .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x2c
+; INST-NEXT: 07 f4 brid .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x42
+; INST-NEXT: 07 f4 brid .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x6
diff --git a/llvm/test/MC/AVR/inst-brie.s b/llvm/test/MC/AVR/inst-brie.s
index 74b724b20bd9e7..561ceb72d465ea 100644
--- a/llvm/test/MC/AVR/inst-brie.s
+++ b/llvm/test/MC/AVR/inst-brie.s
@@ -19,6 +19,9 @@ bar:
 ; CHECK-NEXT:                ;   fixup A - offset: 0, value: bar, kind: fixup_7_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: 57 f0      brie .+20
-; INST-NEXT: a7 f0      brie .+40
-; INST-NEXT: 07 f0      brie .+0
+; INST-NEXT: 07 f0 brie .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x16
+; INST-NEXT: 07 f0 brie .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x2c
+; INST-NEXT: 07 f0 brie .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x6
diff --git a/llvm/test/MC/AVR/inst-brlo.s b/llvm/test/MC/AVR/inst-brlo.s
index 2726d943e0e788..7f64324affb4f6 100644
--- a/llvm/test/MC/AVR/inst-brlo.s
+++ b/llvm/test/MC/AVR/inst-brlo.s
@@ -19,6 +19,9 @@ bar:
 ; CHECK-NEXT:                ;   fixup A - offset: 0, value: bar, kind: fixup_7_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: 30 f0      brlo .+12
-; INST-NEXT: 70 f0      brlo .+28
-; INST-NEXT: 00 f0      brlo .+0
+; INST-NEXT: 00 f0 brlo .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0xe
+; INST-NEXT: 00 f0 brlo .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x20
+; INST-NEXT: 00 f0 brlo .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x6
diff --git a/llvm/test/MC/AVR/inst-brlt.s b/llvm/test/MC/AVR/inst-brlt.s
index 299a873963e5b3..1a29afa931b3f1 100644
--- a/llvm/test/MC/AVR/inst-brlt.s
+++ b/llvm/test/MC/AVR/inst-brlt.s
@@ -19,6 +19,9 @@ bar:
 ; CHECK-NEXT:                ;   fixup A - offset: 0, value: bar, kind: fixup_7_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: 44 f0    brlt .+16
-; INST-NEXT: 0c f0    brlt .+2
-; INST-NEXT: 04 f0    brlt .+0
+; INST-NEXT: 04 f0 brlt .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x12
+; INST-NEXT: 04 f0 brlt .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x6
+; INST-NEXT: 04 f0 brlt .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x6
diff --git a/llvm/test/MC/AVR/inst-brmi.s b/llvm/test/MC/AVR/inst-brmi.s
index 96f7e484f465f3..ca6ff98b196f3d 100644
--- a/llvm/test/MC/AVR/inst-brmi.s
+++ b/llvm/test/MC/AVR/inst-brmi.s
@@ -19,6 +19,9 @@ bar:
 ; CHECK-NEXT:                ;   fixup A - offset: 0, value: bar, kind: fixup_7_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: 0a f1      brmi .+66
-; INST-NEXT: ea f0      brmi .+58
-; INST-NEXT: 02 f0      brmi .+0
+; INST-NEXT: 02 f0 brmi .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x44
+; INST-NEXT: 02 f0 brmi .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x3e
+; INST-NEXT: 02 f0 brmi .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x6
diff --git a/llvm/test/MC/AVR/inst-brne.s b/llvm/test/MC/AVR/inst-brne.s
index ab89d516681d34..29686ff63721cb 100644
--- a/llvm/test/MC/AVR/inst-brne.s
+++ b/llvm/test/MC/AVR/inst-brne.s
@@ -22,7 +22,11 @@ bar:
 ; CHECK-NEXT:                      ;   fixup A - offset: 0, value: bar, kind: fixup_7_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: 29 f4      brne .+10
-; INST-NEXT: 09 f4      brne .+2
-; INST-NEXT: 29 f4      brne .+10
-; INST-NEXT: 01 f4      brne .+0
+; INST-NEXT: 01 f4 brne .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0xc
+; INST-NEXT: 01 f4 brne .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x6
+; INST-NEXT: 01 f4 brne .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x10
+; INST-NEXT: 01 f4 brne .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x8
diff --git a/llvm/test/MC/AVR/inst-brpl.s b/llvm/test/MC/AVR/inst-brpl.s
index cd2f697ae8f209..4db27ecdd8b464 100644
--- a/llvm/test/MC/AVR/inst-brpl.s
+++ b/llvm/test/MC/AVR/inst-brpl.s
@@ -19,6 +19,9 @@ bar:
 ; CHECK-NEXT:                ;   fixup A - offset: 0, value: bar, kind: fixup_7_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: d2 f7      brpl .-12
-; INST-NEXT: 4a f4      brpl .+18
-; INST-NEXT: 02 f4      brpl .+0
+; INST-NEXT: 02 f4 brpl .+0
+; INST-NEXT: R_AVR_7_PCREL .text-0xa
+; INST-NEXT: 02 f4 brpl .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x16
+; INST-NEXT: 02 f4 brpl .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x6
diff --git a/llvm/test/MC/AVR/inst-brsh.s b/llvm/test/MC/AVR/inst-brsh.s
index b066c917f72aec..56c9a967ec80ca 100644
--- a/llvm/test/MC/AVR/inst-brsh.s
+++ b/llvm/test/MC/AVR/inst-brsh.s
@@ -19,6 +19,9 @@ bar:
 ; CHECK-NEXT:                ;   fixup A - offset: 0, value: bar, kind: fixup_7_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: 80 f4      brsh .+32
-; INST-NEXT: 18 f5      brsh .+70
-; INST-NEXT: 00 f4      brsh .+0
+; INST-NEXT: 00 f4 brsh .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x22
+; INST-NEXT: 00 f4 brsh .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x4a
+; INST-NEXT: 00 f4 brsh .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x6
diff --git a/llvm/test/MC/AVR/inst-brtc.s b/llvm/test/MC/AVR/inst-brtc.s
index 64421df10baf5a..0c7a2a79a3ef12 100644
--- a/llvm/test/MC/AVR/inst-brtc.s
+++ b/llvm/test/MC/AVR/inst-brtc.s
@@ -19,6 +19,9 @@ bar:
 ; CHECK-NEXT:                ;   fixup A - offset: 0, value: bar, kind: fixup_7_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: d6 f4      brtc .+52
-; INST-NEXT: ce f4      brtc .+50
-; INST-NEXT: 06 f4      brtc .+0
+; INST-NEXT: 06 f4 brtc .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x36
+; INST-NEXT: 06 f4 brtc .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x36
+; INST-NEXT: 06 f4 brtc .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x6
diff --git a/llvm/test/MC/AVR/inst-brts.s b/llvm/test/MC/AVR/inst-brts.s
index bb02b6f3d475dc..9b7100af4dcdfe 100644
--- a/llvm/test/MC/AVR/inst-brts.s
+++ b/llvm/test/MC/AVR/inst-brts.s
@@ -19,6 +19,9 @@ bar:
 ; CHECK-NEXT:                ;   fixup A - offset: 0, value: bar, kind: fixup_7_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: 4e f0      brts .+18
-; INST-NEXT: 5e f0      brts .+22
-; INST-NEXT: 06 f0      brts .+0
+; INST-NEXT: 06 f0 brts .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x14
+; INST-NEXT: 06 f0 brts .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x1a
+; INST-NEXT: 06 f0 brts .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x6
diff --git a/llvm/test/MC/AVR/inst-brvc.s b/llvm/test/MC/AVR/inst-brvc.s
index 52b9f3b9b403cf..29bd6c39d10d88 100644
--- a/llvm/test/MC/AVR/inst-brvc.s
+++ b/llvm/test/MC/AVR/inst-brvc.s
@@ -19,6 +19,9 @@ bar:
 ; CHECK-NEXT:                ;   fixup A - offset: 0, value: bar, kind: fixup_7_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: 93 f7      brvc .-28
-; INST-NEXT: 0b f7      brvc .-62
-; INST-NEXT: 03 f4      brvc .+0
+; INST-NEXT: 03 f4 brvc .+0
+; INST-NEXT: R_AVR_7_PCREL .text-0x1a
+; INST-NEXT: 03 f4 brvc .+0
+; INST-NEXT: R_AVR_7_PCREL .text-0x3a
+; INST-NEXT: 03 f4 brvc .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x6
diff --git a/llvm/test/MC/AVR/inst-brvs.s b/llvm/test/MC/AVR/inst-brvs.s
index 10382a8e6fd67e..a6dd77314b1732 100644
--- a/llvm/test/MC/AVR/inst-brvs.s
+++ b/llvm/test/MC/AVR/inst-brvs.s
@@ -19,6 +19,9 @@ bar:
 ; CHECK-NEXT:                ;   fixup A - offset: 0, value: bar, kind: fixup_7_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: 4b f0      brvs .+18
-; INST-NEXT: 83 f0      brvs .+32
-; INST-NEXT: 03 f0      brvs .+0
+; INST-NEXT: 03 f0 brvs .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x14
+; INST-NEXT: 03 f0 brvs .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x24
+; INST-NEXT: 03 f0 brvs .+0
+; INST-NEXT: R_AVR_7_PCREL .text+0x6
diff --git a/llvm/test/MC/AVR/inst-rcall.s b/llvm/test/MC/AVR/inst-rcall.s
index 34c2ef86366c54..d7d47cd7ddb98e 100644
--- a/llvm/test/MC/AVR/inst-rcall.s
+++ b/llvm/test/MC/AVR/inst-rcall.s
@@ -21,8 +21,12 @@ foo:
 ; CHECK-NEXT:                 ;   fixup A - offset: 0, value: (.Ltmp3+46)+2, kind: fixup_13_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: 00 d0    rcall .+0
-; INST-NEXT: fc df    rcall .-8
-; INST-NEXT: 06 d0    rcall .+12
-; INST-NEXT: 17 d0    rcall .+46
-; INST-NEXT: ea df    rcall .-44
+; INST-NEXT: 00 d0 rcall .+0
+; INST-NEXT: R_AVR_13_PCREL .text+0x2
+; INST-NEXT: 00 d0 rcall .+0
+; INST-NEXT: R_AVR_13_PCREL .text-0x4
+; INST-NEXT: 00 d0 rcall .+0
+; INST-NEXT: R_AVR_13_PCREL .text+0x12
+; INST-NEXT: 00 d0 rcall .+0
+; INST-NEXT: R_AVR_13_PCREL .text+0x36
+; INST-NEXT: ea df rcall .-44
diff --git a/llvm/test/MC/AVR/inst-rjmp.s b/llvm/test/MC/AVR/inst-rjmp.s
index cf2a9d106f3d18..a9182bc5d191ad 100644
--- a/llvm/test/MC/AVR/inst-rjmp.s
+++ b/llvm/test/MC/AVR/inst-rjmp.s
@@ -5,12 +5,12 @@
 ; RUN:     | FileCheck --check-prefix=INST %s
 
 foo:
-  rjmp  .+2
-  rjmp  .-2
+  rjmp .+2
+  rjmp .-2
   rjmp  foo
-  rjmp  .+8
+  rjmp .+8
   rjmp  end
-  rjmp  .+0
+  rjmp .+0
 
 end:
   rjmp .-4
@@ -43,18 +43,28 @@ x:
 ; CHECK-NEXT:                 ;   fixup A - offset: 0, value: (.Ltmp6+4094)+2, kind: fixup_13_pcrel
 
 ; INST-LABEL: <foo>:
-; INST-NEXT: 01 c0      rjmp  .+2
-; INST-NEXT: ff cf      rjmp  .-2
-; INST-NEXT: fd cf      rjmp  .-6
-; INST-NEXT: 04 c0      rjmp  .+8
-; INST-NEXT: 01 c0      rjmp  .+2
-; INST-NEXT: 00 c0      rjmp  .+0
+; INST-NEXT: 00 c0 rjmp .+0
+; INST-NEXT: R_AVR_13_PCREL .text+0x4
+; INST-NEXT: 00 c0 rjmp .+0
+; INST-NEXT: R_AVR_13_PCREL .text+0x2
+; INST-NEXT: 00 c0 rjmp .+0
+; INST-NEXT: R_AVR_13_PCREL .text
+; INST-NEXT: 00 c0 rjmp .+0
+; INST-NEXT: R_AVR_13_PCREL .text+0x10
+; INST-NEXT: 00 c0 rjmp .+0
+; INST-NEXT: R_AVR_13_PCREL .text+0xc
+; INST-NEXT: 00 c0 rjmp .+0
+; INST-NEXT: R_AVR_13_PCREL .text+0xc
 ; INST-EMPTY:
 ; INST-LABEL: <end>:
-; INST-NEXT: fe cf      rjmp  .-4
-; INST-NEXT: fd cf      rjmp  .-6
+; INST-NEXT: 00 c0 rjmp .+0
+; INST-NEXT: R_AVR_13_PCREL .text+0xa
+; INST-NEXT: 00 c0 rjmp .+0
+; INST-NEXT: R_AVR_13_PCREL .text+0xa
 ; INST-EMPTY:
 ; INST-LABEL: <x>:
-; INST-NEXT: ff cf      rjmp  .-2
-; INST-NEXT: 0f c0      rjmp  .+30
-; INST-NEXT: ff c7      rjmp  .+4094
+; INST-NEXT: 00 c0 rjmp .+0
+; INST-NEXT: R_AVR_13_PCREL .text+0x10
+; INST-NEXT: 0f c0 rjmp .+30
+; INST-NEXT: 00 c0 rjmp .+0
+; INST-NEXT: R_AVR_13_PCREL .text+0x1014



More information about the llvm-commits mailing list