[llvm] Riscv branch peephole opt (PR #90451)
Zhijin Zeng via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 29 19:46:15 PDT 2024
https://github.com/zengdage updated https://github.com/llvm/llvm-project/pull/90451
>From 6f50e0f72f5edd0b0ad6d514f2cae2bd05f5b729 Mon Sep 17 00:00:00 2001
From: Zhijin Zeng <zhijin.zeng at spacemit.com>
Date: Mon, 29 Apr 2024 15:36:01 +0800
Subject: [PATCH 1/2] [RISC-V][NFC] Add branch peephole optimization tests
---
llvm/test/CodeGen/RISCV/peephole-branch.mir | 467 ++++++++++++++++++++
1 file changed, 467 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/peephole-branch.mir
diff --git a/llvm/test/CodeGen/RISCV/peephole-branch.mir b/llvm/test/CodeGen/RISCV/peephole-branch.mir
new file mode 100644
index 00000000000000..8f22b42dacef31
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/peephole-branch.mir
@@ -0,0 +1,467 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
+# RUN: llc -o - %s -mtriple=riscv32 -run-pass=machine-cp | FileCheck %s
+
+--- |
+ define void @peephole_bne(ptr %a, ptr %b, ptr %c) {
+ entry:
+ %e = load i32, ptr %a, align 4
+ %p = icmp ne i32 %e, %e
+ br i1 %p, label %block1, label %block2
+
+ block1: ; preds = %entry
+ store i32 %e, ptr %b, align 4
+ br label %end_block
+
+ block2: ; preds = %entry
+ store i32 87, ptr %c, align 4
+ br label %end_block
+
+ end_block: ; preds = %block2, %block1
+ ret void
+ }
+
+ define void @peephole_beq(ptr %a, ptr %b, ptr %c) {
+ entry:
+ %e = load i32, ptr %a, align 4
+ %p = icmp eq i32 %e, %e
+ br i1 %p, label %block1, label %block2
+
+ block1: ; preds = %entry
+ store i32 %e, ptr %b, align 4
+ br label %end_block
+
+ block2: ; preds = %entry
+ store i32 87, ptr %c, align 4
+ br label %end_block
+
+ end_block: ; preds = %block2, %block1
+ ret void
+ }
+
+ define void @peephole_blt(ptr %a, ptr %b, ptr %c) {
+ entry:
+ %e = load i32, ptr %a, align 4
+ %p = icmp slt i32 %e, %e
+ br i1 %p, label %block1, label %block2
+
+ block1: ; preds = %entry
+ store i32 %e, ptr %b, align 4
+ br label %end_block
+
+ block2: ; preds = %entry
+ store i32 87, ptr %c, align 4
+ br label %end_block
+
+ end_block: ; preds = %block2, %block1
+ ret void
+ }
+
+ define void @peephole_bltu(ptr %a, ptr %b, ptr %c) {
+ entry:
+ %e = load i32, ptr %a, align 4
+ %p = icmp ult i32 %e, %e
+ br i1 %p, label %block1, label %block2
+
+ block1: ; preds = %entry
+ store i32 %e, ptr %b, align 4
+ br label %end_block
+
+ block2: ; preds = %entry
+ store i32 87, ptr %c, align 4
+ br label %end_block
+
+ end_block: ; preds = %block2, %block1
+ ret void
+ }
+
+ define void @peephole_bge(ptr %a, ptr %b, ptr %c) {
+ entry:
+ %e = load i32, ptr %a, align 4
+ %p = icmp sge i32 %e, %e
+ br i1 %p, label %block1, label %block2
+
+ block1: ; preds = %entry
+ store i32 %e, ptr %b, align 4
+ br label %end_block
+
+ block2: ; preds = %entry
+ store i32 87, ptr %c, align 4
+ br label %end_block
+
+ end_block: ; preds = %block2, %block1
+ ret void
+ }
+
+ define void @peephole_bgeu(ptr %a, ptr %b, ptr %c) {
+ entry:
+ %e = load i32, ptr %a, align 4
+ %p = icmp uge i32 %e, %e
+ br i1 %p, label %block1, label %block2
+
+ block1: ; preds = %entry
+ store i32 %e, ptr %b, align 4
+ br label %end_block
+
+ block2: ; preds = %entry
+ store i32 87, ptr %c, align 4
+ br label %end_block
+
+ end_block: ; preds = %block2, %block1
+ ret void
+ }
+
+...
+---
+name: peephole_bne
+alignment: 4
+tracksRegLiveness: true
+liveins:
+ - { reg: '$x10' }
+ - { reg: '$x11' }
+ - { reg: '$x12' }
+body: |
+ ; CHECK-LABEL: name: peephole_bne
+ ; CHECK: bb.0.entry:
+ ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
+ ; CHECK-NEXT: liveins: $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: renamable $x13 = ADDI $x0, 1
+ ; CHECK-NEXT: BNE killed renamable $x13, $x13, %bb.2
+ ; CHECK-NEXT: PseudoBR %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1.block1:
+ ; CHECK-NEXT: successors: %bb.3(0x80000000)
+ ; CHECK-NEXT: liveins: $x10, $x11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: renamable $x10 = LW killed renamable $x10, 0
+ ; CHECK-NEXT: SW killed renamable $x10, killed renamable $x11, 0
+ ; CHECK-NEXT: PseudoBR %bb.3
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2.block2:
+ ; CHECK-NEXT: successors: %bb.3(0x80000000)
+ ; CHECK-NEXT: liveins: $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: renamable $x10 = ADDI $x0, 87
+ ; CHECK-NEXT: SW killed renamable $x10, killed renamable $x12, 0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.3.end_block:
+ ; CHECK-NEXT: PseudoRET
+ bb.0.entry:
+ successors: %bb.1, %bb.2
+ liveins: $x10, $x11, $x12
+
+ renamable $x13 = ADDI $x0, 1
+ BNE killed renamable $x13, $x13, %bb.2
+ PseudoBR %bb.1
+
+ bb.1.block1:
+ liveins: $x10, $x11
+
+ renamable $x10 = LW killed renamable $x10, 0
+ SW killed renamable $x10, killed renamable $x11, 0
+ PseudoBR %bb.3
+
+ bb.2.block2:
+ liveins: $x12
+
+ renamable $x10 = ADDI $x0, 87
+ SW killed renamable $x10, killed renamable $x12, 0
+
+ bb.3.end_block:
+ PseudoRET
+
+...
+---
+name: peephole_beq
+alignment: 4
+tracksRegLiveness: true
+liveins:
+ - { reg: '$x10' }
+ - { reg: '$x11' }
+ - { reg: '$x12' }
+body: |
+ ; CHECK-LABEL: name: peephole_beq
+ ; CHECK: bb.0.entry:
+ ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
+ ; CHECK-NEXT: liveins: $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: BEQ $x0, $x0, %bb.2
+ ; CHECK-NEXT: PseudoBR %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1.block1:
+ ; CHECK-NEXT: successors: %bb.3(0x80000000)
+ ; CHECK-NEXT: liveins: $x10, $x11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: renamable $x10 = LW killed renamable $x10, 0
+ ; CHECK-NEXT: SW killed renamable $x10, killed renamable $x11, 0
+ ; CHECK-NEXT: PseudoBR %bb.3
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2.block2:
+ ; CHECK-NEXT: successors: %bb.3(0x80000000)
+ ; CHECK-NEXT: liveins: $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: renamable $x10 = ADDI $x0, 87
+ ; CHECK-NEXT: SW killed renamable $x10, killed renamable $x12, 0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.3.end_block:
+ ; CHECK-NEXT: PseudoRET
+ bb.0.entry:
+ successors: %bb.1, %bb.2
+ liveins: $x10, $x11, $x12
+
+ BEQ $x0, $x0, %bb.2
+ PseudoBR %bb.1
+
+ bb.1.block1:
+ liveins: $x10, $x11
+
+ renamable $x10 = LW killed renamable $x10, 0
+ SW killed renamable $x10, killed renamable $x11, 0
+ PseudoBR %bb.3
+
+ bb.2.block2:
+ liveins: $x12
+
+ renamable $x10 = ADDI $x0, 87
+ SW killed renamable $x10, killed renamable $x12, 0
+
+ bb.3.end_block:
+ PseudoRET
+
+...
+---
+name: peephole_blt
+alignment: 4
+tracksRegLiveness: true
+liveins:
+ - { reg: '$x10' }
+ - { reg: '$x11' }
+ - { reg: '$x12' }
+body: |
+ ; CHECK-LABEL: name: peephole_blt
+ ; CHECK: bb.0.entry:
+ ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
+ ; CHECK-NEXT: liveins: $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: renamable $x13 = ADDI $x0, 1
+ ; CHECK-NEXT: BLT killed renamable $x13, $x13, %bb.2
+ ; CHECK-NEXT: PseudoBR %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1.block1:
+ ; CHECK-NEXT: successors: %bb.3(0x80000000)
+ ; CHECK-NEXT: liveins: $x10, $x11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: renamable $x10 = LW killed renamable $x10, 0
+ ; CHECK-NEXT: SW killed renamable $x10, killed renamable $x11, 0
+ ; CHECK-NEXT: PseudoBR %bb.3
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2.block2:
+ ; CHECK-NEXT: successors: %bb.3(0x80000000)
+ ; CHECK-NEXT: liveins: $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: renamable $x10 = ADDI $x0, 87
+ ; CHECK-NEXT: SW killed renamable $x10, killed renamable $x12, 0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.3.end_block:
+ ; CHECK-NEXT: PseudoRET
+ bb.0.entry:
+ successors: %bb.1, %bb.2
+ liveins: $x10, $x11, $x12
+
+ renamable $x13 = ADDI $x0, 1
+ BLT killed renamable $x13, $x13, %bb.2
+ PseudoBR %bb.1
+
+ bb.1.block1:
+ liveins: $x10, $x11
+
+ renamable $x10 = LW killed renamable $x10, 0
+ SW killed renamable $x10, killed renamable $x11, 0
+ PseudoBR %bb.3
+
+ bb.2.block2:
+ liveins: $x12
+
+ renamable $x10 = ADDI $x0, 87
+ SW killed renamable $x10, killed renamable $x12, 0
+
+ bb.3.end_block:
+ PseudoRET
+
+...
+---
+name: peephole_bltu
+alignment: 4
+tracksRegLiveness: true
+liveins:
+ - { reg: '$x10' }
+ - { reg: '$x11' }
+ - { reg: '$x12' }
+body: |
+ ; CHECK-LABEL: name: peephole_bltu
+ ; CHECK: bb.0.entry:
+ ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
+ ; CHECK-NEXT: liveins: $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: renamable $x13 = ADDI $x0, 1
+ ; CHECK-NEXT: BLTU killed renamable $x13, $x13, %bb.2
+ ; CHECK-NEXT: PseudoBR %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1.block1:
+ ; CHECK-NEXT: successors: %bb.3(0x80000000)
+ ; CHECK-NEXT: liveins: $x10, $x11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: renamable $x10 = LW killed renamable $x10, 0
+ ; CHECK-NEXT: SW killed renamable $x10, killed renamable $x11, 0
+ ; CHECK-NEXT: PseudoBR %bb.3
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2.block2:
+ ; CHECK-NEXT: successors: %bb.3(0x80000000)
+ ; CHECK-NEXT: liveins: $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: renamable $x10 = ADDI $x0, 87
+ ; CHECK-NEXT: SW killed renamable $x10, killed renamable $x12, 0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.3.end_block:
+ ; CHECK-NEXT: PseudoRET
+ bb.0.entry:
+ successors: %bb.1, %bb.2
+ liveins: $x10, $x11, $x12
+
+ renamable $x13 = ADDI $x0, 1
+ BLTU killed renamable $x13, $x13, %bb.2
+ PseudoBR %bb.1
+
+ bb.1.block1:
+ liveins: $x10, $x11
+
+ renamable $x10 = LW killed renamable $x10, 0
+ SW killed renamable $x10, killed renamable $x11, 0
+ PseudoBR %bb.3
+
+ bb.2.block2:
+ liveins: $x12
+
+ renamable $x10 = ADDI $x0, 87
+ SW killed renamable $x10, killed renamable $x12, 0
+
+ bb.3.end_block:
+ PseudoRET
+
+...
+---
+name: peephole_bge
+alignment: 4
+tracksRegLiveness: true
+liveins:
+ - { reg: '$x10' }
+ - { reg: '$x11' }
+ - { reg: '$x12' }
+body: |
+ ; CHECK-LABEL: name: peephole_bge
+ ; CHECK: bb.0.entry:
+ ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
+ ; CHECK-NEXT: liveins: $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: BGE $x0, $x0, %bb.2
+ ; CHECK-NEXT: PseudoBR %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1.block1:
+ ; CHECK-NEXT: successors: %bb.3(0x80000000)
+ ; CHECK-NEXT: liveins: $x10, $x11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: renamable $x10 = LW killed renamable $x10, 0
+ ; CHECK-NEXT: SW killed renamable $x10, killed renamable $x11, 0
+ ; CHECK-NEXT: PseudoBR %bb.3
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2.block2:
+ ; CHECK-NEXT: successors: %bb.3(0x80000000)
+ ; CHECK-NEXT: liveins: $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: renamable $x10 = ADDI $x0, 87
+ ; CHECK-NEXT: SW killed renamable $x10, killed renamable $x12, 0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.3.end_block:
+ ; CHECK-NEXT: PseudoRET
+ bb.0.entry:
+ successors: %bb.1, %bb.2
+ liveins: $x10, $x11, $x12
+
+ BGE $x0, $x0, %bb.2
+ PseudoBR %bb.1
+
+ bb.1.block1:
+ liveins: $x10, $x11
+
+ renamable $x10 = LW killed renamable $x10, 0
+ SW killed renamable $x10, killed renamable $x11, 0
+ PseudoBR %bb.3
+
+ bb.2.block2:
+ liveins: $x12
+
+ renamable $x10 = ADDI $x0, 87
+ SW killed renamable $x10, killed renamable $x12, 0
+
+ bb.3.end_block:
+ PseudoRET
+
+...
+---
+name: peephole_bgeu
+alignment: 4
+tracksRegLiveness: true
+liveins:
+ - { reg: '$x10' }
+ - { reg: '$x11' }
+ - { reg: '$x12' }
+body: |
+ ; CHECK-LABEL: name: peephole_bgeu
+ ; CHECK: bb.0.entry:
+ ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
+ ; CHECK-NEXT: liveins: $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: BGEU $x0, $x0, %bb.2
+ ; CHECK-NEXT: PseudoBR %bb.1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1.block1:
+ ; CHECK-NEXT: successors: %bb.3(0x80000000)
+ ; CHECK-NEXT: liveins: $x10, $x11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: renamable $x10 = LW killed renamable $x10, 0
+ ; CHECK-NEXT: SW killed renamable $x10, killed renamable $x11, 0
+ ; CHECK-NEXT: PseudoBR %bb.3
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2.block2:
+ ; CHECK-NEXT: successors: %bb.3(0x80000000)
+ ; CHECK-NEXT: liveins: $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: renamable $x10 = ADDI $x0, 87
+ ; CHECK-NEXT: SW killed renamable $x10, killed renamable $x12, 0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.3.end_block:
+ ; CHECK-NEXT: PseudoRET
+ bb.0.entry:
+ successors: %bb.1, %bb.2
+ liveins: $x10, $x11, $x12
+
+ BGEU $x0, $x0, %bb.2
+ PseudoBR %bb.1
+
+ bb.1.block1:
+ liveins: $x10, $x11
+
+ renamable $x10 = LW killed renamable $x10, 0
+ SW killed renamable $x10, killed renamable $x11, 0
+ PseudoBR %bb.3
+
+ bb.2.block2:
+ liveins: $x12
+
+ renamable $x10 = ADDI $x0, 87
+ SW killed renamable $x10, killed renamable $x12, 0
+
+ bb.3.end_block:
+ PseudoRET
+
+...
>From 6e334c2e908e7c8939180b5663e789c12b1e0a77 Mon Sep 17 00:00:00 2001
From: Zhijin Zeng <zhijin.zeng at spacemit.com>
Date: Mon, 29 Apr 2024 09:11:04 +0800
Subject: [PATCH 2/2] [RISC-V] Add RISC-V machine instruction peephole pass
After block-placement and machine-cp, the following situations
may require optimization.
```
bne a0, a0, %bb.2 -> remove it
blt a0, a0, %bb.2 -> remove it
bltu a0, a0, %bb.2 -> remove it
beq a0, a0, %bb.2 -> jal x0, %bb.2
bge a0, a0, %bb.2 -> jal x0, %bb.2
bgeu a0, a0, %bb.2 -> jal x0, %bb.2
```
---
llvm/lib/Target/RISCV/CMakeLists.txt | 1 +
llvm/lib/Target/RISCV/RISCV.h | 3 +
llvm/lib/Target/RISCV/RISCVMIPeepholeOpt.cpp | 120 +++++++++++++++++++
llvm/lib/Target/RISCV/RISCVTargetMachine.cpp | 2 +
llvm/test/CodeGen/RISCV/O3-pipeline.ll | 1 +
llvm/test/CodeGen/RISCV/peephole-branch.mir | 11 +-
6 files changed, 131 insertions(+), 7 deletions(-)
create mode 100644 llvm/lib/Target/RISCV/RISCVMIPeepholeOpt.cpp
diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt
index 8715403f3839a6..429a22a5323795 100644
--- a/llvm/lib/Target/RISCV/CMakeLists.txt
+++ b/llvm/lib/Target/RISCV/CMakeLists.txt
@@ -45,6 +45,7 @@ add_llvm_target(RISCVCodeGen
RISCVISelLowering.cpp
RISCVMachineFunctionInfo.cpp
RISCVMergeBaseOffset.cpp
+ RISCVMIPeepholeOpt.cpp
RISCVOptWInstrs.cpp
RISCVPostRAExpandPseudoInsts.cpp
RISCVRedundantCopyElimination.cpp
diff --git a/llvm/lib/Target/RISCV/RISCV.h b/llvm/lib/Target/RISCV/RISCV.h
index d405395dcf9ec4..d808eca6169662 100644
--- a/llvm/lib/Target/RISCV/RISCV.h
+++ b/llvm/lib/Target/RISCV/RISCV.h
@@ -78,6 +78,9 @@ void initializeRISCVRedundantCopyEliminationPass(PassRegistry &);
FunctionPass *createRISCVMoveMergePass();
void initializeRISCVMoveMergePass(PassRegistry &);
+FunctionPass *createRISCVMIPeepholeOptPass();
+void initializeRISCVMIPeepholeOptPass(PassRegistry &);
+
FunctionPass *createRISCVPushPopOptimizationPass();
void initializeRISCVPushPopOptPass(PassRegistry &);
diff --git a/llvm/lib/Target/RISCV/RISCVMIPeepholeOpt.cpp b/llvm/lib/Target/RISCV/RISCVMIPeepholeOpt.cpp
new file mode 100644
index 00000000000000..1e37a24ba9aebe
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVMIPeepholeOpt.cpp
@@ -0,0 +1,120 @@
+//===- RISCVMIPeepholeOpt.cpp - RISC-V MI peephole optimization pass ---===//
+//
+// 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 pass performs below peephole optimizations on MIR level.
+//
+// 1. Remove redundant branch instrunctions which may be generated by
+// block-placement.
+//
+// bne a1, a1, %bb.1
+// blt a1, a1, %bb.1
+// bltu a1, a1, %bb.1
+//
+// These instruction is bound to fallthrough to next basic block, rather
+// than into the %bb.1, so it should be removed here.
+//
+// 2. beq a1, a1, %bb.1 -> j %bb.1
+// bge a1, a1, %bb.1 -> j %bb.1
+// bgeu a1, a1, %bb.1 -> j %bb.1
+//
+// These instruction is bound to go into %bb.1, so it should be replaced by
+// j pseudo instruction.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RISCVInstrInfo.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/CodeGen/LiveIntervals.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Support/Debug.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "riscv-mi-peephole-opt"
+
+namespace {
+
+struct RISCVMIPeepholeOpt : public MachineFunctionPass {
+ static char ID;
+
+ RISCVMIPeepholeOpt() : MachineFunctionPass(ID) {
+ initializeRISCVMIPeepholeOptPass(*PassRegistry::getPassRegistry());
+ }
+
+ const TargetInstrInfo *TII;
+
+ bool visitBranch(MachineInstr &MI);
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+ StringRef getPassName() const override {
+ return "RISC-V MI Peephole Optimization pass";
+ }
+};
+
+char RISCVMIPeepholeOpt::ID = 0;
+
+} // end anonymous namespace
+
+INITIALIZE_PASS(RISCVMIPeepholeOpt, "riscv-mi-peephole-opt",
+ "RISC-V MI Peephole Optimization", false, false)
+
+bool RISCVMIPeepholeOpt::visitBranch(MachineInstr &MI) {
+ Register FirstReg = MI.getOperand(0).getReg();
+ Register SecondReg = MI.getOperand(1).getReg();
+
+ if (FirstReg != SecondReg)
+ return false;
+
+ switch (MI.getOpcode()) {
+ default:
+ break;
+ case RISCV::BEQ:
+ case RISCV::BGE:
+ case RISCV::BGEU:
+ BuildMI(*MI.getParent(), &MI, MI.getDebugLoc(), TII->get(RISCV::PseudoBR))
+ .add(MI.getOperand(2));
+ break;
+ }
+ MI.eraseFromParent();
+
+ return true;
+}
+
+bool RISCVMIPeepholeOpt::runOnMachineFunction(MachineFunction &MF) {
+ if (skipFunction(MF.getFunction()))
+ return false;
+
+ TII = MF.getSubtarget().getInstrInfo();
+
+ bool Changed = false;
+
+ for (MachineBasicBlock &MBB : MF) {
+ for (MachineInstr &MI : make_early_inc_range(MBB)) {
+ switch (MI.getOpcode()) {
+ default:
+ break;
+ case RISCV::BNE:
+ case RISCV::BEQ:
+ case RISCV::BLT:
+ case RISCV::BLTU:
+ case RISCV::BGE:
+ case RISCV::BGEU:
+ Changed |= visitBranch(MI);
+ break;
+ }
+ }
+ }
+
+ return Changed;
+}
+
+FunctionPass *llvm::createRISCVMIPeepholeOptPass() {
+ return new RISCVMIPeepholeOpt();
+}
diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
index 0876f46728a10c..1af33aac601698 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
@@ -111,6 +111,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
initializeRISCVCodeGenPreparePass(*PR);
initializeRISCVPostRAExpandPseudoPass(*PR);
initializeRISCVMergeBaseOffsetOptPass(*PR);
+ initializeRISCVMIPeepholeOptPass(*PR);
initializeRISCVOptWInstrsPass(*PR);
initializeRISCVPreRAExpandPseudoPass(*PR);
initializeRISCVExpandPseudoPass(*PR);
@@ -501,6 +502,7 @@ void RISCVPassConfig::addPreEmitPass() {
void RISCVPassConfig::addPreEmitPass2() {
if (TM->getOptLevel() != CodeGenOptLevel::None) {
addPass(createRISCVMoveMergePass());
+ addPass(createRISCVMIPeepholeOptPass());
// Schedule PushPop Optimization before expansion of Pseudo instruction,
// ensuring return instruction is detected correctly.
addPass(createRISCVPushPopOptimizationPass());
diff --git a/llvm/test/CodeGen/RISCV/O3-pipeline.ll b/llvm/test/CodeGen/RISCV/O3-pipeline.ll
index 4121d111091117..731d1aea8c14a0 100644
--- a/llvm/test/CodeGen/RISCV/O3-pipeline.ll
+++ b/llvm/test/CodeGen/RISCV/O3-pipeline.ll
@@ -195,6 +195,7 @@
; CHECK-NEXT: Machine Optimization Remark Emitter
; CHECK-NEXT: Stack Frame Layout Analysis
; CHECK-NEXT: RISC-V Zcmp move merging pass
+; CHECK-NEXT: RISC-V MI Peephole Optimization pass
; CHECK-NEXT: RISC-V Zcmp Push/Pop optimization pass
; CHECK-NEXT: RISC-V pseudo instruction expansion pass
; CHECK-NEXT: RISC-V atomic pseudo instruction expansion pass
diff --git a/llvm/test/CodeGen/RISCV/peephole-branch.mir b/llvm/test/CodeGen/RISCV/peephole-branch.mir
index 8f22b42dacef31..27c58cddb035ad 100644
--- a/llvm/test/CodeGen/RISCV/peephole-branch.mir
+++ b/llvm/test/CodeGen/RISCV/peephole-branch.mir
@@ -1,5 +1,5 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
-# RUN: llc -o - %s -mtriple=riscv32 -run-pass=machine-cp | FileCheck %s
+# RUN: llc -o - %s -mtriple=riscv32 -run-pass=riscv-mi-peephole-opt | FileCheck %s
--- |
define void @peephole_bne(ptr %a, ptr %b, ptr %c) {
@@ -126,7 +126,6 @@ body: |
; CHECK-NEXT: liveins: $x10, $x11, $x12
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: renamable $x13 = ADDI $x0, 1
- ; CHECK-NEXT: BNE killed renamable $x13, $x13, %bb.2
; CHECK-NEXT: PseudoBR %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.block1:
@@ -185,7 +184,7 @@ body: |
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
; CHECK-NEXT: liveins: $x10, $x11, $x12
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: BEQ $x0, $x0, %bb.2
+ ; CHECK-NEXT: PseudoBR %bb.2
; CHECK-NEXT: PseudoBR %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.block1:
@@ -244,7 +243,6 @@ body: |
; CHECK-NEXT: liveins: $x10, $x11, $x12
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: renamable $x13 = ADDI $x0, 1
- ; CHECK-NEXT: BLT killed renamable $x13, $x13, %bb.2
; CHECK-NEXT: PseudoBR %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.block1:
@@ -304,7 +302,6 @@ body: |
; CHECK-NEXT: liveins: $x10, $x11, $x12
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: renamable $x13 = ADDI $x0, 1
- ; CHECK-NEXT: BLTU killed renamable $x13, $x13, %bb.2
; CHECK-NEXT: PseudoBR %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.block1:
@@ -363,7 +360,7 @@ body: |
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
; CHECK-NEXT: liveins: $x10, $x11, $x12
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: BGE $x0, $x0, %bb.2
+ ; CHECK-NEXT: PseudoBR %bb.2
; CHECK-NEXT: PseudoBR %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.block1:
@@ -421,7 +418,7 @@ body: |
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
; CHECK-NEXT: liveins: $x10, $x11, $x12
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: BGEU $x0, $x0, %bb.2
+ ; CHECK-NEXT: PseudoBR %bb.2
; CHECK-NEXT: PseudoBR %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.block1:
More information about the llvm-commits
mailing list