[llvm] [AVR] Fix a crash in AVRInstrInfo::insertIndirectBranch (PR #67324)
Ben Shi via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 26 22:57:39 PDT 2023
https://github.com/benshi001 updated https://github.com/llvm/llvm-project/pull/67324
>From fa1581cf0f71fb5530946c9c11b6c6b2e882c6b0 Mon Sep 17 00:00:00 2001
From: Ben Shi <bennshi at tencent.com>
Date: Mon, 25 Sep 2023 20:38:26 +0800
Subject: [PATCH] [AVR] Fix a crash in AVRInstrInfo::insertIndirectBranch
Skip the BranchRelaxation pass on AVR devices without FeatureJMPCALL.
Current branch relaxation relies on the long jump instruction which
is not available on earlier devices.
A full solution should be introducing '--code-model' for AVR, and
emitting indirect jump instead of short direct jump if a larger code
model is specified.
Fixes https://github.com/llvm/llvm-project/issues/67042
---
llvm/lib/Target/AVR/AVRTargetMachine.cpp | 4 +++-
.../CodeGen/AVR/branch-relaxation-long.ll | 19 ++++++++++++++-
llvm/test/CodeGen/AVR/branch-relaxation.ll | 23 ++++++++++++++++---
llvm/test/CodeGen/AVR/ctlz.ll | 4 ++--
llvm/test/CodeGen/AVR/rot.ll | 16 ++++++-------
llvm/test/CodeGen/AVR/rotate.ll | 8 +++----
llvm/test/CodeGen/AVR/shift.ll | 14 +++++------
7 files changed, 62 insertions(+), 26 deletions(-)
diff --git a/llvm/lib/Target/AVR/AVRTargetMachine.cpp b/llvm/lib/Target/AVR/AVRTargetMachine.cpp
index e0776a6cab432f1..907310179a55547 100644
--- a/llvm/lib/Target/AVR/AVRTargetMachine.cpp
+++ b/llvm/lib/Target/AVR/AVRTargetMachine.cpp
@@ -132,7 +132,9 @@ void AVRPassConfig::addPreSched2() {
void AVRPassConfig::addPreEmitPass() {
// Must run branch selection immediately preceding the asm printer.
- addPass(&BranchRelaxationPassID);
+ // However we skip devices without FeatureJMPCALL.
+ if (getAVRTargetMachine().getSubtargetImpl()->hasJMPCALL())
+ addPass(&BranchRelaxationPassID);
}
} // 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..24425a4c3c0c976 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,14 @@
; CHECK: [[BB1]]:
; CHECK: nop
; CHECK: [[BB2]]:
+
+; AVR2-LABEL: relax_to_jmp:
+; AVR2: cpi r{{[0-9]+}}, 0
+; AVR2: breq [[BB2:.LBB[0-9]+_[0-9]+]]
+; AVR2: nop
+; AVR2: [[BB2]]:
+; AVR2-NOT: jmp .LBB
+
define i8 @relax_to_jmp(i1 %a) {
entry-block:
br i1 %a, label %hello, label %finished
@@ -2075,6 +2084,14 @@ finished:
; CHECK: breq [[BB2:.LBB[0-9]+_[0-9]+]]
; CHECK: jmp [[BB1]]
; CHECK: [[BB2]]:
+
+; AVR2-LABEL: relax_to_jmp_backwards:
+; AVR2: [[BB1:.LBB[0-9]+_[0-9]+]]
+; AVR2: nop
+; AVR2: cpi r{{[0-9]+}}, 0
+; AVR2: brne [[BB1:.LBB[0-9]+_[0-9]+]]
+; AVR2-NOT: jmp .LBB
+
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..3f19af897ed0c1f 100644
--- a/llvm/test/CodeGen/AVR/branch-relaxation.ll
+++ b/llvm/test/CodeGen/AVR/branch-relaxation.ll
@@ -1,10 +1,20 @@
; 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: breq .LBB0_2
+; 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:
@@ -72,6 +82,13 @@ finished:
; CHECK: nop
; ...
; .LBB0_1:
+
+; 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
diff --git a/llvm/test/CodeGen/AVR/ctlz.ll b/llvm/test/CodeGen/AVR/ctlz.ll
index 93c2f0bdfa41e9e..ae963ed32e6e12e 100644
--- a/llvm/test/CodeGen/AVR/ctlz.ll
+++ b/llvm/test/CodeGen/AVR/ctlz.ll
@@ -10,7 +10,7 @@ declare i8 @llvm.ctlz.i8(i8)
; CHECK-LABEL: count_leading_zeros:
; CHECK: cpi [[RESULT:r[0-9]+]], 0
-; CHECK: breq .LBB0_2
+; CHECK: breq .LBB0_1
; CHECK: mov [[SCRATCH:r[0-9]+]], {{.*}}[[RESULT]]
; CHECK: lsr {{.*}}[[SCRATCH]]
; CHECK: or {{.*}}[[SCRATCH]], {{.*}}[[RESULT]]
@@ -38,6 +38,6 @@ declare i8 @llvm.ctlz.i8(i8)
; CHECK: add {{.*}}[[RESULT]], {{.*}}[[SCRATCH]]
; CHECK: andi {{.*}}[[RESULT]], 15
; CHECK: ret
-; CHECK: LBB0_2:
+; CHECK: LBB0_1:
; CHECK: ldi {{.*}}[[RESULT]], 8
; CHECK: ret
diff --git a/llvm/test/CodeGen/AVR/rot.ll b/llvm/test/CodeGen/AVR/rot.ll
index 1a6b917af95b7aa..8e160009be10a39 100644
--- a/llvm/test/CodeGen/AVR/rot.ll
+++ b/llvm/test/CodeGen/AVR/rot.ll
@@ -7,26 +7,26 @@ define i8 @rol8(i8 %val, i8 %amt) {
; CHECK: ; %bb.0:
; CHECK-NEXT: andi r22, 7
; CHECK-NEXT: dec r22
-; CHECK-NEXT: brmi .LBB0_2
+; CHECK-NEXT: brmi .LBB0_3
; CHECK-NEXT: .LBB0_1: ; =>This Inner Loop Header: Depth=1
; CHECK-NEXT: lsl r24
; CHECK-NEXT: adc r24, r1
; CHECK-NEXT: dec r22
; CHECK-NEXT: brpl .LBB0_1
-; CHECK-NEXT: .LBB0_2:
+; CHECK-NEXT: .LBB0_3:
; CHECK-NEXT: ret
;
; TINY-LABEL: rol8:
; TINY: ; %bb.0:
; TINY-NEXT: andi r22, 7
; TINY-NEXT: dec r22
-; TINY-NEXT: brmi .LBB0_2
+; TINY-NEXT: brmi .LBB0_3
; TINY-NEXT: .LBB0_1: ; =>This Inner Loop Header: Depth=1
; TINY-NEXT: lsl r24
; TINY-NEXT: adc r24, r17
; TINY-NEXT: dec r22
; TINY-NEXT: brpl .LBB0_1
-; TINY-NEXT: .LBB0_2:
+; TINY-NEXT: .LBB0_3:
; TINY-NEXT: ret
%mod = urem i8 %amt, 8
%inv = sub i8 8, %mod
@@ -42,28 +42,28 @@ define i8 @ror8(i8 %val, i8 %amt) {
; CHECK: ; %bb.0:
; CHECK-NEXT: andi r22, 7
; CHECK-NEXT: dec r22
-; CHECK-NEXT: brmi .LBB1_2
+; CHECK-NEXT: brmi .LBB1_3
; CHECK-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1
; CHECK-NEXT: bst r24, 0
; CHECK-NEXT: ror r24
; CHECK-NEXT: bld r24, 7
; CHECK-NEXT: dec r22
; CHECK-NEXT: brpl .LBB1_1
-; CHECK-NEXT: .LBB1_2:
+; CHECK-NEXT: .LBB1_3:
; CHECK-NEXT: ret
;
; TINY-LABEL: ror8:
; TINY: ; %bb.0:
; TINY-NEXT: andi r22, 7
; TINY-NEXT: dec r22
-; TINY-NEXT: brmi .LBB1_2
+; TINY-NEXT: brmi .LBB1_3
; TINY-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1
; TINY-NEXT: bst r24, 0
; TINY-NEXT: ror r24
; TINY-NEXT: bld r24, 7
; TINY-NEXT: dec r22
; TINY-NEXT: brpl .LBB1_1
-; TINY-NEXT: .LBB1_2:
+; TINY-NEXT: .LBB1_3:
; TINY-NEXT: ret
%mod = urem i8 %amt, 8
%inv = sub i8 8, %mod
diff --git a/llvm/test/CodeGen/AVR/rotate.ll b/llvm/test/CodeGen/AVR/rotate.ll
index 79ff7928b3a3984..2c54763c6150d6f 100644
--- a/llvm/test/CodeGen/AVR/rotate.ll
+++ b/llvm/test/CodeGen/AVR/rotate.ll
@@ -54,14 +54,14 @@ define i8 @rotl8_dyn(i8 %x, i8 %y) {
; CHECK: ; %bb.0: ; %start
; CHECK-NEXT: andi r22, 7
; CHECK-NEXT: dec r22
-; CHECK-NEXT: brmi .LBB4_2
+; CHECK-NEXT: brmi .LBB4_3
; CHECK-NEXT: .LBB4_1: ; %start
; CHECK-NEXT: ; =>This Inner Loop Header: Depth=1
; CHECK-NEXT: lsl r24
; CHECK-NEXT: adc r24, r1
; CHECK-NEXT: dec r22
; CHECK-NEXT: brpl .LBB4_1
-; CHECK-NEXT: .LBB4_2: ; %start
+; CHECK-NEXT: .LBB4_3: ; %start
; CHECK-NEXT: ret
start:
%0 = call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %y)
@@ -121,7 +121,7 @@ define i8 @rotr8_dyn(i8 %x, i8 %y) {
; CHECK: ; %bb.0: ; %start
; CHECK-NEXT: andi r22, 7
; CHECK-NEXT: dec r22
-; CHECK-NEXT: brmi .LBB9_2
+; CHECK-NEXT: brmi .LBB9_3
; CHECK-NEXT: .LBB9_1: ; %start
; CHECK-NEXT: ; =>This Inner Loop Header: Depth=1
; CHECK-NEXT: bst r24, 0
@@ -129,7 +129,7 @@ define i8 @rotr8_dyn(i8 %x, i8 %y) {
; CHECK-NEXT: bld r24, 7
; CHECK-NEXT: dec r22
; CHECK-NEXT: brpl .LBB9_1
-; CHECK-NEXT: .LBB9_2: ; %start
+; CHECK-NEXT: .LBB9_3: ; %start
; CHECK-NEXT: ret
start:
%0 = call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %y)
diff --git a/llvm/test/CodeGen/AVR/shift.ll b/llvm/test/CodeGen/AVR/shift.ll
index c0abc77c9b14ae1..47b8b537b9ba7f6 100644
--- a/llvm/test/CodeGen/AVR/shift.ll
+++ b/llvm/test/CodeGen/AVR/shift.ll
@@ -6,12 +6,12 @@ define i8 @shift_i8_i8_speed(i8 %a, i8 %b) {
; CHECK-LABEL: shift_i8_i8_speed:
; CHECK: ; %bb.0:
; CHECK-NEXT: dec r22
-; CHECK-NEXT: brmi .LBB0_2
+; CHECK-NEXT: brmi .LBB0_3
; CHECK-NEXT: .LBB0_1: ; =>This Inner Loop Header: Depth=1
; CHECK-NEXT: lsl r24
; CHECK-NEXT: dec r22
; CHECK-NEXT: brpl .LBB0_1
-; CHECK-NEXT: .LBB0_2:
+; CHECK-NEXT: .LBB0_3:
; CHECK-NEXT: ret
%result = shl i8 %a, %b
ret i8 %result
@@ -21,12 +21,12 @@ define i8 @shift_i8_i8_speed(i8 %a, i8 %b) {
define i8 @shift_i8_i8_size(i8 %a, i8 %b) optsize {
; CHECK-LABEL: shift_i8_i8_size:
; CHECK: ; %bb.0:
-; CHECK-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: .LBB1_2: ; =>This Inner Loop Header: Depth=1
; CHECK-NEXT: dec r22
; CHECK-NEXT: brmi .LBB1_3
-; CHECK-NEXT: ; %bb.2: ; in Loop: Header=BB1_1 Depth=1
+; CHECK-NEXT: ; %bb.1: ; in Loop: Header=BB1_2 Depth=1
; CHECK-NEXT: lsl r24
-; CHECK-NEXT: rjmp .LBB1_1
+; CHECK-NEXT: rjmp .LBB1_2
; CHECK-NEXT: .LBB1_3:
; CHECK-NEXT: ret
%result = shl i8 %a, %b
@@ -37,13 +37,13 @@ define i16 @shift_i16_i16(i16 %a, i16 %b) {
; CHECK-LABEL: shift_i16_i16:
; CHECK: ; %bb.0:
; CHECK-NEXT: dec r22
-; CHECK-NEXT: brmi .LBB2_2
+; CHECK-NEXT: brmi .LBB2_3
; CHECK-NEXT: .LBB2_1: ; =>This Inner Loop Header: Depth=1
; CHECK-NEXT: lsl r24
; CHECK-NEXT: rol r25
; CHECK-NEXT: dec r22
; CHECK-NEXT: brpl .LBB2_1
-; CHECK-NEXT: .LBB2_2:
+; CHECK-NEXT: .LBB2_3:
; CHECK-NEXT: ret
%result = shl i16 %a, %b
ret i16 %result
More information about the llvm-commits
mailing list