[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