[llvm] [LoongArch][MC] Modify branch evaluation for MCInstrAnalysis (PR #73205)

via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 22 19:56:30 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-loongarch

@llvm/pr-subscribers-llvm-binary-utilities

Author: ZhaoQi (zhaoqi5)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/73205.diff


3 Files Affected:

- (modified) llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.cpp (+2-1) 
- (added) llvm/test/tools/llvm-objdump/ELF/LoongArch/branches.s (+76) 
- (added) llvm/test/tools/llvm-objdump/ELF/LoongArch/lit.local.cfg (+2) 


``````````diff
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.cpp
index d580c3457fecff8..a4e6a09863e6a68 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.cpp
@@ -97,7 +97,8 @@ class LoongArchMCInstrAnalysis : public MCInstrAnalysis {
   bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
                       uint64_t &Target) const override {
     unsigned NumOps = Inst.getNumOperands();
-    if (isBranch(Inst) || Inst.getOpcode() == LoongArch::BL) {
+    if ((isBranch(Inst) && !isIndirectBranch(Inst)) ||
+        Inst.getOpcode() == LoongArch::BL) {
       Target = Addr + Inst.getOperand(NumOps - 1).getImm();
       return true;
     }
diff --git a/llvm/test/tools/llvm-objdump/ELF/LoongArch/branches.s b/llvm/test/tools/llvm-objdump/ELF/LoongArch/branches.s
new file mode 100644
index 000000000000000..8cb00aef9954272
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/ELF/LoongArch/branches.s
@@ -0,0 +1,76 @@
+# RUN: llvm-mc --triple=loongarch32 --filetype=obj < %s | \
+# RUN:   llvm-objdump -d --no-show-raw-insn - | FileCheck %s
+# RUN: llvm-mc --triple=loongarch64 --filetype=obj < %s | \
+# RUN:   llvm-objdump -d --no-show-raw-insn - | FileCheck %s
+
+# CHECK-LABEL: <foo>:
+foo:
+# CHECK: beq $a0, $a1, 108 <foo+0x6c>
+beq $a0, $a1, .Llocal
+# CHECK: bne $a0, $a1, 104 <foo+0x6c>
+bne $a0, $a1, .Llocal
+# CHECK: blt $a0, $a1, 100 <foo+0x6c>
+blt $a0, $a1, .Llocal
+# CHECK: bltu $a0, $a1, 96 <foo+0x6c>
+bltu $a0, $a1, .Llocal
+# CHECK: bge $a0, $a1, 92 <foo+0x6c>
+bge $a0, $a1, .Llocal
+# CHECK: bgeu $a0, $a1, 88 <foo+0x6c>
+bgeu $a0, $a1, .Llocal
+# CHECK: beqz $a0, 84 <foo+0x6c>
+beqz $a0, .Llocal
+# CHECK: bnez $a0, 80 <foo+0x6c>
+bnez $a0, .Llocal
+# CHECK: bceqz $fcc6, 76 <foo+0x6c>
+bceqz $fcc6, .Llocal
+# CHECK: bcnez $fcc6, 72 <foo+0x6c>
+bcnez $fcc6, .Llocal
+
+# CHECK: beq $a0, $a1, 76 <bar>
+beq $a0, $a1, bar
+# CHECK: bne $a0, $a1, 72 <bar>
+bne $a0, $a1, bar
+# CHECK: blt $a0, $a1, 68 <bar>
+blt $a0, $a1, bar
+# CHECK: bltu $a0, $a1, 64 <bar>
+bltu $a0, $a1, bar
+# CHECK: bge $a0, $a1, 60 <bar>
+bge $a0, $a1, bar
+# CHECK: bgeu $a0, $a1, 56 <bar>
+bgeu $a0, $a1, bar
+# CHECK: beqz $a0, 52 <bar>
+beqz $a0, bar
+# CHECK: bnez $a0, 48 <bar>
+bnez $a0, bar
+# CHECK: bceqz $fcc6, 44 <bar>
+bceqz $fcc6, bar
+# CHECK: bcnez $fcc6, 40 <bar>
+bcnez $fcc6, bar
+
+# CHECK: b 28 <foo+0x6c>
+b .Llocal
+# CHECK: b 32 <bar>
+b bar
+
+# CHECK: bl 20 <foo+0x6c>
+bl .Llocal
+# CHECK: bl 24 <bar>
+bl bar
+
+# CHECK: jirl $zero, $a0, 4{{$}}
+jirl $zero, $a0, 4
+# CHECK: jirl $ra, $a0, 4{{$}}
+jirl $ra, $a0, 4
+# CHECK: ret
+ret
+
+.Llocal:
+# CHECK: 6c: nop
+# CHECK: nop
+nop
+nop
+
+# CHECK-LABEL: <bar>:
+bar:
+# CHECK: 74: nop
+nop
diff --git a/llvm/test/tools/llvm-objdump/ELF/LoongArch/lit.local.cfg b/llvm/test/tools/llvm-objdump/ELF/LoongArch/lit.local.cfg
new file mode 100644
index 000000000000000..cc24278acbb414a
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/ELF/LoongArch/lit.local.cfg
@@ -0,0 +1,2 @@
+if not "LoongArch" in config.root.targets:
+    config.unsupported = True

``````````

</details>


https://github.com/llvm/llvm-project/pull/73205


More information about the llvm-commits mailing list