[llvm] 5db0a45 - [AVR] Fix a crash in AVRInstrInfo::insertIndirectBranch (#67324)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 2 06:14:25 PDT 2023
Author: Ben Shi
Date: 2023-10-02T21:14:22+08:00
New Revision: 5db0a450be757de46edcc375134546023f2cb081
URL: https://github.com/llvm/llvm-project/commit/5db0a450be757de46edcc375134546023f2cb081
DIFF: https://github.com/llvm/llvm-project/commit/5db0a450be757de46edcc375134546023f2cb081.diff
LOG: [AVR] Fix a crash in AVRInstrInfo::insertIndirectBranch (#67324)
Fixes https://github.com/llvm/llvm-project/issues/67042
Added:
Modified:
llvm/lib/Target/AVR/AVRInstrInfo.cpp
llvm/test/CodeGen/AVR/branch-relaxation-long.ll
llvm/test/CodeGen/AVR/branch-relaxation.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.cpp b/llvm/lib/Target/AVR/AVRInstrInfo.cpp
index b9d27c78ce8e41e..2640ad9e3626739 100644
--- a/llvm/lib/Target/AVR/AVRInstrInfo.cpp
+++ b/llvm/lib/Target/AVR/AVRInstrInfo.cpp
@@ -43,7 +43,6 @@ void AVRInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
const DebugLoc &DL, MCRegister DestReg,
MCRegister SrcReg, bool KillSrc) const {
- const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
const AVRRegisterInfo &TRI = *STI.getRegisterInfo();
unsigned Opc;
@@ -496,9 +495,7 @@ unsigned AVRInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
const MachineFunction &MF = *MI.getParent()->getParent();
const AVRTargetMachine &TM =
static_cast<const AVRTargetMachine &>(MF.getTarget());
- const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
const TargetInstrInfo &TII = *STI.getInstrInfo();
-
return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(),
*TM.getMCAsmInfo());
}
@@ -542,7 +539,7 @@ bool AVRInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
llvm_unreachable("unexpected opcode!");
case AVR::JMPk:
case AVR::CALLk:
- return true;
+ return STI.hasJMPCALL();
case AVR::RCALLk:
case AVR::RJMPk:
return isIntN(13, BrOffset);
@@ -573,7 +570,10 @@ void AVRInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
if (STI.hasJMPCALL())
BuildMI(&MBB, DL, get(AVR::JMPk)).addMBB(&NewDestBB);
else
- report_fatal_error("cannot create long jump without FeatureJMPCALL");
+ // 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);
}
} // end of namespace llvm
diff --git a/llvm/test/CodeGen/AVR/branch-relaxation-long.ll b/llvm/test/CodeGen/AVR/branch-relaxation-long.ll
index b09976320b56221..bca505e5edd5f1d 100644
--- a/llvm/test/CodeGen/AVR/branch-relaxation-long.ll
+++ b/llvm/test/CodeGen/AVR/branch-relaxation-long.ll
@@ -1,4 +1,5 @@
-; RUN: llc < %s -march=avr -mattr=avr3 | FileCheck %s
+; RUN: llc < %s -march=avr -mattr=avr3 | FileCheck %s
+; RUN: llc < %s -march=avr -mattr=avr2 | FileCheck --check-prefix=AVR2 %s
; CHECK-LABEL: relax_to_jmp:
; CHECK: cpi r{{[0-9]+}}, 0
@@ -7,6 +8,18 @@
; CHECK: [[BB1]]:
; CHECK: nop
; CHECK: [[BB2]]:
+
+;; 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]]:
+
define i8 @relax_to_jmp(i1 %a) {
entry-block:
br i1 %a, label %hello, label %finished
@@ -2075,6 +2088,18 @@ finished:
; CHECK: breq [[BB2:.LBB[0-9]+_[0-9]+]]
; CHECK: jmp [[BB1]]
; CHECK: [[BB2]]:
+
+;; 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]]:
+
define i8 @relax_to_jmp_backwards(i1 %a) {
entry-block:
br label %hello
diff --git a/llvm/test/CodeGen/AVR/branch-relaxation.ll b/llvm/test/CodeGen/AVR/branch-relaxation.ll
index cee3963c1ee3efb..3958cca8f207586 100644
--- a/llvm/test/CodeGen/AVR/branch-relaxation.ll
+++ b/llvm/test/CodeGen/AVR/branch-relaxation.ll
@@ -1,10 +1,22 @@
; RUN: llc < %s -march=avr | FileCheck %s
+; RUN: llc < %s -march=avr -mcpu=avr5 | FileCheck -check-prefix=AVR5 %s
; CHECK-LABEL: relax_breq
; CHECK: cpi r{{[0-9]+}}, 0
; CHECK: brne .LBB0_1
; CHECK: rjmp .LBB0_2
-; .LBB0_1:
+; CHECK: .LBB0_1:
+; CHECK: nop
+; CHECK: .LBB0_2:
+
+; AVR5-LABEL: relax_breq
+; AVR5: andi r24, 1
+; AVR5: cpi r24, 0
+; AVR5: brne .LBB0_1
+; AVR5: rjmp .LBB0_2
+; AVR5: .LBB0_1:
+; AVR5: nop
+; AVR5: .LBB0_2:
define i8 @relax_breq(i1 %a) {
entry-block:
@@ -70,8 +82,14 @@ finished:
; CHECK: cpi r{{[0-9]+}}, 0
; CHECK: breq [[END_BB:.LBB[0-9]+_[0-9]+]]
; CHECK: nop
-; ...
-; .LBB0_1:
+; CHECK: [[END_BB]]
+
+; AVR5-LABEL: no_relax_breq
+; AVR5: cpi r{{[0-9]+}}, 0
+; AVR5: breq [[END_BB:.LBB[0-9]+_[0-9]+]]
+; AVR5: nop
+; AVR5: [[END_BB]]
+
define i8 @no_relax_breq(i1 %a) {
entry-block:
br i1 %a, label %hello, label %finished
More information about the llvm-commits
mailing list