[llvm] 8aae191 - [BPF] Remove 'may_goto 0' instructions (#123482)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 28 15:19:12 PST 2025


Author: yonghong-song
Date: 2025-01-28T15:19:05-08:00
New Revision: 8aae191cb6ad1f2dfc468975e4f5e564fea3cbfd

URL: https://github.com/llvm/llvm-project/commit/8aae191cb6ad1f2dfc468975e4f5e564fea3cbfd
DIFF: https://github.com/llvm/llvm-project/commit/8aae191cb6ad1f2dfc468975e4f5e564fea3cbfd.diff

LOG: [BPF] Remove 'may_goto 0' instructions (#123482)

Emil Tsalapatis from Meta reported such a case where 'may_goto 0' insn
is generated by clang compiler. But 'may_goto 0' insn is actually a
no-op so it makes sense to remove that in llvm. The patch is also able
to handle the following code pattern
```
   ...
   may_goto 2
   may_goto 1
   may_goto 0
   ...
```
where three may_goto insns can all be removed.

---------

Co-authored-by: Yonghong Song <yonghong.song at linux.dev>

Added: 
    llvm/test/CodeGen/BPF/may_goto_1.ll
    llvm/test/CodeGen/BPF/may_goto_2.ll

Modified: 
    llvm/lib/Target/BPF/BPFMIPeephole.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/BPF/BPFMIPeephole.cpp b/llvm/lib/Target/BPF/BPFMIPeephole.cpp
index 2b17f2aaefe2bf..106572cdeb8401 100644
--- a/llvm/lib/Target/BPF/BPFMIPeephole.cpp
+++ b/llvm/lib/Target/BPF/BPFMIPeephole.cpp
@@ -24,6 +24,7 @@
 #include "BPFInstrInfo.h"
 #include "BPFTargetMachine.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/CodeGen/LivePhysRegs.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
@@ -322,6 +323,7 @@ struct BPFMIPreEmitPeephole : public MachineFunctionPass {
   bool eliminateRedundantMov();
   bool adjustBranch();
   bool insertMissingCallerSavedSpills();
+  bool removeMayGotoZero();
 
 public:
 
@@ -337,6 +339,7 @@ struct BPFMIPreEmitPeephole : public MachineFunctionPass {
     if (SupportGotol)
       Changed = adjustBranch() || Changed;
     Changed |= insertMissingCallerSavedSpills();
+    Changed |= removeMayGotoZero();
     return Changed;
   }
 };
@@ -682,6 +685,59 @@ bool BPFMIPreEmitPeephole::insertMissingCallerSavedSpills() {
   return Changed;
 }
 
+bool BPFMIPreEmitPeephole::removeMayGotoZero() {
+  bool Changed = false;
+  MachineBasicBlock *Prev_MBB, *Curr_MBB = nullptr;
+
+  for (MachineBasicBlock &MBB : make_early_inc_range(reverse(*MF))) {
+    Prev_MBB = Curr_MBB;
+    Curr_MBB = &MBB;
+    if (Prev_MBB == nullptr || Curr_MBB->empty())
+      continue;
+
+    MachineInstr &MI = Curr_MBB->back();
+    if (MI.getOpcode() != TargetOpcode::INLINEASM_BR)
+      continue;
+
+    const char *AsmStr = MI.getOperand(0).getSymbolName();
+    SmallVector<StringRef, 4> AsmPieces;
+    SplitString(AsmStr, AsmPieces, ";\n");
+
+    // Do not support multiple insns in one inline asm.
+    if (AsmPieces.size() != 1)
+      continue;
+
+    // The asm insn must be a may_goto insn.
+    SmallVector<StringRef, 4> AsmOpPieces;
+    SplitString(AsmPieces[0], AsmOpPieces, " ");
+    if (AsmOpPieces.size() != 2 || AsmOpPieces[0] != "may_goto")
+      continue;
+    // Enforce the format of 'may_goto <label>'.
+    if (AsmOpPieces[1] != "${0:l}" && AsmOpPieces[1] != "$0")
+      continue;
+
+    // Get the may_goto branch target.
+    MachineOperand &MO = MI.getOperand(InlineAsm::MIOp_FirstOperand + 1);
+    if (!MO.isMBB() || MO.getMBB() != Prev_MBB)
+      continue;
+
+    Changed = true;
+    if (Curr_MBB->begin() == MI) {
+      // Single 'may_goto' insn in the same basic block.
+      Curr_MBB->removeSuccessor(Prev_MBB);
+      for (MachineBasicBlock *Pred : Curr_MBB->predecessors())
+        Pred->replaceSuccessor(Curr_MBB, Prev_MBB);
+      Curr_MBB->eraseFromParent();
+      Curr_MBB = Prev_MBB;
+    } else {
+      // Remove 'may_goto' insn.
+      MI.eraseFromParent();
+    }
+  }
+
+  return Changed;
+}
+
 } // end default namespace
 
 INITIALIZE_PASS(BPFMIPreEmitPeephole, "bpf-mi-pemit-peephole",

diff  --git a/llvm/test/CodeGen/BPF/may_goto_1.ll b/llvm/test/CodeGen/BPF/may_goto_1.ll
new file mode 100644
index 00000000000000..a47716509c7aba
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/may_goto_1.ll
@@ -0,0 +1,27 @@
+; RUN: llc -mtriple=bpfel -mcpu=v3 -filetype=obj -o - %s | llvm-objdump --no-show-raw-insn -d - | FileCheck %s
+
+ at j = dso_local local_unnamed_addr global i32 0, align 4
+
+define dso_local noundef i32 @foo() local_unnamed_addr {
+entry:
+  callbr void asm sideeffect "may_goto ${0:l}", "!i"()
+          to label %for.body [label %for.cond.cleanup]
+
+for.cond.cleanup:                                 ; preds = %for.body.2, %for.body.2, %for.body.1, %for.body, %entry
+  ret i32 0
+
+for.body:                                         ; preds = %entry
+  callbr void asm sideeffect "may_goto ${0:l}", "!i"()
+          to label %for.body.1 [label %for.cond.cleanup]
+
+for.body.1:                                       ; preds = %for.body
+  callbr void asm sideeffect "may_goto ${0:l}", "!i"()
+          to label %for.body.2 [label %for.cond.cleanup]
+
+for.body.2:                                       ; preds = %for.body.1
+  callbr void asm sideeffect "may_goto ${0:l}", "!i"()
+          to label %for.cond.cleanup [label %for.cond.cleanup]
+}
+
+; CHECK:       0:       w0 = 0x0
+; CHECK-NEXT:  1:       exit

diff  --git a/llvm/test/CodeGen/BPF/may_goto_2.ll b/llvm/test/CodeGen/BPF/may_goto_2.ll
new file mode 100644
index 00000000000000..8f6fea5913d2ab
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/may_goto_2.ll
@@ -0,0 +1,27 @@
+; RUN: llc -mtriple=bpfel -mcpu=v3 -filetype=obj -o - %s | llvm-objdump --no-show-raw-insn -d - | FileCheck %s
+
+ at j = dso_local local_unnamed_addr global i32 0, align 4
+
+define dso_local noundef i32 @foo() local_unnamed_addr {
+entry:
+  callbr void asm sideeffect "may_goto $0", "!i"()
+          to label %for.body [label %for.cond.cleanup]
+
+for.cond.cleanup:                                 ; preds = %for.body.2, %for.body.2, %for.body.1, %for.body, %entry
+  ret i32 0
+
+for.body:                                         ; preds = %entry
+  callbr void asm sideeffect "may_goto $0", "!i"()
+          to label %for.body.1 [label %for.cond.cleanup]
+
+for.body.1:                                       ; preds = %for.body
+  callbr void asm sideeffect "may_goto $0", "!i"()
+          to label %for.body.2 [label %for.cond.cleanup]
+
+for.body.2:                                       ; preds = %for.body.1
+  callbr void asm sideeffect "may_goto $0", "!i"()
+          to label %for.cond.cleanup [label %for.cond.cleanup]
+}
+
+; CHECK:       0:       w0 = 0x0
+; CHECK-NEXT:  1:       exit


        


More information about the llvm-commits mailing list