[llvm-branch-commits] [llvm] [LoongArch] Add late branch optimization pass (PR #216261)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Aug 13 23:43:24 PDT 2026


https://github.com/heiher created https://github.com/llvm/llvm-project/pull/216261

The patch adds a late optimization pass that replaces conditional branches that can be statically evaluated with an unconditinal branch.

This pass is inspired by RISC-V's RISCVLateBranchOpt pass.

>From 08d3ff7cacea5f4f12dc49001f81e04c66666e37 Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui at loongson.cn>
Date: Thu, 13 Aug 2026 17:57:27 +0800
Subject: [PATCH] [LoongArch] Add late branch optimization pass

The patch adds a late optimization pass that replaces conditional
branches that can be statically evaluated with an unconditinal branch.

This pass is inspired by RISC-V's RISCVLateBranchOpt pass.
---
 llvm/lib/Target/LoongArch/CMakeLists.txt      |   1 +
 llvm/lib/Target/LoongArch/LoongArch.h         |   2 +
 .../LoongArch/LoongArchISelLowering.cpp       |  14 +
 .../LoongArch/LoongArchLateBranchOpt.cpp      | 122 ++++++
 .../LoongArch/LoongArchTargetMachine.cpp      |   8 +
 llvm/test/CodeGen/LoongArch/branch-opt.ll     | 351 +++---------------
 llvm/test/CodeGen/LoongArch/jr-without-ra.ll  |  90 ++---
 llvm/test/CodeGen/LoongArch/opt-pipeline.ll   |   4 +
 llvm/test/CodeGen/LoongArch/pr215935.ll       |  10 -
 ...arch_generated_funcs.ll.generated.expected |  20 +-
 ...ch_generated_funcs.ll.nogenerated.expected |  20 +-
 .../llvm/lib/Target/LoongArch/BUILD.gn        |   1 +
 12 files changed, 241 insertions(+), 402 deletions(-)
 create mode 100644 llvm/lib/Target/LoongArch/LoongArchLateBranchOpt.cpp

diff --git a/llvm/lib/Target/LoongArch/CMakeLists.txt b/llvm/lib/Target/LoongArch/CMakeLists.txt
index c856173ca89de..084544ff4112d 100644
--- a/llvm/lib/Target/LoongArch/CMakeLists.txt
+++ b/llvm/lib/Target/LoongArch/CMakeLists.txt
@@ -24,6 +24,7 @@ add_llvm_target(LoongArchCodeGen
   LoongArchInstrInfo.cpp
   LoongArchISelDAGToDAG.cpp
   LoongArchISelLowering.cpp
+  LoongArchLateBranchOpt.cpp
   LoongArchMCInstLower.cpp
   LoongArchMergeBaseOffset.cpp
   LoongArchOptWInstrs.cpp
diff --git a/llvm/lib/Target/LoongArch/LoongArch.h b/llvm/lib/Target/LoongArch/LoongArch.h
index e5b3083348792..6762f91df72d9 100644
--- a/llvm/lib/Target/LoongArch/LoongArch.h
+++ b/llvm/lib/Target/LoongArch/LoongArch.h
@@ -41,6 +41,7 @@ FunctionPass *createLoongArchMergeBaseOffsetOptPass();
 FunctionPass *createLoongArchOptWInstrsPass();
 FunctionPass *createLoongArchPreRAExpandPseudoPass();
 FunctionPass *createLoongArchExpandPseudoPass();
+FunctionPass *createLoongArchLateBranchOptPass();
 void initializeLoongArchAsmPrinterPass(PassRegistry &);
 void initializeLoongArchDAGToDAGISelLegacyPass(PassRegistry &);
 void initializeLoongArchDeadRegisterDefinitionsPass(PassRegistry &);
@@ -49,6 +50,7 @@ void initializeLoongArchMergeBaseOffsetOptPass(PassRegistry &);
 void initializeLoongArchOptWInstrsPass(PassRegistry &);
 void initializeLoongArchPreRAExpandPseudoPass(PassRegistry &);
 void initializeLoongArchExpandPseudoPass(PassRegistry &);
+void initializeLoongArchLateBranchOptPass(PassRegistry &);
 } // end namespace llvm
 
 #endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCH_H
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 92e1feb07ae50..55f779a612909 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -7314,6 +7314,20 @@ static bool combine_CC(SDValue &LHS, SDValue &RHS, SDValue &CC, const SDLoc &DL,
     }
   }
 
+  // Fold (C1, C2, cond) -> (0, 0, seteq/setne)
+  if (isa<ConstantSDNode>(LHS) && isa<ConstantSDNode>(RHS)) {
+    const LoongArchTargetLowering *TLI = Subtarget.getTargetLowering();
+    EVT VT = LHS.getValueType();
+    EVT SetCCResVT =
+        TLI->getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
+    if (SDValue Folded = DAG.FoldSetCC(SetCCResVT, LHS, RHS, CCVal, DL)) {
+      LHS = DAG.getConstant(0, DL, VT);
+      RHS = DAG.getConstant(0, DL, VT);
+      CC = DAG.getCondCode(!isNullConstant(Folded) ? ISD::SETEQ : ISD::SETNE);
+      return true;
+    }
+  }
+
   return false;
 }
 
diff --git a/llvm/lib/Target/LoongArch/LoongArchLateBranchOpt.cpp b/llvm/lib/Target/LoongArch/LoongArchLateBranchOpt.cpp
new file mode 100644
index 0000000000000..988b0427cfae2
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/LoongArchLateBranchOpt.cpp
@@ -0,0 +1,122 @@
+//===-- LoongArchLateBranchOpt.cpp - Late Stage Branch Optimization
+//-----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// This file provides LoongArch specific target optimizations, currently it's
+/// limited to convert conditional branches into unconditional branches when
+/// the condition can be statically evaluated.
+///
+//===----------------------------------------------------------------------===//
+
+#include "LoongArchInstrInfo.h"
+#include "LoongArchSubtarget.h"
+
+using namespace llvm;
+
+#define LOONGARCH_LATE_BRANCH_OPT_NAME "LoongArch Late Branch Optimisation Pass"
+
+namespace {
+
+struct LoongArchLateBranchOpt : public MachineFunctionPass {
+  static char ID;
+
+  LoongArchLateBranchOpt() : MachineFunctionPass(ID) {}
+
+  StringRef getPassName() const override {
+    return LOONGARCH_LATE_BRANCH_OPT_NAME;
+  }
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    MachineFunctionPass::getAnalysisUsage(AU);
+  }
+
+  bool runOnMachineFunction(MachineFunction &Fn) override;
+
+private:
+  bool runOnBasicBlock(MachineBasicBlock &MBB) const;
+
+  const LoongArchInstrInfo *TII = nullptr;
+};
+} // namespace
+
+char LoongArchLateBranchOpt::ID = 0;
+INITIALIZE_PASS(LoongArchLateBranchOpt, "loongarch-late-branch-opt",
+                LOONGARCH_LATE_BRANCH_OPT_NAME, false, false)
+
+bool LoongArchLateBranchOpt::runOnBasicBlock(MachineBasicBlock &MBB) const {
+  MachineBasicBlock *TBB, *FBB;
+  SmallVector<MachineOperand, 4> Cond;
+  if (TII->analyzeBranch(MBB, TBB, FBB, Cond, /*AllowModify=*/false))
+    return false;
+
+  if (!TBB || Cond.size() < 1)
+    return false;
+
+  // Try and convert a conditional branch that can be evaluated statically
+  // into an unconditional branch.
+  unsigned Opc = Cond[0].getImm();
+  MachineBasicBlock *Folded;
+  switch (Opc) {
+  case LoongArch::BEQZ:
+  case LoongArch::BNEZ:
+    if (Cond.size() < 2 || !Cond[1].isReg() ||
+        Cond[1].getReg() != LoongArch::R0)
+      return false;
+    Folded = (Opc == LoongArch::BEQZ) ? TBB : FBB;
+    break;
+  case LoongArch::BEQ:
+  case LoongArch::BNE:
+    if (Cond.size() < 3 || !Cond[1].isReg() || !Cond[2].isReg() ||
+        Cond[1].getReg() != Cond[2].getReg())
+      return false;
+    Folded = (Opc == LoongArch::BEQ) ? TBB : FBB;
+    break;
+  default:
+    return false;
+  }
+
+  // At this point, its legal to optimize.
+  TII->removeBranch(MBB);
+
+  // Only need to insert a branch if we're not falling through.
+  if (Folded) {
+    DebugLoc DL = MBB.findBranchDebugLoc();
+    TII->insertBranch(MBB, Folded, nullptr, {}, DL);
+  }
+
+  // Update the successors. Remove them all and add back the correct one.
+  while (!MBB.succ_empty())
+    MBB.removeSuccessor(MBB.succ_end() - 1);
+
+  // If it's a fallthrough, we need to figure out where MBB is going.
+  if (!Folded) {
+    MachineFunction::iterator Fallthrough = ++MBB.getIterator();
+    if (Fallthrough != MBB.getParent()->end())
+      MBB.addSuccessor(&*Fallthrough);
+  } else
+    MBB.addSuccessor(Folded);
+
+  return true;
+}
+
+bool LoongArchLateBranchOpt::runOnMachineFunction(MachineFunction &Fn) {
+  if (skipFunction(Fn.getFunction()))
+    return false;
+
+  auto &ST = Fn.getSubtarget<LoongArchSubtarget>();
+  TII = ST.getInstrInfo();
+
+  bool Changed = false;
+  for (MachineBasicBlock &MBB : Fn)
+    Changed |= runOnBasicBlock(MBB);
+  return Changed;
+}
+
+FunctionPass *llvm::createLoongArchLateBranchOptPass() {
+  return new LoongArchLateBranchOpt();
+}
diff --git a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
index fb0053b7077e4..027650f92a08a 100644
--- a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
@@ -44,6 +44,7 @@ LLVMInitializeLoongArchTarget() {
   initializeLoongArchExpandPseudoPass(*PR);
   initializeLoongArchDAGToDAGISelLegacyPass(*PR);
   initializeLoongArchExpandAtomicPseudoPass(*PR);
+  initializeLoongArchLateBranchOptPass(*PR);
 }
 
 static cl::opt<bool> EnableLoongArchDeadRegisterElimination(
@@ -165,6 +166,7 @@ class LoongArchPassConfig : public TargetPassConfig {
   void addPreRegAlloc() override;
   bool addRegAssignAndRewriteFast() override;
   bool addRegAssignAndRewriteOptimized() override;
+  void addMachineLateOptimization() override;
 };
 } // end namespace
 
@@ -239,3 +241,9 @@ bool LoongArchPassConfig::addRegAssignAndRewriteOptimized() {
     addPass(createLoongArchDeadRegisterDefinitionsPass());
   return TargetPassConfig::addRegAssignAndRewriteOptimized();
 }
+
+void LoongArchPassConfig::addMachineLateOptimization() {
+  if (TM->getOptLevel() != CodeGenOptLevel::None)
+    addPass(createLoongArchLateBranchOptPass());
+  TargetPassConfig::addMachineLateOptimization();
+}
diff --git a/llvm/test/CodeGen/LoongArch/branch-opt.ll b/llvm/test/CodeGen/LoongArch/branch-opt.ll
index 2a7712afb44af..fa4b558a58d55 100644
--- a/llvm/test/CodeGen/LoongArch/branch-opt.ll
+++ b/llvm/test/CodeGen/LoongArch/branch-opt.ll
@@ -1,38 +1,13 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc --mtriple=loongarch32 -mattr=-32s,+d --verify-machineinstrs < %s | FileCheck %s --check-prefix=LA32R
-; RUN: llc --mtriple=loongarch32 -mattr=+32s,+d --verify-machineinstrs < %s | FileCheck %s --check-prefix=LA32S
-; RUN: llc --mtriple=loongarch64 -mattr=+d --verify-machineinstrs < %s | FileCheck %s --check-prefix=LA64
+; RUN: llc --mtriple=loongarch32 -mattr=-32s,+d --verify-machineinstrs < %s | FileCheck %s
+; RUN: llc --mtriple=loongarch32 -mattr=+32s,+d --verify-machineinstrs < %s | FileCheck %s
+; RUN: llc --mtriple=loongarch64 -mattr=+d --verify-machineinstrs < %s | FileCheck %s
 
 define i32 @br_eq() nounwind {
-; LA32R-LABEL: br_eq:
-; LA32R:       # %bb.0: # %entry
-; LA32R-NEXT:    beq $zero, $zero, .LBB0_2
-; LA32R-NEXT:  # %bb.1:
-; LA32R-NEXT:    ori $a0, $zero, 1
-; LA32R-NEXT:    ret
-; LA32R-NEXT:  .LBB0_2:
-; LA32R-NEXT:    move $a0, $zero
-; LA32R-NEXT:    ret
-;
-; LA32S-LABEL: br_eq:
-; LA32S:       # %bb.0: # %entry
-; LA32S-NEXT:    beqz $zero, .LBB0_2
-; LA32S-NEXT:  # %bb.1:
-; LA32S-NEXT:    ori $a0, $zero, 1
-; LA32S-NEXT:    ret
-; LA32S-NEXT:  .LBB0_2:
-; LA32S-NEXT:    move $a0, $zero
-; LA32S-NEXT:    ret
-;
-; LA64-LABEL: br_eq:
-; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    beqz $zero, .LBB0_2
-; LA64-NEXT:  # %bb.1:
-; LA64-NEXT:    ori $a0, $zero, 1
-; LA64-NEXT:    ret
-; LA64-NEXT:  .LBB0_2:
-; LA64-NEXT:    move $a0, $zero
-; LA64-NEXT:    ret
+; CHECK-LABEL: br_eq:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    move $a0, $zero
+; CHECK-NEXT:    ret
 entry:
   %1 = icmp eq i32 0, 0
   br i1 %1, label %2, label %3
@@ -43,38 +18,10 @@ entry:
 }
 
 define i32 @br_ne() nounwind {
-; LA32R-LABEL: br_ne:
-; LA32R:       # %bb.0: # %entry
-; LA32R-NEXT:    ori $a0, $zero, 1
-; LA32R-NEXT:    beq $a0, $zero, .LBB1_2
-; LA32R-NEXT:  # %bb.1:
-; LA32R-NEXT:    ori $a0, $zero, 1
-; LA32R-NEXT:    ret
-; LA32R-NEXT:  .LBB1_2:
-; LA32R-NEXT:    move $a0, $zero
-; LA32R-NEXT:    ret
-;
-; LA32S-LABEL: br_ne:
-; LA32S:       # %bb.0: # %entry
-; LA32S-NEXT:    ori $a0, $zero, 1
-; LA32S-NEXT:    beqz $a0, .LBB1_2
-; LA32S-NEXT:  # %bb.1:
-; LA32S-NEXT:    ori $a0, $zero, 1
-; LA32S-NEXT:    ret
-; LA32S-NEXT:  .LBB1_2:
-; LA32S-NEXT:    move $a0, $zero
-; LA32S-NEXT:    ret
-;
-; LA64-LABEL: br_ne:
-; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    ori $a0, $zero, 1
-; LA64-NEXT:    beqz $a0, .LBB1_2
-; LA64-NEXT:  # %bb.1:
-; LA64-NEXT:    ori $a0, $zero, 1
-; LA64-NEXT:    ret
-; LA64-NEXT:  .LBB1_2:
-; LA64-NEXT:    move $a0, $zero
-; LA64-NEXT:    ret
+; CHECK-LABEL: br_ne:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    ori $a0, $zero, 1
+; CHECK-NEXT:    ret
 entry:
   %1 = icmp ne i32 0, 1
   br i1 %1, label %3, label %2
@@ -85,35 +32,10 @@ entry:
 }
 
 define i32 @br_lt() nounwind {
-; LA32R-LABEL: br_lt:
-; LA32R:       # %bb.0: # %entry
-; LA32R-NEXT:    beq $zero, $zero, .LBB2_2
-; LA32R-NEXT:  # %bb.1:
-; LA32R-NEXT:    ori $a0, $zero, 1
-; LA32R-NEXT:    ret
-; LA32R-NEXT:  .LBB2_2:
-; LA32R-NEXT:    move $a0, $zero
-; LA32R-NEXT:    ret
-;
-; LA32S-LABEL: br_lt:
-; LA32S:       # %bb.0: # %entry
-; LA32S-NEXT:    beqz $zero, .LBB2_2
-; LA32S-NEXT:  # %bb.1:
-; LA32S-NEXT:    ori $a0, $zero, 1
-; LA32S-NEXT:    ret
-; LA32S-NEXT:  .LBB2_2:
-; LA32S-NEXT:    move $a0, $zero
-; LA32S-NEXT:    ret
-;
-; LA64-LABEL: br_lt:
-; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    beqz $zero, .LBB2_2
-; LA64-NEXT:  # %bb.1:
-; LA64-NEXT:    ori $a0, $zero, 1
-; LA64-NEXT:    ret
-; LA64-NEXT:  .LBB2_2:
-; LA64-NEXT:    move $a0, $zero
-; LA64-NEXT:    ret
+; CHECK-LABEL: br_lt:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    move $a0, $zero
+; CHECK-NEXT:    ret
 entry:
   %1 = icmp slt i32 0, 1
   br i1 %1, label %2, label %3
@@ -124,35 +46,10 @@ entry:
 }
 
 define i32 @br_le() nounwind {
-; LA32R-LABEL: br_le:
-; LA32R:       # %bb.0: # %entry
-; LA32R-NEXT:    bne $zero, $zero, .LBB3_2
-; LA32R-NEXT:  # %bb.1:
-; LA32R-NEXT:    move $a0, $zero
-; LA32R-NEXT:    ret
-; LA32R-NEXT:  .LBB3_2:
-; LA32R-NEXT:    ori $a0, $zero, 1
-; LA32R-NEXT:    ret
-;
-; LA32S-LABEL: br_le:
-; LA32S:       # %bb.0: # %entry
-; LA32S-NEXT:    bnez $zero, .LBB3_2
-; LA32S-NEXT:  # %bb.1:
-; LA32S-NEXT:    move $a0, $zero
-; LA32S-NEXT:    ret
-; LA32S-NEXT:  .LBB3_2:
-; LA32S-NEXT:    ori $a0, $zero, 1
-; LA32S-NEXT:    ret
-;
-; LA64-LABEL: br_le:
-; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    bnez $zero, .LBB3_2
-; LA64-NEXT:  # %bb.1:
-; LA64-NEXT:    move $a0, $zero
-; LA64-NEXT:    ret
-; LA64-NEXT:  .LBB3_2:
-; LA64-NEXT:    ori $a0, $zero, 1
-; LA64-NEXT:    ret
+; CHECK-LABEL: br_le:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    move $a0, $zero
+; CHECK-NEXT:    ret
 entry:
   %1 = icmp sle i32 0, 1
   br i1 %1, label %2, label %3
@@ -163,38 +60,10 @@ entry:
 }
 
 define i32 @br_gt() nounwind {
-; LA32R-LABEL: br_gt:
-; LA32R:       # %bb.0: # %entry
-; LA32R-NEXT:    ori $a0, $zero, 1
-; LA32R-NEXT:    beq $a0, $zero, .LBB4_2
-; LA32R-NEXT:  # %bb.1:
-; LA32R-NEXT:    ori $a0, $zero, 1
-; LA32R-NEXT:    ret
-; LA32R-NEXT:  .LBB4_2:
-; LA32R-NEXT:    move $a0, $zero
-; LA32R-NEXT:    ret
-;
-; LA32S-LABEL: br_gt:
-; LA32S:       # %bb.0: # %entry
-; LA32S-NEXT:    ori $a0, $zero, 1
-; LA32S-NEXT:    beqz $a0, .LBB4_2
-; LA32S-NEXT:  # %bb.1:
-; LA32S-NEXT:    ori $a0, $zero, 1
-; LA32S-NEXT:    ret
-; LA32S-NEXT:  .LBB4_2:
-; LA32S-NEXT:    move $a0, $zero
-; LA32S-NEXT:    ret
-;
-; LA64-LABEL: br_gt:
-; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    ori $a0, $zero, 1
-; LA64-NEXT:    beqz $a0, .LBB4_2
-; LA64-NEXT:  # %bb.1:
-; LA64-NEXT:    ori $a0, $zero, 1
-; LA64-NEXT:    ret
-; LA64-NEXT:  .LBB4_2:
-; LA64-NEXT:    move $a0, $zero
-; LA64-NEXT:    ret
+; CHECK-LABEL: br_gt:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    ori $a0, $zero, 1
+; CHECK-NEXT:    ret
 entry:
   %1 = icmp sgt i32 1, 0
   br i1 %1, label %3, label %2
@@ -205,38 +74,10 @@ entry:
 }
 
 define i32 @br_ge() nounwind {
-; LA32R-LABEL: br_ge:
-; LA32R:       # %bb.0: # %entry
-; LA32R-NEXT:    ori $a0, $zero, 1
-; LA32R-NEXT:    beq $a0, $zero, .LBB5_2
-; LA32R-NEXT:  # %bb.1:
-; LA32R-NEXT:    ori $a0, $zero, 1
-; LA32R-NEXT:    ret
-; LA32R-NEXT:  .LBB5_2:
-; LA32R-NEXT:    move $a0, $zero
-; LA32R-NEXT:    ret
-;
-; LA32S-LABEL: br_ge:
-; LA32S:       # %bb.0: # %entry
-; LA32S-NEXT:    ori $a0, $zero, 1
-; LA32S-NEXT:    beqz $a0, .LBB5_2
-; LA32S-NEXT:  # %bb.1:
-; LA32S-NEXT:    ori $a0, $zero, 1
-; LA32S-NEXT:    ret
-; LA32S-NEXT:  .LBB5_2:
-; LA32S-NEXT:    move $a0, $zero
-; LA32S-NEXT:    ret
-;
-; LA64-LABEL: br_ge:
-; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    ori $a0, $zero, 1
-; LA64-NEXT:    beqz $a0, .LBB5_2
-; LA64-NEXT:  # %bb.1:
-; LA64-NEXT:    ori $a0, $zero, 1
-; LA64-NEXT:    ret
-; LA64-NEXT:  .LBB5_2:
-; LA64-NEXT:    move $a0, $zero
-; LA64-NEXT:    ret
+; CHECK-LABEL: br_ge:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    ori $a0, $zero, 1
+; CHECK-NEXT:    ret
 entry:
   %1 = icmp sge i32 1, 0
   br i1 %1, label %3, label %2
@@ -247,35 +88,10 @@ entry:
 }
 
 define i32 @br_ltu() nounwind {
-; LA32R-LABEL: br_ltu:
-; LA32R:       # %bb.0: # %entry
-; LA32R-NEXT:    bne $zero, $zero, .LBB6_2
-; LA32R-NEXT:  # %bb.1:
-; LA32R-NEXT:    move $a0, $zero
-; LA32R-NEXT:    ret
-; LA32R-NEXT:  .LBB6_2:
-; LA32R-NEXT:    ori $a0, $zero, 1
-; LA32R-NEXT:    ret
-;
-; LA32S-LABEL: br_ltu:
-; LA32S:       # %bb.0: # %entry
-; LA32S-NEXT:    bnez $zero, .LBB6_2
-; LA32S-NEXT:  # %bb.1:
-; LA32S-NEXT:    move $a0, $zero
-; LA32S-NEXT:    ret
-; LA32S-NEXT:  .LBB6_2:
-; LA32S-NEXT:    ori $a0, $zero, 1
-; LA32S-NEXT:    ret
-;
-; LA64-LABEL: br_ltu:
-; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    bnez $zero, .LBB6_2
-; LA64-NEXT:  # %bb.1:
-; LA64-NEXT:    move $a0, $zero
-; LA64-NEXT:    ret
-; LA64-NEXT:  .LBB6_2:
-; LA64-NEXT:    ori $a0, $zero, 1
-; LA64-NEXT:    ret
+; CHECK-LABEL: br_ltu:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    move $a0, $zero
+; CHECK-NEXT:    ret
 entry:
   %1 = icmp ult i32 0, 1
   br i1 %1, label %2, label %3
@@ -286,35 +102,10 @@ entry:
 }
 
 define i32 @br_leu() nounwind {
-; LA32R-LABEL: br_leu:
-; LA32R:       # %bb.0: # %entry
-; LA32R-NEXT:    bne $zero, $zero, .LBB7_2
-; LA32R-NEXT:  # %bb.1:
-; LA32R-NEXT:    move $a0, $zero
-; LA32R-NEXT:    ret
-; LA32R-NEXT:  .LBB7_2:
-; LA32R-NEXT:    ori $a0, $zero, 1
-; LA32R-NEXT:    ret
-;
-; LA32S-LABEL: br_leu:
-; LA32S:       # %bb.0: # %entry
-; LA32S-NEXT:    bnez $zero, .LBB7_2
-; LA32S-NEXT:  # %bb.1:
-; LA32S-NEXT:    move $a0, $zero
-; LA32S-NEXT:    ret
-; LA32S-NEXT:  .LBB7_2:
-; LA32S-NEXT:    ori $a0, $zero, 1
-; LA32S-NEXT:    ret
-;
-; LA64-LABEL: br_leu:
-; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    bnez $zero, .LBB7_2
-; LA64-NEXT:  # %bb.1:
-; LA64-NEXT:    move $a0, $zero
-; LA64-NEXT:    ret
-; LA64-NEXT:  .LBB7_2:
-; LA64-NEXT:    ori $a0, $zero, 1
-; LA64-NEXT:    ret
+; CHECK-LABEL: br_leu:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    move $a0, $zero
+; CHECK-NEXT:    ret
 entry:
   %1 = icmp ule i32 0, 1
   br i1 %1, label %2, label %3
@@ -325,38 +116,10 @@ entry:
 }
 
 define i32 @br_gtu() nounwind {
-; LA32R-LABEL: br_gtu:
-; LA32R:       # %bb.0: # %entry
-; LA32R-NEXT:    ori $a0, $zero, 1
-; LA32R-NEXT:    beq $a0, $zero, .LBB8_2
-; LA32R-NEXT:  # %bb.1:
-; LA32R-NEXT:    ori $a0, $zero, 1
-; LA32R-NEXT:    ret
-; LA32R-NEXT:  .LBB8_2:
-; LA32R-NEXT:    move $a0, $zero
-; LA32R-NEXT:    ret
-;
-; LA32S-LABEL: br_gtu:
-; LA32S:       # %bb.0: # %entry
-; LA32S-NEXT:    ori $a0, $zero, 1
-; LA32S-NEXT:    beqz $a0, .LBB8_2
-; LA32S-NEXT:  # %bb.1:
-; LA32S-NEXT:    ori $a0, $zero, 1
-; LA32S-NEXT:    ret
-; LA32S-NEXT:  .LBB8_2:
-; LA32S-NEXT:    move $a0, $zero
-; LA32S-NEXT:    ret
-;
-; LA64-LABEL: br_gtu:
-; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    ori $a0, $zero, 1
-; LA64-NEXT:    beqz $a0, .LBB8_2
-; LA64-NEXT:  # %bb.1:
-; LA64-NEXT:    ori $a0, $zero, 1
-; LA64-NEXT:    ret
-; LA64-NEXT:  .LBB8_2:
-; LA64-NEXT:    move $a0, $zero
-; LA64-NEXT:    ret
+; CHECK-LABEL: br_gtu:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    ori $a0, $zero, 1
+; CHECK-NEXT:    ret
 entry:
   %1 = icmp ugt i32 1, 0
   br i1 %1, label %3, label %2
@@ -366,38 +129,10 @@ entry:
   ret i32 1
 }
 define i32 @br_geu() nounwind {
-; LA32R-LABEL: br_geu:
-; LA32R:       # %bb.0: # %entry
-; LA32R-NEXT:    ori $a0, $zero, 1
-; LA32R-NEXT:    beq $a0, $zero, .LBB9_2
-; LA32R-NEXT:  # %bb.1:
-; LA32R-NEXT:    ori $a0, $zero, 1
-; LA32R-NEXT:    ret
-; LA32R-NEXT:  .LBB9_2:
-; LA32R-NEXT:    move $a0, $zero
-; LA32R-NEXT:    ret
-;
-; LA32S-LABEL: br_geu:
-; LA32S:       # %bb.0: # %entry
-; LA32S-NEXT:    ori $a0, $zero, 1
-; LA32S-NEXT:    beqz $a0, .LBB9_2
-; LA32S-NEXT:  # %bb.1:
-; LA32S-NEXT:    ori $a0, $zero, 1
-; LA32S-NEXT:    ret
-; LA32S-NEXT:  .LBB9_2:
-; LA32S-NEXT:    move $a0, $zero
-; LA32S-NEXT:    ret
-;
-; LA64-LABEL: br_geu:
-; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    ori $a0, $zero, 1
-; LA64-NEXT:    beqz $a0, .LBB9_2
-; LA64-NEXT:  # %bb.1:
-; LA64-NEXT:    ori $a0, $zero, 1
-; LA64-NEXT:    ret
-; LA64-NEXT:  .LBB9_2:
-; LA64-NEXT:    move $a0, $zero
-; LA64-NEXT:    ret
+; CHECK-LABEL: br_geu:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    ori $a0, $zero, 1
+; CHECK-NEXT:    ret
 entry:
   %1 = icmp uge i32 1, 0
   br i1 %1, label %3, label %2
diff --git a/llvm/test/CodeGen/LoongArch/jr-without-ra.ll b/llvm/test/CodeGen/LoongArch/jr-without-ra.ll
index 96c9e7523f642..814e2f2c70287 100644
--- a/llvm/test/CodeGen/LoongArch/jr-without-ra.ll
+++ b/llvm/test/CodeGen/LoongArch/jr-without-ra.ll
@@ -38,23 +38,31 @@ define void @jr_without_ra(ptr %rtwdev, ptr %chan, ptr %h2c, i8 %.pre, i1 %cmp.i
 ; CHECK-NEXT:    alsl.d $a6, $a6, $s2, 4
 ; CHECK-NEXT:    pcalau12i $s2, %pc_hi20(.LJTI0_0)
 ; CHECK-NEXT:    addi.d $s2, $s2, %pc_lo12(.LJTI0_0)
-; CHECK-NEXT:    ori $s3, $zero, 1
-; CHECK-NEXT:    ori $s4, $zero, 50
+; CHECK-NEXT:    ori $s3, $zero, 50
+; CHECK-NEXT:    ori $s4, $zero, 1
 ; CHECK-NEXT:    ori $s5, $zero, 3
 ; CHECK-NEXT:    lu32i.d $s5, 262144
-; CHECK-NEXT:    b .LBB0_4
+; CHECK-NEXT:    b .LBB0_3
 ; CHECK-NEXT:    .p2align 4, , 16
-; CHECK-NEXT:  .LBB0_1: # %sw.bb27.i.i
-; CHECK-NEXT:    # in Loop: Header=BB0_4 Depth=1
+; CHECK-NEXT:  .LBB0_1: # %if.else58.i
+; CHECK-NEXT:    # in Loop: Header=BB0_3 Depth=1
+; CHECK-NEXT:    ldx.bu $s6, $a6, $s6
+; CHECK-NEXT:  .LBB0_2: # %phy_tssi_get_ofdm_trim_de.exit
+; CHECK-NEXT:    # in Loop: Header=BB0_3 Depth=1
+; CHECK-NEXT:    st.b $zero, $t8, 0
+; CHECK-NEXT:    slli.d $s8, $t1, 2
+; CHECK-NEXT:    alsl.d $s8, $t1, $s8, 1
+; CHECK-NEXT:    add.d $s8, $t6, $s8
+; CHECK-NEXT:    ldx.b $s8, $s8, $t5
+; CHECK-NEXT:    st.b $zero, $a2, 0
+; CHECK-NEXT:    st.b $zero, $a7, 0
+; CHECK-NEXT:    st.b $zero, $t7, 0
+; CHECK-NEXT:    st.b $s8, $a0, 0
 ; CHECK-NEXT:    ori $s7, $zero, 1
-; CHECK-NEXT:  .LBB0_2: # %if.else.i106
-; CHECK-NEXT:    # in Loop: Header=BB0_4 Depth=1
 ; CHECK-NEXT:    alsl.d $s8, $s1, $s1, 3
 ; CHECK-NEXT:    alsl.d $s1, $s8, $s1, 1
 ; CHECK-NEXT:    add.d $s1, $t0, $s1
 ; CHECK-NEXT:    ldx.bu $s7, $s1, $s7
-; CHECK-NEXT:  .LBB0_3: # %phy_tssi_get_ofdm_de.exit
-; CHECK-NEXT:    # in Loop: Header=BB0_4 Depth=1
 ; CHECK-NEXT:    st.b $zero, $t6, 0
 ; CHECK-NEXT:    st.b $s6, $t4, 0
 ; CHECK-NEXT:    st.b $zero, $fp, 0
@@ -64,65 +72,31 @@ define void @jr_without_ra(ptr %rtwdev, ptr %chan, ptr %h2c, i8 %.pre, i1 %cmp.i
 ; CHECK-NEXT:    st.b $s7, $a5, 0
 ; CHECK-NEXT:    ori $s1, $zero, 1
 ; CHECK-NEXT:    move $s6, $a3
-; CHECK-NEXT:  .LBB0_4: # %for.body
+; CHECK-NEXT:  .LBB0_3: # %for.body
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    beqz $a4, .LBB0_9
-; CHECK-NEXT:  # %bb.5: # %calc_6g.i
-; CHECK-NEXT:    # in Loop: Header=BB0_4 Depth=1
+; CHECK-NEXT:    beqz $a4, .LBB0_6
+; CHECK-NEXT:  # %bb.4: # %calc_6g.i
+; CHECK-NEXT:    # in Loop: Header=BB0_3 Depth=1
 ; CHECK-NEXT:    move $s6, $zero
-; CHECK-NEXT:    bnez $zero, .LBB0_8
-; CHECK-NEXT:  # %bb.6: # %calc_6g.i
-; CHECK-NEXT:    # in Loop: Header=BB0_4 Depth=1
 ; CHECK-NEXT:    slli.d $s7, $zero, 3
 ; CHECK-NEXT:    ldx.d $s7, $s2, $s7
 ; CHECK-NEXT:    jr $s7
-; CHECK-NEXT:  .LBB0_7: # %sw.bb12.i.i
-; CHECK-NEXT:    # in Loop: Header=BB0_4 Depth=1
+; CHECK-NEXT:  .LBB0_5: # %sw.bb12.i.i
+; CHECK-NEXT:    # in Loop: Header=BB0_3 Depth=1
 ; CHECK-NEXT:    ori $s6, $zero, 1
-; CHECK-NEXT:  .LBB0_8: # %if.else58.i
-; CHECK-NEXT:    # in Loop: Header=BB0_4 Depth=1
-; CHECK-NEXT:    ldx.bu $s6, $a6, $s6
-; CHECK-NEXT:    b .LBB0_11
+; CHECK-NEXT:    b .LBB0_1
 ; CHECK-NEXT:    .p2align 4, , 16
-; CHECK-NEXT:  .LBB0_9: # %if.end.i
-; CHECK-NEXT:    # in Loop: Header=BB0_4 Depth=1
+; CHECK-NEXT:  .LBB0_6: # %if.end.i
+; CHECK-NEXT:    # in Loop: Header=BB0_3 Depth=1
 ; CHECK-NEXT:    andi $s6, $s6, 255
-; CHECK-NEXT:    bltu $s4, $s6, .LBB0_15
-; CHECK-NEXT:  # %bb.10: # %if.end.i
-; CHECK-NEXT:    # in Loop: Header=BB0_4 Depth=1
-; CHECK-NEXT:    sll.d $s6, $s3, $s6
+; CHECK-NEXT:    bltu $s3, $s6, .LBB0_8
+; CHECK-NEXT:  # %bb.7: # %if.end.i
+; CHECK-NEXT:    # in Loop: Header=BB0_3 Depth=1
+; CHECK-NEXT:    sll.d $s6, $s4, $s6
 ; CHECK-NEXT:    and $s7, $s6, $s5
 ; CHECK-NEXT:    move $s6, $s0
-; CHECK-NEXT:    beqz $s7, .LBB0_15
-; CHECK-NEXT:  .LBB0_11: # %phy_tssi_get_ofdm_trim_de.exit
-; CHECK-NEXT:    # in Loop: Header=BB0_4 Depth=1
-; CHECK-NEXT:    move $s7, $zero
-; CHECK-NEXT:    st.b $zero, $t8, 0
-; CHECK-NEXT:    slli.d $s8, $t1, 2
-; CHECK-NEXT:    alsl.d $s8, $t1, $s8, 1
-; CHECK-NEXT:    add.d $s8, $t6, $s8
-; CHECK-NEXT:    ldx.b $s8, $s8, $t5
-; CHECK-NEXT:    st.b $zero, $a2, 0
-; CHECK-NEXT:    st.b $zero, $a7, 0
-; CHECK-NEXT:    st.b $zero, $t7, 0
-; CHECK-NEXT:    st.b $s8, $a0, 0
-; CHECK-NEXT:    bnez $s3, .LBB0_13
-; CHECK-NEXT:  # %bb.12: # %phy_tssi_get_ofdm_trim_de.exit
-; CHECK-NEXT:    # in Loop: Header=BB0_4 Depth=1
-; CHECK-NEXT:    addi.w $s8, $zero, -41
-; CHECK-NEXT:    slli.d $s8, $s8, 3
-; CHECK-NEXT:    pcalau12i $ra, %pc_hi20(.LJTI0_1)
-; CHECK-NEXT:    addi.d $ra, $ra, %pc_lo12(.LJTI0_1)
-; CHECK-NEXT:    ldx.d $s8, $ra, $s8
-; CHECK-NEXT:    jr $s8
-; CHECK-NEXT:  .LBB0_13: # %phy_tssi_get_ofdm_trim_de.exit
-; CHECK-NEXT:    # in Loop: Header=BB0_4 Depth=1
-; CHECK-NEXT:    bnez $s3, .LBB0_1
-; CHECK-NEXT:  # %bb.14: # %phy_tssi_get_ofdm_trim_de.exit
-; CHECK-NEXT:    # in Loop: Header=BB0_4 Depth=1
-; CHECK-NEXT:    bnez $zero, .LBB0_3
-; CHECK-NEXT:    b .LBB0_2
-; CHECK-NEXT:  .LBB0_15: # %sw.bb9.i.i
+; CHECK-NEXT:    bnez $s7, .LBB0_2
+; CHECK-NEXT:  .LBB0_8: # %sw.bb9.i.i
 ; CHECK-NEXT:    ld.d $s8, $sp, 8 # 8-byte Folded Reload
 ; CHECK-NEXT:    ld.d $s7, $sp, 16 # 8-byte Folded Reload
 ; CHECK-NEXT:    ld.d $s6, $sp, 24 # 8-byte Folded Reload
diff --git a/llvm/test/CodeGen/LoongArch/opt-pipeline.ll b/llvm/test/CodeGen/LoongArch/opt-pipeline.ll
index 4a77cccb99a2e..3bbd6676181d0 100644
--- a/llvm/test/CodeGen/LoongArch/opt-pipeline.ll
+++ b/llvm/test/CodeGen/LoongArch/opt-pipeline.ll
@@ -152,7 +152,10 @@
 ; LAXX-NEXT:       Machine Optimization Remark Emitter
 ; LAXX-NEXT:       Shrink Wrapping analysis
 ; LAXX-NEXT:       Prologue/Epilogue Insertion & Frame Finalization
+; LAXX-NEXT:       LoongArch Late Branch Optimisation Pass
 ; LAXX-NEXT:       Machine Late Instructions Cleanup Pass
+; LAXX-NEXT:       Machine Cycle Info Analysis
+; LAXX-NEXT:       Machine Block Frequency Analysis
 ; LAXX-NEXT:       Control Flow Optimizer
 ; LAXX-NEXT:       Lazy Machine Block Frequency Analysis
 ; LAXX-NEXT:       Tail Duplication
@@ -160,6 +163,7 @@
 ; LAXX-NEXT:       Post-RA pseudo instruction expansion pass
 ; LAXX-NEXT:       MachineDominator Tree Construction
 ; LAXX-NEXT:       Machine Natural Loop Construction
+; LAXX-NEXT:       Machine Register Class Info Analysis
 ; LAXX-NEXT:       Post RA top-down list latency scheduler
 ; LAXX-NEXT:       Analyze Machine Code For Garbage Collection
 ; LAXX-NEXT:       Machine Cycle Info Analysis
diff --git a/llvm/test/CodeGen/LoongArch/pr215935.ll b/llvm/test/CodeGen/LoongArch/pr215935.ll
index 661f7f9f60f88..9c00ff18ef4cf 100644
--- a/llvm/test/CodeGen/LoongArch/pr215935.ll
+++ b/llvm/test/CodeGen/LoongArch/pr215935.ll
@@ -4,11 +4,6 @@
 define i64 @brcond_const_1(i64 %0) nounwind {
 ; CHECK-LABEL: brcond_const_1:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    beqz $zero, .LBB0_2
-; CHECK-NEXT:  # %bb.1:
-; CHECK-NEXT:    move $a0, $zero
-; CHECK-NEXT:    ret
-; CHECK-NEXT:  .LBB0_2:
 ; CHECK-NEXT:    ori $a0, $zero, 1
 ; CHECK-NEXT:    ret
 entry:
@@ -28,13 +23,8 @@ entry:
 define i64 @brcond_const_0(i64 %0) nounwind {
 ; CHECK-LABEL: brcond_const_0:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    bnez $zero, .LBB1_2
-; CHECK-NEXT:  # %bb.1:
 ; CHECK-NEXT:    move $a0, $zero
 ; CHECK-NEXT:    ret
-; CHECK-NEXT:  .LBB1_2:
-; CHECK-NEXT:    ori $a0, $zero, 1
-; CHECK-NEXT:    ret
 entry:
   %2 = trunc i64 %0 to i32
   %3 = trunc i64 %0 to i8
diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected
index c2f5f345624bc..acf0803a1c525 100644
--- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected
@@ -75,16 +75,6 @@ attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
 ; CHECK-NEXT:    st.w $zero, $fp, -12
 ; CHECK-NEXT:    st.w $zero, $fp, -16
 ; CHECK-NEXT:    ori $a0, $zero, 1
-; CHECK-NEXT:    beq $zero, $zero, .LBB0_3
-; CHECK-NEXT:  # %bb.1:
-; CHECK-NEXT:    st.w $a0, $fp, -24
-; CHECK-NEXT:    ld.w $a0, $fp, -16
-; CHECK-NEXT:    beq $a0, $zero, .LBB0_4
-; CHECK-NEXT:  .LBB0_2:
-; CHECK-NEXT:    ori $a0, $zero, 1
-; CHECK-NEXT:    st.w $a0, $fp, -24
-; CHECK-NEXT:    b .LBB0_5
-; CHECK-NEXT:  .LBB0_3:
 ; CHECK-NEXT:    st.w $a0, $fp, -16
 ; CHECK-NEXT:    ori $a0, $zero, 2
 ; CHECK-NEXT:    st.w $a0, $fp, -20
@@ -93,8 +83,12 @@ attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
 ; CHECK-NEXT:    ori $a0, $zero, 4
 ; CHECK-NEXT:    st.w $a0, $fp, -28
 ; CHECK-NEXT:    ld.w $a0, $fp, -16
-; CHECK-NEXT:    bne $a0, $zero, .LBB0_2
-; CHECK-NEXT:  .LBB0_4:
+; CHECK-NEXT:    beq $a0, $zero, .LBB0_2
+; CHECK-NEXT:  # %bb.1:
+; CHECK-NEXT:    ori $a0, $zero, 1
+; CHECK-NEXT:    st.w $a0, $fp, -24
+; CHECK-NEXT:    b .LBB0_3
+; CHECK-NEXT:  .LBB0_2:
 ; CHECK-NEXT:    ori $a0, $zero, 1
 ; CHECK-NEXT:    st.w $a0, $fp, -16
 ; CHECK-NEXT:    ori $a0, $zero, 2
@@ -103,7 +97,7 @@ attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
 ; CHECK-NEXT:    st.w $a0, $fp, -24
 ; CHECK-NEXT:    ori $a0, $zero, 4
 ; CHECK-NEXT:    st.w $a0, $fp, -28
-; CHECK-NEXT:  .LBB0_5:
+; CHECK-NEXT:  .LBB0_3:
 ; CHECK-NEXT:    move $a0, $zero
 ; CHECK-NEXT:    ld.w $fp, $sp, 24 # 4-byte Folded Reload
 ; CHECK-NEXT:    ld.w $ra, $sp, 28 # 4-byte Folded Reload
diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected
index 1ab256f6fa268..e0d1623f5720a 100644
--- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected
@@ -16,16 +16,6 @@ define dso_local i32 @check_boundaries() #0 {
 ; CHECK-NEXT:    st.w $zero, $fp, -12
 ; CHECK-NEXT:    st.w $zero, $fp, -16
 ; CHECK-NEXT:    ori $a0, $zero, 1
-; CHECK-NEXT:    beq $zero, $zero, .LBB0_3
-; CHECK-NEXT:  # %bb.1:
-; CHECK-NEXT:    st.w $a0, $fp, -24
-; CHECK-NEXT:    ld.w $a0, $fp, -16
-; CHECK-NEXT:    beq $a0, $zero, .LBB0_4
-; CHECK-NEXT:  .LBB0_2:
-; CHECK-NEXT:    ori $a0, $zero, 1
-; CHECK-NEXT:    st.w $a0, $fp, -24
-; CHECK-NEXT:    b .LBB0_5
-; CHECK-NEXT:  .LBB0_3:
 ; CHECK-NEXT:    st.w $a0, $fp, -16
 ; CHECK-NEXT:    ori $a0, $zero, 2
 ; CHECK-NEXT:    st.w $a0, $fp, -20
@@ -34,8 +24,12 @@ define dso_local i32 @check_boundaries() #0 {
 ; CHECK-NEXT:    ori $a0, $zero, 4
 ; CHECK-NEXT:    st.w $a0, $fp, -28
 ; CHECK-NEXT:    ld.w $a0, $fp, -16
-; CHECK-NEXT:    bne $a0, $zero, .LBB0_2
-; CHECK-NEXT:  .LBB0_4:
+; CHECK-NEXT:    beq $a0, $zero, .LBB0_2
+; CHECK-NEXT:  # %bb.1:
+; CHECK-NEXT:    ori $a0, $zero, 1
+; CHECK-NEXT:    st.w $a0, $fp, -24
+; CHECK-NEXT:    b .LBB0_3
+; CHECK-NEXT:  .LBB0_2:
 ; CHECK-NEXT:    ori $a0, $zero, 1
 ; CHECK-NEXT:    st.w $a0, $fp, -16
 ; CHECK-NEXT:    ori $a0, $zero, 2
@@ -44,7 +38,7 @@ define dso_local i32 @check_boundaries() #0 {
 ; CHECK-NEXT:    st.w $a0, $fp, -24
 ; CHECK-NEXT:    ori $a0, $zero, 4
 ; CHECK-NEXT:    st.w $a0, $fp, -28
-; CHECK-NEXT:  .LBB0_5:
+; CHECK-NEXT:  .LBB0_3:
 ; CHECK-NEXT:    move $a0, $zero
 ; CHECK-NEXT:    ld.w $fp, $sp, 24 # 4-byte Folded Reload
 ; CHECK-NEXT:    ld.w $ra, $sp, 28 # 4-byte Folded Reload
diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/BUILD.gn
index 810811f7d147c..d68ccd8cbee73 100644
--- a/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/BUILD.gn
@@ -48,6 +48,7 @@ static_library("LLVMLoongArchCodeGen") {
     "LoongArchISelDAGToDAG.cpp",
     "LoongArchISelLowering.cpp",
     "LoongArchInstrInfo.cpp",
+    "LoongArchLateBranchOpt.cpp",
     "LoongArchMCInstLower.cpp",
     "LoongArchMergeBaseOffset.cpp",
     "LoongArchOptWInstrs.cpp",



More information about the llvm-branch-commits mailing list