Skip to content

[RISCV] Add bltu/bgeu zero => bnez/beqz canonicalisation to RISCVInstrInfo::simplifyInstruction #141775

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 29, 2025

Conversation

asb
Copy link
Contributor

@asb asb commented May 28, 2025

We can end up with bltu/bgeu with the zero register as the 0th operand after tail duplication and then machine copy propagation. Canonicalising in simplifyInstruction (called from MachineCopyPropagation) both produces easier to read assembly output, and means it's possible that the compressed c.beqz/c.bnez forms are produced.

…rInfo::simplifyInstruction

We can end up with bltu/bgeu with the zero register as the 0th operand
after tail duplication and then machine copy propagation. Canonicalising
in simplifyInstruction (called from MachineCopyPropagation) both
produces easier to read assembly output, and means it's possible that
the compressed c.beqz/c.bnez forms are produced.
@asb asb requested review from preames and topperc May 28, 2025 14:30
@llvmbot
Copy link
Member

llvmbot commented May 28, 2025

@llvm/pr-subscribers-backend-risc-v

Author: Alex Bradbury (asb)

Changes

We can end up with bltu/bgeu with the zero register as the 0th operand after tail duplication and then machine copy propagation. Canonicalising in simplifyInstruction (called from MachineCopyPropagation) both produces easier to read assembly output, and means it's possible that the compressed c.beqz/c.bnez forms are produced.


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

2 Files Affected:

  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.cpp (+18)
  • (modified) llvm/test/CodeGen/RISCV/machine-copyprop-simplifyinstruction.mir (+36)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 818dedac08dde..7b3ab58f448db 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -4191,6 +4191,24 @@ bool RISCVInstrInfo::simplifyInstruction(MachineInstr &MI) const {
       return true;
     }
     break;
+  case RISCV::BLTU:
+    // bltu zero, rs, imm => bne rs, zero, imm
+    if (MI.getOperand(0).getReg() == RISCV::X0) {
+      MachineOperand MO0 = MI.getOperand(0);
+      MI.removeOperand(0);
+      MI.insert(MI.operands_begin() + 1, {MO0});
+      MI.setDesc(get(RISCV::BNE));
+    }
+    break;
+  case RISCV::BGEU:
+    // bgeu zero, rs, imm => beq rs, zero, imm
+    if (MI.getOperand(0).getReg() == RISCV::X0) {
+      MachineOperand MO0 = MI.getOperand(0);
+      MI.removeOperand(0);
+      MI.insert(MI.operands_begin() + 1, {MO0});
+      MI.setDesc(get(RISCV::BEQ));
+    }
+    break;
   }
   return false;
 }
diff --git a/llvm/test/CodeGen/RISCV/machine-copyprop-simplifyinstruction.mir b/llvm/test/CodeGen/RISCV/machine-copyprop-simplifyinstruction.mir
index 15a6d53f343c1..9e42783e44553 100644
--- a/llvm/test/CodeGen/RISCV/machine-copyprop-simplifyinstruction.mir
+++ b/llvm/test/CodeGen/RISCV/machine-copyprop-simplifyinstruction.mir
@@ -742,3 +742,39 @@ body: |
     renamable $x10 = MAXU renamable $x11, renamable $x11
     PseudoRET implicit $x10
 ...
+---
+name: bltu
+body: |
+  ; CHECK-LABEL: name: bltu
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $x11 = COPY $x12
+  ; CHECK-NEXT:   BNE $x12, $x0, %bb.1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1:
+  ; CHECK-NEXT:   PseudoRET
+  bb.0:
+    renamable $x11 = COPY $x12
+    BLTU $x0, renamable $x11, %bb.1
+  bb.1:
+    PseudoRET
+...
+---
+name: bgeu
+body: |
+  ; CHECK-LABEL: name: bgeu
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $x11 = COPY $x12
+  ; CHECK-NEXT:   BEQ $x12, $x0, %bb.1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1:
+  ; CHECK-NEXT:   PseudoRET
+  bb.0:
+    renamable $x11 = COPY $x12
+    BGEU $x0, renamable $x11, %bb.1
+  bb.1:
+    PseudoRET
+...

Copy link
Collaborator

@preames preames left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

}
break;
case RISCV::BGEU:
// bgeu zero, rs, imm => beq rs, zero, imm
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about other cases here:

bgeu rs, zero, imm is an unconditionally taken branch. Rewriting as a unconditional branch is hard (due to CFG updates), but maybe we could turn this into beq zero, zero, imm? That would remove the register use, and might compress better?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

beq zero, zero, imm isn't compressible. The first register needs to be x8-x15.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, bgeu reg, zero is on my radar and as you say the CFG update makes it challenging. I hadn't considered canonicalising to beq zero, zero, imm. beq reg, reg, imm would be an alternative that has the chance of being compressible.

There are ~440 static instances of bgeu reg, zero in an RVA22 test-suite build. 40 instances of beq with rs1 == rs2 and 50 of bne with rs1 == rs2.

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@asb asb merged commit 76b6bf4 into llvm:main May 29, 2025
13 checks passed
svkeerthy pushed a commit that referenced this pull request May 29, 2025
…rInfo::simplifyInstruction (#141775)

We can end up with bltu/bgeu with the zero register as the 0th operand
after tail duplication and then machine copy propagation. Canonicalising
in simplifyInstruction (called from MachineCopyPropagation) both
produces easier to read assembly output, and means it's possible that
the compressed c.beqz/c.bnez forms are produced.
google-yfyang pushed a commit to google-yfyang/llvm-project that referenced this pull request May 29, 2025
…rInfo::simplifyInstruction (llvm#141775)

We can end up with bltu/bgeu with the zero register as the 0th operand
after tail duplication and then machine copy propagation. Canonicalising
in simplifyInstruction (called from MachineCopyPropagation) both
produces easier to read assembly output, and means it's possible that
the compressed c.beqz/c.bnez forms are produced.
sivan-shani pushed a commit to sivan-shani/llvm-project that referenced this pull request Jun 3, 2025
…rInfo::simplifyInstruction (llvm#141775)

We can end up with bltu/bgeu with the zero register as the 0th operand
after tail duplication and then machine copy propagation. Canonicalising
in simplifyInstruction (called from MachineCopyPropagation) both
produces easier to read assembly output, and means it's possible that
the compressed c.beqz/c.bnez forms are produced.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants