Skip to content

Commit 1c68c4c

Browse files
authored
[LoongArch][MC] Modify branch evaluation for MCInstrAnalysis (#73205)
Function evaluateBranch() is used to compute target address for a given branch instruction and return true on success. But target address of indirect branch cannot be simply added, so rule it out and just return false. This patch also add objdump tests which capture the current state of support for printing branch targets. Without this patch, the result of "jirl $zero, $a0, 4" is "jirl $zero, $a0, 4 <foo+0x64>". It is obviously incorrect, because this instruction represents an indirect branch whose target address depends on both the register value and the imm. After this patch, it will be right despite loss of details.
1 parent 6367677 commit 1c68c4c

File tree

3 files changed

+80
-1
lines changed

3 files changed

+80
-1
lines changed

llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ class LoongArchMCInstrAnalysis : public MCInstrAnalysis {
9797
bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
9898
uint64_t &Target) const override {
9999
unsigned NumOps = Inst.getNumOperands();
100-
if (isBranch(Inst) || Inst.getOpcode() == LoongArch::BL) {
100+
if ((isBranch(Inst) && !isIndirectBranch(Inst)) ||
101+
Inst.getOpcode() == LoongArch::BL) {
101102
Target = Addr + Inst.getOperand(NumOps - 1).getImm();
102103
return true;
103104
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# RUN: llvm-mc --triple=loongarch32 --filetype=obj < %s | \
2+
# RUN: llvm-objdump -d --no-show-raw-insn - | FileCheck %s
3+
# RUN: llvm-mc --triple=loongarch64 --filetype=obj < %s | \
4+
# RUN: llvm-objdump -d --no-show-raw-insn - | FileCheck %s
5+
6+
# CHECK-LABEL: <foo>:
7+
foo:
8+
# CHECK: beq $a0, $a1, 108 <foo+0x6c>
9+
beq $a0, $a1, .Llocal
10+
# CHECK: bne $a0, $a1, 104 <foo+0x6c>
11+
bne $a0, $a1, .Llocal
12+
# CHECK: blt $a0, $a1, 100 <foo+0x6c>
13+
blt $a0, $a1, .Llocal
14+
# CHECK: bltu $a0, $a1, 96 <foo+0x6c>
15+
bltu $a0, $a1, .Llocal
16+
# CHECK: bge $a0, $a1, 92 <foo+0x6c>
17+
bge $a0, $a1, .Llocal
18+
# CHECK: bgeu $a0, $a1, 88 <foo+0x6c>
19+
bgeu $a0, $a1, .Llocal
20+
# CHECK: beqz $a0, 84 <foo+0x6c>
21+
beqz $a0, .Llocal
22+
# CHECK: bnez $a0, 80 <foo+0x6c>
23+
bnez $a0, .Llocal
24+
# CHECK: bceqz $fcc6, 76 <foo+0x6c>
25+
bceqz $fcc6, .Llocal
26+
# CHECK: bcnez $fcc6, 72 <foo+0x6c>
27+
bcnez $fcc6, .Llocal
28+
29+
# CHECK: beq $a0, $a1, 76 <bar>
30+
beq $a0, $a1, bar
31+
# CHECK: bne $a0, $a1, 72 <bar>
32+
bne $a0, $a1, bar
33+
# CHECK: blt $a0, $a1, 68 <bar>
34+
blt $a0, $a1, bar
35+
# CHECK: bltu $a0, $a1, 64 <bar>
36+
bltu $a0, $a1, bar
37+
# CHECK: bge $a0, $a1, 60 <bar>
38+
bge $a0, $a1, bar
39+
# CHECK: bgeu $a0, $a1, 56 <bar>
40+
bgeu $a0, $a1, bar
41+
# CHECK: beqz $a0, 52 <bar>
42+
beqz $a0, bar
43+
# CHECK: bnez $a0, 48 <bar>
44+
bnez $a0, bar
45+
# CHECK: bceqz $fcc6, 44 <bar>
46+
bceqz $fcc6, bar
47+
# CHECK: bcnez $fcc6, 40 <bar>
48+
bcnez $fcc6, bar
49+
50+
# CHECK: b 28 <foo+0x6c>
51+
b .Llocal
52+
# CHECK: b 32 <bar>
53+
b bar
54+
55+
# CHECK: bl 20 <foo+0x6c>
56+
bl .Llocal
57+
# CHECK: bl 24 <bar>
58+
bl bar
59+
60+
# CHECK: jirl $zero, $a0, 4{{$}}
61+
jirl $zero, $a0, 4
62+
# CHECK: jirl $ra, $a0, 4{{$}}
63+
jirl $ra, $a0, 4
64+
# CHECK: ret
65+
ret
66+
67+
.Llocal:
68+
# CHECK: 6c: nop
69+
# CHECK: nop
70+
nop
71+
nop
72+
73+
# CHECK-LABEL: <bar>:
74+
bar:
75+
# CHECK: 74: nop
76+
nop
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
if not "LoongArch" in config.root.targets:
2+
config.unsupported = True

0 commit comments

Comments
 (0)