Skip to content

Commit 5db0a45

Browse files
authored
[AVR] Fix a crash in AVRInstrInfo::insertIndirectBranch (#67324)
Fixes #67042
1 parent 6fe4e03 commit 5db0a45

File tree

3 files changed

+52
-9
lines changed

3 files changed

+52
-9
lines changed

llvm/lib/Target/AVR/AVRInstrInfo.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ void AVRInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
4343
MachineBasicBlock::iterator MI,
4444
const DebugLoc &DL, MCRegister DestReg,
4545
MCRegister SrcReg, bool KillSrc) const {
46-
const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
4746
const AVRRegisterInfo &TRI = *STI.getRegisterInfo();
4847
unsigned Opc;
4948

@@ -496,9 +495,7 @@ unsigned AVRInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
496495
const MachineFunction &MF = *MI.getParent()->getParent();
497496
const AVRTargetMachine &TM =
498497
static_cast<const AVRTargetMachine &>(MF.getTarget());
499-
const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
500498
const TargetInstrInfo &TII = *STI.getInstrInfo();
501-
502499
return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(),
503500
*TM.getMCAsmInfo());
504501
}
@@ -542,7 +539,7 @@ bool AVRInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
542539
llvm_unreachable("unexpected opcode!");
543540
case AVR::JMPk:
544541
case AVR::CALLk:
545-
return true;
542+
return STI.hasJMPCALL();
546543
case AVR::RCALLk:
547544
case AVR::RJMPk:
548545
return isIntN(13, BrOffset);
@@ -573,7 +570,10 @@ void AVRInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
573570
if (STI.hasJMPCALL())
574571
BuildMI(&MBB, DL, get(AVR::JMPk)).addMBB(&NewDestBB);
575572
else
576-
report_fatal_error("cannot create long jump without FeatureJMPCALL");
573+
// The RJMP may jump to a far place beyond its legal range. We let the
574+
// linker to report 'out of range' rather than crash, or silently emit
575+
// incorrect assembly code.
576+
BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(&NewDestBB);
577577
}
578578

579579
} // end of namespace llvm

llvm/test/CodeGen/AVR/branch-relaxation-long.ll

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
; RUN: llc < %s -march=avr -mattr=avr3 | FileCheck %s
1+
; RUN: llc < %s -march=avr -mattr=avr3 | FileCheck %s
2+
; RUN: llc < %s -march=avr -mattr=avr2 | FileCheck --check-prefix=AVR2 %s
23

34
; CHECK-LABEL: relax_to_jmp:
45
; CHECK: cpi r{{[0-9]+}}, 0
@@ -7,6 +8,18 @@
78
; CHECK: [[BB1]]:
89
; CHECK: nop
910
; CHECK: [[BB2]]:
11+
12+
;; A `RJMP` is generated instead of expected `JMP` for AVR2,
13+
;; and it is up to the linker to report 'out of range' or
14+
;; 'exceed flash maximum size'.
15+
; AVR2-LABEL: relax_to_jmp:
16+
; AVR2: cpi r{{[0-9]+}}, 0
17+
; AVR2: brne [[BB1:.LBB[0-9]+_[0-9]+]]
18+
; AVR2: rjmp [[BB2:.LBB[0-9]+_[0-9]+]]
19+
; AVR2: [[BB1]]:
20+
; AVR2: nop
21+
; AVR2: [[BB2]]:
22+
1023
define i8 @relax_to_jmp(i1 %a) {
1124
entry-block:
1225
br i1 %a, label %hello, label %finished
@@ -2075,6 +2088,18 @@ finished:
20752088
; CHECK: breq [[BB2:.LBB[0-9]+_[0-9]+]]
20762089
; CHECK: jmp [[BB1]]
20772090
; CHECK: [[BB2]]:
2091+
2092+
;; A `RJMP` is generated instead of expected `JMP` for AVR2,
2093+
;; and it is up to the linker to report 'out of range' or
2094+
;; 'exceed flash maximum size'.
2095+
; AVR2-LABEL: relax_to_jmp_backwards:
2096+
; AVR2: [[BB1:.LBB[0-9]+_[0-9]+]]
2097+
; AVR2: nop
2098+
; AVR2: cpi r{{[0-9]+}}, 0
2099+
; AVR2: breq [[BB2:.LBB[0-9]+_[0-9]+]]
2100+
; AVR2: rjmp [[BB1]]
2101+
; AVR2: [[BB2]]:
2102+
20782103
define i8 @relax_to_jmp_backwards(i1 %a) {
20792104
entry-block:
20802105
br label %hello

llvm/test/CodeGen/AVR/branch-relaxation.ll

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
11
; RUN: llc < %s -march=avr | FileCheck %s
2+
; RUN: llc < %s -march=avr -mcpu=avr5 | FileCheck -check-prefix=AVR5 %s
23

34
; CHECK-LABEL: relax_breq
45
; CHECK: cpi r{{[0-9]+}}, 0
56
; CHECK: brne .LBB0_1
67
; CHECK: rjmp .LBB0_2
7-
; .LBB0_1:
8+
; CHECK: .LBB0_1:
9+
; CHECK: nop
10+
; CHECK: .LBB0_2:
11+
12+
; AVR5-LABEL: relax_breq
13+
; AVR5: andi r24, 1
14+
; AVR5: cpi r24, 0
15+
; AVR5: brne .LBB0_1
16+
; AVR5: rjmp .LBB0_2
17+
; AVR5: .LBB0_1:
18+
; AVR5: nop
19+
; AVR5: .LBB0_2:
820

921
define i8 @relax_breq(i1 %a) {
1022
entry-block:
@@ -70,8 +82,14 @@ finished:
7082
; CHECK: cpi r{{[0-9]+}}, 0
7183
; CHECK: breq [[END_BB:.LBB[0-9]+_[0-9]+]]
7284
; CHECK: nop
73-
; ...
74-
; .LBB0_1:
85+
; CHECK: [[END_BB]]
86+
87+
; AVR5-LABEL: no_relax_breq
88+
; AVR5: cpi r{{[0-9]+}}, 0
89+
; AVR5: breq [[END_BB:.LBB[0-9]+_[0-9]+]]
90+
; AVR5: nop
91+
; AVR5: [[END_BB]]
92+
7593
define i8 @no_relax_breq(i1 %a) {
7694
entry-block:
7795
br i1 %a, label %hello, label %finished

0 commit comments

Comments
 (0)