[llvm] [RISCV][TII] Add and use new hook to optimize/canonicalize instructions after MachineCopyPropagation (PR #137973)
Alex Bradbury via llvm-commits
llvm-commits at lists.llvm.org
Tue May 6 06:51:26 PDT 2025
https://github.com/asb updated https://github.com/llvm/llvm-project/pull/137973
>From 2ad6cc8a9b84c91dd6e1efd65baa6e3e896f6221 Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Wed, 30 Apr 2025 15:24:19 +0100
Subject: [PATCH 01/18] [RISCV][TII] Add and use new hook fo
optmize/canonicalize instructions after MachineCopyPropagation
PR #136875 was posted as a draft PR that handled a subset of these
cases, using the CompressPat mechanism. The consensus from that
discussion (and a conclusion I agree with) is that it would be
beneficial doing this optimisation earlier on, and in a way that isn't
limited just to cases that can be handled by instruction compression.
The most common source for instructions that can be
optimized/canonicalized in this way is through tail duplication followed
by machine copy propagation. For RISC-V, choosing a more canonical
instruction allows it to be compressed when it couldn't be before. There
is the potential that it would make other MI-level optimisations easier.
This modifies ~910 instructions across an llvm-test-suite build
including SPEC2017, targeting rva22u64.
Coverage of instructions is based on observations from a script written
to find redundant or improperly canonicalized instructions (though I
aim to support all instructions in a 'group' at once, e.g. MUL* even if
I only saw some variants of MUL in practice).
---
llvm/include/llvm/CodeGen/TargetInstrInfo.h | 10 +
llvm/lib/CodeGen/MachineCopyPropagation.cpp | 6 +
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 218 ++++++
llvm/lib/Target/RISCV/RISCVInstrInfo.h | 2 +
.../RISCV/machine-copyprop-optimizeinstr.mir | 685 ++++++++++++++++++
5 files changed, 921 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir
diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
index 0aac02d3dc786..3b33989d28c77 100644
--- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
@@ -510,6 +510,16 @@ class TargetInstrInfo : public MCInstrInfo {
return false;
}
+ /// If possible, converts the instruction to a more 'optimized'/canonical
+ /// form. Returns true if the instruction was modified.
+ ///
+ /// This function is only called after register allocation. The MI will be
+ /// modified in place. This is called by passes such as
+ /// MachineCopyPropagation, where their mutation of the MI operands may
+ /// expose opportunities to convert the instruction to a simpler form (e.g.
+ /// a load of 0).
+ virtual bool optimizeInstruction(MachineInstr &MI) const { return false; }
+
/// A pair composed of a register and a sub-register index.
/// Used to give some type checking when modeling Reg:SubReg.
struct RegSubRegPair {
diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
index ff75b87b23128..6f1e6e46eef8b 100644
--- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp
+++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
@@ -867,6 +867,12 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
make_range(Copy->getIterator(), std::next(MI.getIterator())))
KMI.clearRegisterKills(CopySrcReg, TRI);
+ // Attempt to canonicalize/optimize the instruction now its arguments have
+ // been mutated.
+ if (TII->optimizeInstruction(MI)) {
+ LLVM_DEBUG(dbgs() << "MCP: After optimizeInstruction: " << MI << "\n");
+ }
+
++NumCopyForwards;
Changed = true;
}
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index c4a2784263af0..3e2549d4b17bd 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -2344,6 +2344,21 @@ static unsigned getSHXADDShiftAmount(unsigned Opc) {
}
}
+// Returns the shift amount from a SHXADD.UW instruction. Returns 0 if the
+// instruction is not a SHXADD.UW.
+static unsigned getSHXADDUWShiftAmount(unsigned Opc) {
+ switch (Opc) {
+ default:
+ return 0;
+ case RISCV::SH1ADD_UW:
+ return 1;
+ case RISCV::SH2ADD_UW:
+ return 2;
+ case RISCV::SH3ADD_UW:
+ return 3;
+ }
+}
+
// Look for opportunities to combine (sh3add Z, (add X, (slli Y, 5))) into
// (sh3add (sh2add Y, Z), X).
static bool getSHXADDPatterns(const MachineInstr &Root,
@@ -3850,6 +3865,209 @@ MachineInstr *RISCVInstrInfo::commuteInstructionImpl(MachineInstr &MI,
return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
}
+bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
+ switch (MI.getOpcode()) {
+ default:
+ break;
+ case RISCV::OR:
+ case RISCV::XOR:
+ // Normalize:
+ // [x]or rd, zero, rs => [x]or rd, rs, zero
+ if (MI.getOperand(1).getReg() == RISCV::X0) {
+ MachineOperand MO1 = MI.getOperand(1);
+ MI.removeOperand(1);
+ MI.addOperand(MO1);
+ }
+ // [x]or rd, rs, zero => addi rd, rs, 0
+ if (MI.getOperand(2).getReg() == RISCV::X0) {
+ MI.getOperand(2).ChangeToImmediate(0);
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ // xor rd, rs, rs => li rd, rs, 0
+ if (MI.getOpcode() == RISCV::XOR && MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
+ MI.getOperand(2).ChangeToImmediate(0);
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ break;
+ case RISCV::ADDW:
+ // Normalize:
+ // addw rd, zero, rs => addw rd, rs, zero
+ if (MI.getOperand(1).getReg() == RISCV::X0) {
+ MachineOperand MO1 = MI.getOperand(1);
+ MI.removeOperand(1);
+ MI.addOperand(MO1);
+ }
+ // addw rd, rs, zero => addiw rd, rs, 0
+ if (MI.getOperand(2).getReg() == RISCV::X0) {
+ MI.getOperand(2).ChangeToImmediate(0);
+ MI.setDesc(get(RISCV::ADDIW));
+ return true;
+ }
+ break;
+ case RISCV::SUB:
+ case RISCV::PACK:
+ case RISCV::PACKW:
+ // sub rd, rs, zero => addi rd, rs, 0
+ // pack[w] rd, rs, zero => addi rd, rs, zero
+ if (MI.getOperand(2).getReg() == RISCV::X0) {
+ MI.getOperand(2).ChangeToImmediate(0);
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ break;
+ case RISCV::SUBW:
+ // subw rd, rs, zero => addiw rd, rs, 0
+ if (MI.getOperand(2).getReg() == RISCV::X0) {
+ MI.getOperand(2).ChangeToImmediate(0);
+ MI.setDesc(get(RISCV::ADDIW));
+ return true;
+ }
+ break;
+ case RISCV::SH1ADD:
+ case RISCV::SH1ADD_UW:
+ case RISCV::SH2ADD:
+ case RISCV::SH2ADD_UW:
+ case RISCV::SH3ADD:
+ case RISCV::SH3ADD_UW:
+ // shNadd[.uw] rd, zero, rs => addi rd, rs, 0
+ if (MI.getOperand(1).getReg() == RISCV::X0) {
+ MI.removeOperand(1);
+ MI.addOperand(MachineOperand::CreateImm(0));
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ // shNadd[.uw] rd, rs, zero => slli[.uw] rd, rs, N
+ if (MI.getOperand(2).getReg() == RISCV::X0) {
+ MI.removeOperand(2);
+ unsigned Opc = MI.getOpcode();
+ if (Opc == RISCV::SH1ADD_UW || Opc == RISCV::SH2ADD_UW || Opc == RISCV::SH3ADD_UW) {
+ MI.addOperand(MachineOperand::CreateImm(getSHXADDUWShiftAmount(Opc)));
+ MI.setDesc(get(RISCV::SLLI_UW));
+ return true;
+ }
+ MI.addOperand(MachineOperand::CreateImm(getSHXADDShiftAmount(Opc)));
+ MI.setDesc(get(RISCV::SLLI));
+ return true;
+ }
+ break;
+ case RISCV::ANDI:
+ // andi rd, zero, C => li rd, 0
+ if (MI.getOperand(1).getReg() == RISCV::X0) {
+ MI.getOperand(2).setImm(0);
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ break;
+ case RISCV::AND:
+ case RISCV::MUL:
+ case RISCV::MULH:
+ case RISCV::MULHSU:
+ case RISCV::MULHU:
+ case RISCV::MULW:
+ // and rd, rs, zero => li rd, 0
+ // and rd, zero, rs => li rd, 0
+ // mul* rd, rs, zero => li rd, 0
+ // mul* rd, zero, rs => li rd, 0
+ if (MI.getOperand(1).getReg() == RISCV::X0) {
+ MI.removeOperand(2);
+ MI.addOperand(MachineOperand::CreateImm(0));
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ if (MI.getOperand(2).getReg() == RISCV::X0) {
+ MI.removeOperand(1);
+ MI.addOperand(MachineOperand::CreateImm(0));
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ break;
+ case RISCV::SLLI:
+ case RISCV::SRLI:
+ case RISCV::SRAI:
+ case RISCV::SLLIW:
+ case RISCV::SRLIW:
+ case RISCV::SRAIW:
+ case RISCV::SLLI_UW:
+ // shiftimm rd, zero, N => li rd, 0
+ if (MI.getOperand(1).getReg() == RISCV::X0) {
+ MI.getOperand(2).setImm(0);
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ break;
+ case RISCV::ORI:
+ case RISCV::XORI:
+ // [x]ori rd, zero, N => li rd, N
+ if (MI.getOperand(1).getReg() == RISCV::X0) {
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ break;
+ case RISCV::SLTIU:
+ // seqz rd, zero => li rd, 1
+ if (MI.getOperand(1).getReg() == RISCV::X0 && MI.getOperand(2).getImm() == 1) {
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ break;
+ case RISCV::SLTU:
+ case RISCV::ADD_UW:
+ // snez rd, zero => li rd, 0
+ // zext.w rd, zero => li rd, 0
+ if (MI.getOperand(1).getReg() == RISCV::X0 && MI.getOperand(2).getReg() == RISCV::X0) {
+ MI.getOperand(2).ChangeToImmediate(0);
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ // add.uw rd, zero, rs => add.uw rd, rs, zero (canonical zext.w)
+ if (MI.getOpcode() == RISCV::ADD_UW && MI.getOperand(1).getReg() == RISCV::X0) {
+ MachineOperand MO1 = MI.getOperand(1);
+ MI.removeOperand(1);
+ MI.addOperand(MO1);
+ }
+ break;
+ case RISCV::SEXT_H:
+ case RISCV::SEXT_B:
+ case RISCV::ZEXT_H_RV32:
+ case RISCV::ZEXT_H_RV64:
+ // sext.[hb] rd, zero => li rd, 0
+ // zext.h rd, zero => li rd, 0
+ if (MI.getOperand(1).getReg() == RISCV::X0) {
+ MI.addOperand(MachineOperand::CreateImm(0));
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ break;
+ case RISCV::SLL:
+ case RISCV::SRL:
+ case RISCV::SRA:
+ case RISCV::SLLW:
+ case RISCV::SRLW:
+ case RISCV::SRAW:
+ // shift rd, zero, rs => li rd, 0
+ if (MI.getOperand(1).getReg() == RISCV::X0) {
+ MI.getOperand(2).ChangeToImmediate(0);
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ break;
+ case RISCV::MIN:
+ case RISCV::MINU:
+ case RISCV::MAX:
+ case RISCV::MAXU:
+ // min|max rd, rs, rs => addi rd, rs, 0
+ if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
+ MI.getOperand(2).ChangeToImmediate(0);
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ break;
+ }
+ return false;
+}
+
#undef CASE_RVV_OPCODE_UNMASK_LMUL
#undef CASE_RVV_OPCODE_MASK_LMUL
#undef CASE_RVV_OPCODE_LMUL
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.h b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
index 67e457d64f6e3..ccca9b7120e02 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
@@ -242,6 +242,8 @@ class RISCVInstrInfo : public RISCVGenInstrInfo {
unsigned OpIdx1,
unsigned OpIdx2) const override;
+ bool optimizeInstruction(MachineInstr &MI) const override;
+
MachineInstr *convertToThreeAddress(MachineInstr &MI, LiveVariables *LV,
LiveIntervals *LIS) const override;
diff --git a/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir b/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir
new file mode 100644
index 0000000000000..ed4e7cb8df6b5
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir
@@ -0,0 +1,685 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -o - %s -mtriple=riscv64 -run-pass=machine-cp -mcp-use-is-copy-instr | FileCheck %s
+
+---
+name: or1
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: or1
+ ; CHECK: renamable $x10 = ADDI $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = OR renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: or2
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: or2
+ ; CHECK: renamable $x10 = ADDI $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = OR $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: xor1
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: xor1
+ ; CHECK: renamable $x10 = ADDI $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = XOR renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: xor2
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: xor2
+ ; CHECK: renamable $x10 = ADDI $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = XOR $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: addw1
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: addw1
+ ; CHECK: renamable $x10 = ADDIW $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x0
+ renamable $x10 = ADDW renamable $x11, $x12
+ PseudoRET implicit $x10
+...
+---
+name: addw2
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: addw2
+ ; CHECK: renamable $x10 = ADDIW $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x0
+ renamable $x10 = ADDW $x12, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: sub
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sub
+ ; CHECK: renamable $x10 = ADDI $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SUB renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: pack
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: pack
+ ; CHECK: renamable $x10 = ADDI $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = PACK renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: packw
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: packw
+ ; CHECK: renamable $x10 = ADDI $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = PACKW renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: subw
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: subw
+ ; CHECK: renamable $x10 = ADDIW $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SUBW renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: sh1add1
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sh1add1
+ ; CHECK: renamable $x10 = ADDI $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SH1ADD $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: sh1add2
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sh1add2
+ ; CHECK: renamable $x10 = SLLI $x12, 1
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SH1ADD renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: sh1add.uw1
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sh1add.uw1
+ ; CHECK: renamable $x10 = ADDI $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SH1ADD_UW $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: sh1add.uw2
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sh1add.uw2
+ ; CHECK: renamable $x10 = SLLI_UW $x12, 1
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SH1ADD_UW renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: sh2add1
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sh2add1
+ ; CHECK: renamable $x10 = ADDI $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SH2ADD $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: sh2add2
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sh2add2
+ ; CHECK: renamable $x10 = SLLI $x12, 2
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SH2ADD renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: sh2add.uw1
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sh2add.uw1
+ ; CHECK: renamable $x10 = ADDI $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SH2ADD_UW $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: sh2add.uw2
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sh2add.uw2
+ ; CHECK: renamable $x10 = SLLI_UW $x12, 2
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SH2ADD_UW renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: sh3add1
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sh3add1
+ ; CHECK: renamable $x10 = ADDI $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SH3ADD $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: sh3add2
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sh3add2
+ ; CHECK: renamable $x10 = SLLI $x12, 3
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SH3ADD renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: sh3add.uw1
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sh3add.uw1
+ ; CHECK: renamable $x10 = ADDI $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SH3ADD_UW $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: sh3add.uw2
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sh3add.uw2
+ ; CHECK: renamable $x10 = SLLI_UW $x12, 3
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SH3ADD_UW renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: andi
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: andi
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x0
+ renamable $x10 = ANDI renamable $x11, 13
+ PseudoRET implicit $x10
+...
+---
+name: and1
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: and1
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = AND renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: and2
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: and2
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = AND $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: mul1
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: mul1
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = MUL renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: mul2
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: mul2
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = MUL $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: mulh1
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: mulh1
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = MULH renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: mulh2
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: mulh2
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = MULH $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: mulhsu1
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: mulhsu1
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = MULHSU renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: mulhsu2
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: mulhsu2
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = MULHSU $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: mulhu1
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: mulhu1
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = MULHU renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: mulhu2
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: mulhu2
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = MULHU $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: mulw1
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: mulw1
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = MULW renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: mulw2
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: mulw2
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = MULW $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: slli
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: slli
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x0
+ renamable $x10 = SLLI renamable $x11, 13
+ PseudoRET implicit $x10
+...
+---
+name: srli
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: srli
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x0
+ renamable $x10 = SRLI renamable $x11, 13
+ PseudoRET implicit $x10
+...
+---
+name: srai
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: srai
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x0
+ renamable $x10 = SRAI renamable $x11, 13
+ PseudoRET implicit $x10
+...
+---
+name: slliw
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: slliw
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x0
+ renamable $x10 = SLLIW renamable $x11, 13
+ PseudoRET implicit $x10
+...
+---
+name: srliw
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: srliw
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x0
+ renamable $x10 = SRLIW renamable $x11, 13
+ PseudoRET implicit $x10
+...
+---
+name: sraiw
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sraiw
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x0
+ renamable $x10 = SRAIW renamable $x11, 13
+ PseudoRET implicit $x10
+...
+---
+name: slli_uw
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: slli_uw
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x0
+ renamable $x10 = SLLI_UW renamable $x11, 13
+ PseudoRET implicit $x10
+...
+---
+name: ori
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: ori
+ ; CHECK: renamable $x10 = ADDI $x0, 13
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x0
+ renamable $x10 = ORI renamable $x11, 13
+ PseudoRET implicit $x10
+...
+---
+name: xori
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: xori
+ ; CHECK: renamable $x10 = ADDI $x0, 13
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x0
+ renamable $x10 = XORI renamable $x11, 13
+ PseudoRET implicit $x10
+...
+---
+name: sltiu
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sltiu
+ ; CHECK: renamable $x10 = ADDI $x0, 1
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x0
+ renamable $x10 = SLTIU renamable $x11, 1
+ PseudoRET implicit $x10
+...
+---
+name: sltu
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sltu
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x0
+ renamable $x10 = SLTU renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: add.uw1
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: add.uw1
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x0
+ renamable $x10 = ADD_UW renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: add.uw2
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: add.uw2
+ ; CHECK: renamable $x10 = ADD_UW $x12, $x0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = ADD_UW $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: sext.h
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sext.h
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x0
+ renamable $x10 = SEXT_H renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: sext.b
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sext.b
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x0
+ renamable $x10 = SEXT_B renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: zext.h.rv32
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: zext.h.rv32
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x0
+ renamable $x10 = ZEXT_H_RV32 renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: zext.h.rv64
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: zext.h.rv64
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x0
+ renamable $x10 = ZEXT_H_RV64 renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: sll
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sll
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SLL $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: srl
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: srl
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SRL $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: sra
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sra
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SRA $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: sllw
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sllw
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SLLW $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: srlw
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: srlw
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SRLW $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: sraw
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sraw
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SRAW $x0, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: min
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: min
+ ; CHECK: renamable $x10 = ADDI $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = MIN renamable $x11, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: minu
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: minu
+ ; CHECK: renamable $x10 = MINU $x12, $x12
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = MINU renamable $x11, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: max
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: max
+ ; CHECK: renamable $x10 = ADDI $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = MAX renamable $x11, renamable $x11
+ PseudoRET implicit $x10
+...
+---
+name: maxu
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: maxu
+ ; CHECK: renamable $x10 = MAXU $x12, $x12
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = MAXU renamable $x11, renamable $x11
+ PseudoRET implicit $x10
+...
>From d23c66cd54da35c77d84e4da7ee3a622e97b6fd5 Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Wed, 30 Apr 2025 15:35:24 +0100
Subject: [PATCH 02/18] Add changes missed in first push
---
llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir b/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir
index ed4e7cb8df6b5..753a688c7c3b2 100644
--- a/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir
+++ b/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir
@@ -655,7 +655,7 @@ name: minu
body: |
bb.0:
; CHECK-LABEL: name: minu
- ; CHECK: renamable $x10 = MINU $x12, $x12
+ ; CHECK: renamable $x10 = ADDI $x12, 0
; CHECK-NEXT: PseudoRET implicit $x10
renamable $x11 = COPY $x12
renamable $x10 = MINU renamable $x11, renamable $x11
@@ -677,7 +677,7 @@ name: maxu
body: |
bb.0:
; CHECK-LABEL: name: maxu
- ; CHECK: renamable $x10 = MAXU $x12, $x12
+ ; CHECK: renamable $x10 = ADDI $x12, 0
; CHECK-NEXT: PseudoRET implicit $x10
renamable $x11 = COPY $x12
renamable $x10 = MAXU renamable $x11, renamable $x11
>From 5d00e6f71478018074efb999eb07c5c0f7cf6da9 Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Wed, 30 Apr 2025 17:29:11 +0100
Subject: [PATCH 03/18] Fix errors in some patterns and remove PACK/PACKW
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 12 +++----
.../RISCV/machine-copyprop-optimizeinstr.mir | 36 +++++++------------
2 files changed, 18 insertions(+), 30 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 3e2549d4b17bd..21a878655bb66 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -3884,8 +3884,9 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
MI.setDesc(get(RISCV::ADDI));
return true;
}
- // xor rd, rs, rs => li rd, rs, 0
+ // xor rd, rs, rs => li rd, 0
if (MI.getOpcode() == RISCV::XOR && MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
+ MI.getOperand(1).setReg(RISCV::X0);
MI.getOperand(2).ChangeToImmediate(0);
MI.setDesc(get(RISCV::ADDI));
return true;
@@ -3907,10 +3908,7 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
}
break;
case RISCV::SUB:
- case RISCV::PACK:
- case RISCV::PACKW:
// sub rd, rs, zero => addi rd, rs, 0
- // pack[w] rd, rs, zero => addi rd, rs, zero
if (MI.getOperand(2).getReg() == RISCV::X0) {
MI.getOperand(2).ChangeToImmediate(0);
MI.setDesc(get(RISCV::ADDI));
@@ -4021,11 +4019,11 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
MI.setDesc(get(RISCV::ADDI));
return true;
}
- // add.uw rd, zero, rs => add.uw rd, rs, zero (canonical zext.w)
+ // add.uw rd, zero, rs => addi rd, rs, 0
if (MI.getOpcode() == RISCV::ADD_UW && MI.getOperand(1).getReg() == RISCV::X0) {
- MachineOperand MO1 = MI.getOperand(1);
MI.removeOperand(1);
- MI.addOperand(MO1);
+ MI.addOperand(MachineOperand::CreateImm(0));
+ MI.setDesc(get(RISCV::ADDI));
}
break;
case RISCV::SEXT_H:
diff --git a/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir b/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir
index 753a688c7c3b2..25df833913bda 100644
--- a/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir
+++ b/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir
@@ -46,6 +46,18 @@ body: |
PseudoRET implicit $x10
...
---
+---
+name: xor3
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: xor3
+ ; CHECK: renamable $x10 = ADDI $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = XOR renamable $x11, renamable $x11
+ PseudoRET implicit $x10
+...
+---
name: addw1
body: |
bb.0:
@@ -79,28 +91,6 @@ body: |
PseudoRET implicit $x10
...
---
-name: pack
-body: |
- bb.0:
- ; CHECK-LABEL: name: pack
- ; CHECK: renamable $x10 = ADDI $x12, 0
- ; CHECK-NEXT: PseudoRET implicit $x10
- renamable $x11 = COPY $x12
- renamable $x10 = PACK renamable $x11, $x0
- PseudoRET implicit $x10
-...
----
-name: packw
-body: |
- bb.0:
- ; CHECK-LABEL: name: packw
- ; CHECK: renamable $x10 = ADDI $x12, 0
- ; CHECK-NEXT: PseudoRET implicit $x10
- renamable $x11 = COPY $x12
- renamable $x10 = PACKW renamable $x11, $x0
- PseudoRET implicit $x10
-...
----
name: subw
body: |
bb.0:
@@ -523,7 +513,7 @@ name: add.uw2
body: |
bb.0:
; CHECK-LABEL: name: add.uw2
- ; CHECK: renamable $x10 = ADD_UW $x12, $x0
+ ; CHECK: renamable $x10 = ADDI $x12, 0
; CHECK-NEXT: PseudoRET implicit $x10
renamable $x11 = COPY $x12
renamable $x10 = ADD_UW $x0, renamable $x11
>From 3048ba9b5c483fad907869ec1345ed6d5ae88390 Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Thu, 1 May 2025 13:33:02 +0100
Subject: [PATCH 04/18] Use commuteInstruction helper
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 21a878655bb66..da9fdb882941f 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -3873,11 +3873,8 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
case RISCV::XOR:
// Normalize:
// [x]or rd, zero, rs => [x]or rd, rs, zero
- if (MI.getOperand(1).getReg() == RISCV::X0) {
- MachineOperand MO1 = MI.getOperand(1);
- MI.removeOperand(1);
- MI.addOperand(MO1);
- }
+ if (MI.getOperand(1).getReg() == RISCV::X0)
+ commuteInstruction(MI);
// [x]or rd, rs, zero => addi rd, rs, 0
if (MI.getOperand(2).getReg() == RISCV::X0) {
MI.getOperand(2).ChangeToImmediate(0);
@@ -3895,11 +3892,8 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
case RISCV::ADDW:
// Normalize:
// addw rd, zero, rs => addw rd, rs, zero
- if (MI.getOperand(1).getReg() == RISCV::X0) {
- MachineOperand MO1 = MI.getOperand(1);
- MI.removeOperand(1);
- MI.addOperand(MO1);
- }
+ if (MI.getOperand(1).getReg() == RISCV::X0)
+ commuteInstruction(MI);
// addw rd, rs, zero => addiw rd, rs, 0
if (MI.getOperand(2).getReg() == RISCV::X0) {
MI.getOperand(2).ChangeToImmediate(0);
>From 7da3f928b54aec33923c575f8d8a6e83ad96cb92 Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Thu, 1 May 2025 13:42:46 +0100
Subject: [PATCH 05/18] Move optimizeInstructoin to after the preprocessor
undefs
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 44 ++++++++++++------------
1 file changed, 22 insertions(+), 22 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index da9fdb882941f..e5f967d38ac6d 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -3865,6 +3865,28 @@ MachineInstr *RISCVInstrInfo::commuteInstructionImpl(MachineInstr &MI,
return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
}
+#undef CASE_RVV_OPCODE_UNMASK_LMUL
+#undef CASE_RVV_OPCODE_MASK_LMUL
+#undef CASE_RVV_OPCODE_LMUL
+#undef CASE_RVV_OPCODE_UNMASK_WIDEN
+#undef CASE_RVV_OPCODE_UNMASK
+#undef CASE_RVV_OPCODE_MASK_WIDEN
+#undef CASE_RVV_OPCODE_MASK
+#undef CASE_RVV_OPCODE_WIDEN
+#undef CASE_RVV_OPCODE
+
+#undef CASE_VMA_OPCODE_COMMON
+#undef CASE_VMA_OPCODE_LMULS_M1
+#undef CASE_VMA_OPCODE_LMULS_MF2
+#undef CASE_VMA_OPCODE_LMULS_MF4
+#undef CASE_VMA_OPCODE_LMULS
+#undef CASE_VFMA_OPCODE_COMMON
+#undef CASE_VFMA_OPCODE_LMULS_M1
+#undef CASE_VFMA_OPCODE_LMULS_MF2
+#undef CASE_VFMA_OPCODE_LMULS_MF4
+#undef CASE_VFMA_OPCODE_VV
+#undef CASE_VFMA_SPLATS
+
bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
switch (MI.getOpcode()) {
default:
@@ -4060,28 +4082,6 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
return false;
}
-#undef CASE_RVV_OPCODE_UNMASK_LMUL
-#undef CASE_RVV_OPCODE_MASK_LMUL
-#undef CASE_RVV_OPCODE_LMUL
-#undef CASE_RVV_OPCODE_UNMASK_WIDEN
-#undef CASE_RVV_OPCODE_UNMASK
-#undef CASE_RVV_OPCODE_MASK_WIDEN
-#undef CASE_RVV_OPCODE_MASK
-#undef CASE_RVV_OPCODE_WIDEN
-#undef CASE_RVV_OPCODE
-
-#undef CASE_VMA_OPCODE_COMMON
-#undef CASE_VMA_OPCODE_LMULS_M1
-#undef CASE_VMA_OPCODE_LMULS_MF2
-#undef CASE_VMA_OPCODE_LMULS_MF4
-#undef CASE_VMA_OPCODE_LMULS
-#undef CASE_VFMA_OPCODE_COMMON
-#undef CASE_VFMA_OPCODE_LMULS_M1
-#undef CASE_VFMA_OPCODE_LMULS_MF2
-#undef CASE_VFMA_OPCODE_LMULS_MF4
-#undef CASE_VFMA_OPCODE_VV
-#undef CASE_VFMA_SPLATS
-
// clang-format off
#define CASE_WIDEOP_OPCODE_COMMON(OP, LMUL) \
RISCV::PseudoV##OP##_##LMUL##_TIED
>From 109a5ba7addbc5dba9b21e571b4dc87b81b2e9e8 Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Thu, 1 May 2025 13:37:49 +0100
Subject: [PATCH 06/18] (cherry-pick) [RISCV][NFC] Add missed // clang-format
on
clang-format was turned off for the defines, but there was no matching
`// clang-format on` comment at the end. Ran into this in #137973
https://github.com/llvm/llvm-project/commit/3376071a24b772446d2f2241e4370b6d0cba6947
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index e5f967d38ac6d..2ab058c8e86b5 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -3749,6 +3749,7 @@ bool RISCVInstrInfo::findCommutedOpIndices(const MachineInstr &MI,
CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VFPR16, E16) \
CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VFPR32, E32) \
CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VFPR64, E64)
+// clang-format on
MachineInstr *RISCVInstrInfo::commuteInstructionImpl(MachineInstr &MI,
bool NewMI,
>From a02dc453fef531c8bc820c51a8b42cd66f4cf5d0 Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Thu, 1 May 2025 13:44:38 +0100
Subject: [PATCH 07/18] Reformat now issue with clang-format being disabled was
fixed
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 221 ++++++++++++-----------
1 file changed, 113 insertions(+), 108 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 2ab058c8e86b5..b36428beb2e40 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -3894,110 +3894,112 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
break;
case RISCV::OR:
case RISCV::XOR:
- // Normalize:
- // [x]or rd, zero, rs => [x]or rd, rs, zero
- if (MI.getOperand(1).getReg() == RISCV::X0)
- commuteInstruction(MI);
- // [x]or rd, rs, zero => addi rd, rs, 0
- if (MI.getOperand(2).getReg() == RISCV::X0) {
- MI.getOperand(2).ChangeToImmediate(0);
- MI.setDesc(get(RISCV::ADDI));
- return true;
- }
- // xor rd, rs, rs => li rd, 0
- if (MI.getOpcode() == RISCV::XOR && MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
- MI.getOperand(1).setReg(RISCV::X0);
- MI.getOperand(2).ChangeToImmediate(0);
- MI.setDesc(get(RISCV::ADDI));
- return true;
- }
- break;
+ // Normalize:
+ // [x]or rd, zero, rs => [x]or rd, rs, zero
+ if (MI.getOperand(1).getReg() == RISCV::X0)
+ commuteInstruction(MI);
+ // [x]or rd, rs, zero => addi rd, rs, 0
+ if (MI.getOperand(2).getReg() == RISCV::X0) {
+ MI.getOperand(2).ChangeToImmediate(0);
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ // xor rd, rs, rs => li rd, 0
+ if (MI.getOpcode() == RISCV::XOR &&
+ MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
+ MI.getOperand(1).setReg(RISCV::X0);
+ MI.getOperand(2).ChangeToImmediate(0);
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ break;
case RISCV::ADDW:
- // Normalize:
- // addw rd, zero, rs => addw rd, rs, zero
- if (MI.getOperand(1).getReg() == RISCV::X0)
- commuteInstruction(MI);
- // addw rd, rs, zero => addiw rd, rs, 0
- if (MI.getOperand(2).getReg() == RISCV::X0) {
- MI.getOperand(2).ChangeToImmediate(0);
- MI.setDesc(get(RISCV::ADDIW));
- return true;
- }
- break;
+ // Normalize:
+ // addw rd, zero, rs => addw rd, rs, zero
+ if (MI.getOperand(1).getReg() == RISCV::X0)
+ commuteInstruction(MI);
+ // addw rd, rs, zero => addiw rd, rs, 0
+ if (MI.getOperand(2).getReg() == RISCV::X0) {
+ MI.getOperand(2).ChangeToImmediate(0);
+ MI.setDesc(get(RISCV::ADDIW));
+ return true;
+ }
+ break;
case RISCV::SUB:
- // sub rd, rs, zero => addi rd, rs, 0
- if (MI.getOperand(2).getReg() == RISCV::X0) {
- MI.getOperand(2).ChangeToImmediate(0);
- MI.setDesc(get(RISCV::ADDI));
- return true;
- }
- break;
+ // sub rd, rs, zero => addi rd, rs, 0
+ if (MI.getOperand(2).getReg() == RISCV::X0) {
+ MI.getOperand(2).ChangeToImmediate(0);
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ break;
case RISCV::SUBW:
- // subw rd, rs, zero => addiw rd, rs, 0
- if (MI.getOperand(2).getReg() == RISCV::X0) {
- MI.getOperand(2).ChangeToImmediate(0);
- MI.setDesc(get(RISCV::ADDIW));
- return true;
- }
- break;
+ // subw rd, rs, zero => addiw rd, rs, 0
+ if (MI.getOperand(2).getReg() == RISCV::X0) {
+ MI.getOperand(2).ChangeToImmediate(0);
+ MI.setDesc(get(RISCV::ADDIW));
+ return true;
+ }
+ break;
case RISCV::SH1ADD:
case RISCV::SH1ADD_UW:
case RISCV::SH2ADD:
case RISCV::SH2ADD_UW:
case RISCV::SH3ADD:
case RISCV::SH3ADD_UW:
- // shNadd[.uw] rd, zero, rs => addi rd, rs, 0
- if (MI.getOperand(1).getReg() == RISCV::X0) {
- MI.removeOperand(1);
- MI.addOperand(MachineOperand::CreateImm(0));
- MI.setDesc(get(RISCV::ADDI));
- return true;
- }
- // shNadd[.uw] rd, rs, zero => slli[.uw] rd, rs, N
- if (MI.getOperand(2).getReg() == RISCV::X0) {
- MI.removeOperand(2);
- unsigned Opc = MI.getOpcode();
- if (Opc == RISCV::SH1ADD_UW || Opc == RISCV::SH2ADD_UW || Opc == RISCV::SH3ADD_UW) {
- MI.addOperand(MachineOperand::CreateImm(getSHXADDUWShiftAmount(Opc)));
- MI.setDesc(get(RISCV::SLLI_UW));
- return true;
- }
- MI.addOperand(MachineOperand::CreateImm(getSHXADDShiftAmount(Opc)));
- MI.setDesc(get(RISCV::SLLI));
+ // shNadd[.uw] rd, zero, rs => addi rd, rs, 0
+ if (MI.getOperand(1).getReg() == RISCV::X0) {
+ MI.removeOperand(1);
+ MI.addOperand(MachineOperand::CreateImm(0));
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ // shNadd[.uw] rd, rs, zero => slli[.uw] rd, rs, N
+ if (MI.getOperand(2).getReg() == RISCV::X0) {
+ MI.removeOperand(2);
+ unsigned Opc = MI.getOpcode();
+ if (Opc == RISCV::SH1ADD_UW || Opc == RISCV::SH2ADD_UW ||
+ Opc == RISCV::SH3ADD_UW) {
+ MI.addOperand(MachineOperand::CreateImm(getSHXADDUWShiftAmount(Opc)));
+ MI.setDesc(get(RISCV::SLLI_UW));
return true;
}
- break;
+ MI.addOperand(MachineOperand::CreateImm(getSHXADDShiftAmount(Opc)));
+ MI.setDesc(get(RISCV::SLLI));
+ return true;
+ }
+ break;
case RISCV::ANDI:
- // andi rd, zero, C => li rd, 0
- if (MI.getOperand(1).getReg() == RISCV::X0) {
- MI.getOperand(2).setImm(0);
- MI.setDesc(get(RISCV::ADDI));
- return true;
- }
- break;
+ // andi rd, zero, C => li rd, 0
+ if (MI.getOperand(1).getReg() == RISCV::X0) {
+ MI.getOperand(2).setImm(0);
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ break;
case RISCV::AND:
case RISCV::MUL:
case RISCV::MULH:
case RISCV::MULHSU:
case RISCV::MULHU:
case RISCV::MULW:
- // and rd, rs, zero => li rd, 0
- // and rd, zero, rs => li rd, 0
- // mul* rd, rs, zero => li rd, 0
- // mul* rd, zero, rs => li rd, 0
- if (MI.getOperand(1).getReg() == RISCV::X0) {
- MI.removeOperand(2);
- MI.addOperand(MachineOperand::CreateImm(0));
- MI.setDesc(get(RISCV::ADDI));
- return true;
- }
- if (MI.getOperand(2).getReg() == RISCV::X0) {
- MI.removeOperand(1);
- MI.addOperand(MachineOperand::CreateImm(0));
- MI.setDesc(get(RISCV::ADDI));
- return true;
- }
- break;
+ // and rd, rs, zero => li rd, 0
+ // and rd, zero, rs => li rd, 0
+ // mul* rd, rs, zero => li rd, 0
+ // mul* rd, zero, rs => li rd, 0
+ if (MI.getOperand(1).getReg() == RISCV::X0) {
+ MI.removeOperand(2);
+ MI.addOperand(MachineOperand::CreateImm(0));
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ if (MI.getOperand(2).getReg() == RISCV::X0) {
+ MI.removeOperand(1);
+ MI.addOperand(MachineOperand::CreateImm(0));
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ break;
case RISCV::SLLI:
case RISCV::SRLI:
case RISCV::SRAI:
@@ -4005,39 +4007,42 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
case RISCV::SRLIW:
case RISCV::SRAIW:
case RISCV::SLLI_UW:
- // shiftimm rd, zero, N => li rd, 0
- if (MI.getOperand(1).getReg() == RISCV::X0) {
- MI.getOperand(2).setImm(0);
- MI.setDesc(get(RISCV::ADDI));
- return true;
- }
- break;
+ // shiftimm rd, zero, N => li rd, 0
+ if (MI.getOperand(1).getReg() == RISCV::X0) {
+ MI.getOperand(2).setImm(0);
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ break;
case RISCV::ORI:
case RISCV::XORI:
- // [x]ori rd, zero, N => li rd, N
- if (MI.getOperand(1).getReg() == RISCV::X0) {
- MI.setDesc(get(RISCV::ADDI));
- return true;
- }
- break;
+ // [x]ori rd, zero, N => li rd, N
+ if (MI.getOperand(1).getReg() == RISCV::X0) {
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ break;
case RISCV::SLTIU:
- // seqz rd, zero => li rd, 1
- if (MI.getOperand(1).getReg() == RISCV::X0 && MI.getOperand(2).getImm() == 1) {
- MI.setDesc(get(RISCV::ADDI));
- return true;
- }
- break;
+ // seqz rd, zero => li rd, 1
+ if (MI.getOperand(1).getReg() == RISCV::X0 &&
+ MI.getOperand(2).getImm() == 1) {
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ break;
case RISCV::SLTU:
case RISCV::ADD_UW:
// snez rd, zero => li rd, 0
// zext.w rd, zero => li rd, 0
- if (MI.getOperand(1).getReg() == RISCV::X0 && MI.getOperand(2).getReg() == RISCV::X0) {
+ if (MI.getOperand(1).getReg() == RISCV::X0 &&
+ MI.getOperand(2).getReg() == RISCV::X0) {
MI.getOperand(2).ChangeToImmediate(0);
MI.setDesc(get(RISCV::ADDI));
return true;
}
// add.uw rd, zero, rs => addi rd, rs, 0
- if (MI.getOpcode() == RISCV::ADD_UW && MI.getOperand(1).getReg() == RISCV::X0) {
+ if (MI.getOpcode() == RISCV::ADD_UW &&
+ MI.getOperand(1).getReg() == RISCV::X0) {
MI.removeOperand(1);
MI.addOperand(MachineOperand::CreateImm(0));
MI.setDesc(get(RISCV::ADDI));
@@ -4078,7 +4083,7 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
MI.setDesc(get(RISCV::ADDI));
return true;
}
- break;
+ break;
}
return false;
}
>From 8e73913ba442d7e2c695018a315182c9523f0fda Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Thu, 1 May 2025 14:09:42 +0100
Subject: [PATCH 08/18] Consistently avoid use of pseudoinstructions in
comments for transforms
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 28 ++++++++++++------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index b36428beb2e40..c0182cfced3a1 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -3904,7 +3904,7 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
MI.setDesc(get(RISCV::ADDI));
return true;
}
- // xor rd, rs, rs => li rd, 0
+ // xor rd, rs, rs => addi rd, zero, 0
if (MI.getOpcode() == RISCV::XOR &&
MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
MI.getOperand(1).setReg(RISCV::X0);
@@ -3970,7 +3970,7 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
}
break;
case RISCV::ANDI:
- // andi rd, zero, C => li rd, 0
+ // andi rd, zero, C => addi rd, zero, 0
if (MI.getOperand(1).getReg() == RISCV::X0) {
MI.getOperand(2).setImm(0);
MI.setDesc(get(RISCV::ADDI));
@@ -3983,10 +3983,10 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
case RISCV::MULHSU:
case RISCV::MULHU:
case RISCV::MULW:
- // and rd, rs, zero => li rd, 0
- // and rd, zero, rs => li rd, 0
- // mul* rd, rs, zero => li rd, 0
- // mul* rd, zero, rs => li rd, 0
+ // and rd, rs, zero => addi rd, zero, 0
+ // and rd, zero, rs => addi rd, zero, 0
+ // mul* rd, rs, zero => addi rd, zero, 0
+ // mul* rd, zero, rs => addi rd, zero, 0
if (MI.getOperand(1).getReg() == RISCV::X0) {
MI.removeOperand(2);
MI.addOperand(MachineOperand::CreateImm(0));
@@ -4007,7 +4007,7 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
case RISCV::SRLIW:
case RISCV::SRAIW:
case RISCV::SLLI_UW:
- // shiftimm rd, zero, N => li rd, 0
+ // shiftimm rd, zero, N => addi rd, zero, 0
if (MI.getOperand(1).getReg() == RISCV::X0) {
MI.getOperand(2).setImm(0);
MI.setDesc(get(RISCV::ADDI));
@@ -4016,14 +4016,14 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
break;
case RISCV::ORI:
case RISCV::XORI:
- // [x]ori rd, zero, N => li rd, N
+ // [x]ori rd, zero, N => addi rd, zero, N
if (MI.getOperand(1).getReg() == RISCV::X0) {
MI.setDesc(get(RISCV::ADDI));
return true;
}
break;
case RISCV::SLTIU:
- // seqz rd, zero => li rd, 1
+ // sltiu rd, zero, 1 => addi rd, zero, 1
if (MI.getOperand(1).getReg() == RISCV::X0 &&
MI.getOperand(2).getImm() == 1) {
MI.setDesc(get(RISCV::ADDI));
@@ -4032,8 +4032,8 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
break;
case RISCV::SLTU:
case RISCV::ADD_UW:
- // snez rd, zero => li rd, 0
- // zext.w rd, zero => li rd, 0
+ // sltu rd, zero, zero => addi rd, zero, 0
+ // add.uw rd, zero, zero => addi rd, zero, 0
if (MI.getOperand(1).getReg() == RISCV::X0 &&
MI.getOperand(2).getReg() == RISCV::X0) {
MI.getOperand(2).ChangeToImmediate(0);
@@ -4052,8 +4052,8 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
case RISCV::SEXT_B:
case RISCV::ZEXT_H_RV32:
case RISCV::ZEXT_H_RV64:
- // sext.[hb] rd, zero => li rd, 0
- // zext.h rd, zero => li rd, 0
+ // sext.[hb] rd, zero => addi rd, zero, 0
+ // zext.h rd, zero => addi rd, zero, 0
if (MI.getOperand(1).getReg() == RISCV::X0) {
MI.addOperand(MachineOperand::CreateImm(0));
MI.setDesc(get(RISCV::ADDI));
@@ -4066,7 +4066,7 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
case RISCV::SLLW:
case RISCV::SRLW:
case RISCV::SRAW:
- // shift rd, zero, rs => li rd, 0
+ // shift rd, zero, rs => addi rd, zero, 0
if (MI.getOperand(1).getReg() == RISCV::X0) {
MI.getOperand(2).ChangeToImmediate(0);
MI.setDesc(get(RISCV::ADDI));
>From 1c8715d84373ddf2031fd8cb2a0c968b0aa5bce0 Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Thu, 1 May 2025 15:49:36 +0100
Subject: [PATCH 09/18] Pull optimizeInstruction call outside of loop
---
llvm/lib/CodeGen/MachineCopyPropagation.cpp | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
index 6f1e6e46eef8b..79036362c31ad 100644
--- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp
+++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
@@ -867,15 +867,14 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
make_range(Copy->getIterator(), std::next(MI.getIterator())))
KMI.clearRegisterKills(CopySrcReg, TRI);
- // Attempt to canonicalize/optimize the instruction now its arguments have
- // been mutated.
- if (TII->optimizeInstruction(MI)) {
- LLVM_DEBUG(dbgs() << "MCP: After optimizeInstruction: " << MI << "\n");
- }
-
++NumCopyForwards;
Changed = true;
}
+ // Attempt to canonicalize/optimize the instruction now its arguments have
+ // been mutated.
+ if (TII->optimizeInstruction(MI)) {
+ LLVM_DEBUG(dbgs() << "MCP: After optimizeInstruction: " << MI << "\n");
+ }
}
void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
>From 825b1f6b1e7203d8a6fba2ea855e23c44b4acc89 Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Thu, 1 May 2025 15:55:17 +0100
Subject: [PATCH 10/18] Simplify and/mul* case as suggested in review
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 12 +++---------
1 file changed, 3 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index c0182cfced3a1..aca87c85abce5 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -3987,15 +3987,9 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
// and rd, zero, rs => addi rd, zero, 0
// mul* rd, rs, zero => addi rd, zero, 0
// mul* rd, zero, rs => addi rd, zero, 0
- if (MI.getOperand(1).getReg() == RISCV::X0) {
- MI.removeOperand(2);
- MI.addOperand(MachineOperand::CreateImm(0));
- MI.setDesc(get(RISCV::ADDI));
- return true;
- }
- if (MI.getOperand(2).getReg() == RISCV::X0) {
- MI.removeOperand(1);
- MI.addOperand(MachineOperand::CreateImm(0));
+ if (MI.getOperand(1).getReg() == RISCV::X0 || MI.getOperand(2).getReg() == RISCV::X0) {
+ MI.getOperand(1).setReg(RISCV::X0);
+ MI.getOperand(2).ChangeToImmediate(0);
MI.setDesc(get(RISCV::ADDI));
return true;
}
>From 9500cee2d3c349370afb66781c67a96d879fe935 Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Thu, 1 May 2025 16:00:21 +0100
Subject: [PATCH 11/18] Re-order instructions in switch
reg-reg and reg-imm forms are now close to each other. In general we
handle the mv-like transforms first, then the loadimm ones.
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 90 ++++++++++++------------
1 file changed, 45 insertions(+), 45 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index aca87c85abce5..fe1ee7425ef94 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -3913,15 +3913,11 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
return true;
}
break;
- case RISCV::ADDW:
- // Normalize:
- // addw rd, zero, rs => addw rd, rs, zero
- if (MI.getOperand(1).getReg() == RISCV::X0)
- commuteInstruction(MI);
- // addw rd, rs, zero => addiw rd, rs, 0
- if (MI.getOperand(2).getReg() == RISCV::X0) {
- MI.getOperand(2).ChangeToImmediate(0);
- MI.setDesc(get(RISCV::ADDIW));
+ case RISCV::ORI:
+ case RISCV::XORI:
+ // [x]ori rd, zero, N => addi rd, zero, N
+ if (MI.getOperand(1).getReg() == RISCV::X0) {
+ MI.setDesc(get(RISCV::ADDI));
return true;
}
break;
@@ -3941,6 +3937,18 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
return true;
}
break;
+ case RISCV::ADDW:
+ // Normalize:
+ // addw rd, zero, rs => addw rd, rs, zero
+ if (MI.getOperand(1).getReg() == RISCV::X0)
+ commuteInstruction(MI);
+ // addw rd, rs, zero => addiw rd, rs, 0
+ if (MI.getOperand(2).getReg() == RISCV::X0) {
+ MI.getOperand(2).ChangeToImmediate(0);
+ MI.setDesc(get(RISCV::ADDIW));
+ return true;
+ }
+ break;
case RISCV::SH1ADD:
case RISCV::SH1ADD_UW:
case RISCV::SH2ADD:
@@ -3969,14 +3977,6 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
return true;
}
break;
- case RISCV::ANDI:
- // andi rd, zero, C => addi rd, zero, 0
- if (MI.getOperand(1).getReg() == RISCV::X0) {
- MI.getOperand(2).setImm(0);
- MI.setDesc(get(RISCV::ADDI));
- return true;
- }
- break;
case RISCV::AND:
case RISCV::MUL:
case RISCV::MULH:
@@ -3994,32 +3994,37 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
return true;
}
break;
- case RISCV::SLLI:
- case RISCV::SRLI:
- case RISCV::SRAI:
- case RISCV::SLLIW:
- case RISCV::SRLIW:
- case RISCV::SRAIW:
- case RISCV::SLLI_UW:
- // shiftimm rd, zero, N => addi rd, zero, 0
+ case RISCV::ANDI:
+ // andi rd, zero, C => addi rd, zero, 0
if (MI.getOperand(1).getReg() == RISCV::X0) {
MI.getOperand(2).setImm(0);
MI.setDesc(get(RISCV::ADDI));
return true;
}
break;
- case RISCV::ORI:
- case RISCV::XORI:
- // [x]ori rd, zero, N => addi rd, zero, N
+ case RISCV::SLL:
+ case RISCV::SRL:
+ case RISCV::SRA:
+ case RISCV::SLLW:
+ case RISCV::SRLW:
+ case RISCV::SRAW:
+ // shift rd, zero, rs => addi rd, zero, 0
if (MI.getOperand(1).getReg() == RISCV::X0) {
+ MI.getOperand(2).ChangeToImmediate(0);
MI.setDesc(get(RISCV::ADDI));
return true;
}
break;
- case RISCV::SLTIU:
- // sltiu rd, zero, 1 => addi rd, zero, 1
- if (MI.getOperand(1).getReg() == RISCV::X0 &&
- MI.getOperand(2).getImm() == 1) {
+ case RISCV::SLLI:
+ case RISCV::SRLI:
+ case RISCV::SRAI:
+ case RISCV::SLLIW:
+ case RISCV::SRLIW:
+ case RISCV::SRAIW:
+ case RISCV::SLLI_UW:
+ // shiftimm rd, zero, N => addi rd, zero, 0
+ if (MI.getOperand(1).getReg() == RISCV::X0) {
+ MI.getOperand(2).setImm(0);
MI.setDesc(get(RISCV::ADDI));
return true;
}
@@ -4042,6 +4047,14 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
MI.setDesc(get(RISCV::ADDI));
}
break;
+ case RISCV::SLTIU:
+ // sltiu rd, zero, 1 => addi rd, zero, 1
+ if (MI.getOperand(1).getReg() == RISCV::X0 &&
+ MI.getOperand(2).getImm() == 1) {
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ break;
case RISCV::SEXT_H:
case RISCV::SEXT_B:
case RISCV::ZEXT_H_RV32:
@@ -4054,19 +4067,6 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
return true;
}
break;
- case RISCV::SLL:
- case RISCV::SRL:
- case RISCV::SRA:
- case RISCV::SLLW:
- case RISCV::SRLW:
- case RISCV::SRAW:
- // shift rd, zero, rs => addi rd, zero, 0
- if (MI.getOperand(1).getReg() == RISCV::X0) {
- MI.getOperand(2).ChangeToImmediate(0);
- MI.setDesc(get(RISCV::ADDI));
- return true;
- }
- break;
case RISCV::MIN:
case RISCV::MINU:
case RISCV::MAX:
>From bb9e2c19f1416ed13fcae590aa4640a3fbb3c9c5 Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Thu, 1 May 2025 16:34:37 +0100
Subject: [PATCH 12/18] clang-format
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index fe1ee7425ef94..d83215926dd85 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -3987,7 +3987,8 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
// and rd, zero, rs => addi rd, zero, 0
// mul* rd, rs, zero => addi rd, zero, 0
// mul* rd, zero, rs => addi rd, zero, 0
- if (MI.getOperand(1).getReg() == RISCV::X0 || MI.getOperand(2).getReg() == RISCV::X0) {
+ if (MI.getOperand(1).getReg() == RISCV::X0 ||
+ MI.getOperand(2).getReg() == RISCV::X0) {
MI.getOperand(1).setReg(RISCV::X0);
MI.getOperand(2).ChangeToImmediate(0);
MI.setDesc(get(RISCV::ADDI));
>From 3f2049f1c2cf6b3489cf8c64f3d4174e27ab46d4 Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Tue, 6 May 2025 10:49:59 +0100
Subject: [PATCH 13/18] reorder comment to match code logic
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index d83215926dd85..2b4fbc597cb58 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -3983,10 +3983,10 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
case RISCV::MULHSU:
case RISCV::MULHU:
case RISCV::MULW:
- // and rd, rs, zero => addi rd, zero, 0
// and rd, zero, rs => addi rd, zero, 0
- // mul* rd, rs, zero => addi rd, zero, 0
// mul* rd, zero, rs => addi rd, zero, 0
+ // and rd, rs, zero => addi rd, zero, 0
+ // mul* rd, rs, zero => addi rd, zero, 0
if (MI.getOperand(1).getReg() == RISCV::X0 ||
MI.getOperand(2).getReg() == RISCV::X0) {
MI.getOperand(1).setReg(RISCV::X0);
>From 47ca1a037c55a62d217a7062168a266fa7d4e58a Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Tue, 6 May 2025 10:57:49 +0100
Subject: [PATCH 14/18] generalise sltiu check to any non-zero immediate
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 5 +++--
.../RISCV/machine-copyprop-optimizeinstr.mir | 13 ++++++++++++-
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 2b4fbc597cb58..b75bf4371135d 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -4049,9 +4049,10 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
}
break;
case RISCV::SLTIU:
- // sltiu rd, zero, 1 => addi rd, zero, 1
+ // sltiu rd, zero, NZC => addi rd, zero, 1
if (MI.getOperand(1).getReg() == RISCV::X0 &&
- MI.getOperand(2).getImm() == 1) {
+ MI.getOperand(2).getImm() != 0) {
+ MI.getOperand(2).setImm(1);
MI.setDesc(get(RISCV::ADDI));
return true;
}
diff --git a/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir b/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir
index 25df833913bda..e5dd95b17943c 100644
--- a/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir
+++ b/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir
@@ -483,7 +483,18 @@ body: |
; CHECK: renamable $x10 = ADDI $x0, 1
; CHECK-NEXT: PseudoRET implicit $x10
renamable $x11 = COPY $x0
- renamable $x10 = SLTIU renamable $x11, 1
+ renamable $x10 = SLTIU renamable $x11, 2
+ PseudoRET implicit $x10
+...
+---
+name: sltiu_noopt
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sltiu_noopt
+ ; CHECK: renamable $x10 = SLTIU $x0, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x0
+ renamable $x10 = SLTIU renamable $x11, 0
PseudoRET implicit $x10
...
---
>From ff42dca7fbd09cc73d622757946ca894d54f9633 Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Tue, 6 May 2025 14:31:48 +0100
Subject: [PATCH 15/18] Add sll/srl/sra mv-like case
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 15 ++++++-
.../RISCV/machine-copyprop-optimizeinstr.mir | 45 ++++++++++++++++---
2 files changed, 53 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index b75bf4371135d..e44af9a77add3 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -4006,10 +4006,23 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
case RISCV::SLL:
case RISCV::SRL:
case RISCV::SRA:
+ // shift rd, zero, rs => addi rd, zero, 0
+ if (MI.getOperand(1).getReg() == RISCV::X0) {
+ MI.getOperand(2).ChangeToImmediate(0);
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ // shift rd, rs, zero => addi rd, rs, 0
+ if (MI.getOperand(2).getReg() == RISCV::X0) {
+ MI.getOperand(2).ChangeToImmediate(0);
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ break;
case RISCV::SLLW:
case RISCV::SRLW:
case RISCV::SRAW:
- // shift rd, zero, rs => addi rd, zero, 0
+ // shiftw rd, zero, rs => addi rd, zero, 0
if (MI.getOperand(1).getReg() == RISCV::X0) {
MI.getOperand(2).ChangeToImmediate(0);
MI.setDesc(get(RISCV::ADDI));
diff --git a/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir b/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir
index e5dd95b17943c..677bd0ec8d84b 100644
--- a/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir
+++ b/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir
@@ -575,10 +575,10 @@ body: |
PseudoRET implicit $x10
...
---
-name: sll
+name: sll1
body: |
bb.0:
- ; CHECK-LABEL: name: sll
+ ; CHECK-LABEL: name: sll1
; CHECK: renamable $x10 = ADDI $x0, 0
; CHECK-NEXT: PseudoRET implicit $x10
renamable $x11 = COPY $x12
@@ -586,10 +586,21 @@ body: |
PseudoRET implicit $x10
...
---
-name: srl
+name: sll2
body: |
bb.0:
- ; CHECK-LABEL: name: srl
+ ; CHECK-LABEL: name: sll2
+ ; CHECK: renamable $x10 = ADDI $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SLL renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: sr11
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sr11
; CHECK: renamable $x10 = ADDI $x0, 0
; CHECK-NEXT: PseudoRET implicit $x10
renamable $x11 = COPY $x12
@@ -597,10 +608,21 @@ body: |
PseudoRET implicit $x10
...
---
-name: sra
+name: sr12
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sr12
+ ; CHECK: renamable $x10 = ADDI $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SRL renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
+name: sra1
body: |
bb.0:
- ; CHECK-LABEL: name: sra
+ ; CHECK-LABEL: name: sra1
; CHECK: renamable $x10 = ADDI $x0, 0
; CHECK-NEXT: PseudoRET implicit $x10
renamable $x11 = COPY $x12
@@ -608,6 +630,17 @@ body: |
PseudoRET implicit $x10
...
---
+name: sra2
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: sra2
+ ; CHECK: renamable $x10 = ADDI $x12, 0
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ renamable $x11 = COPY $x12
+ renamable $x10 = SRA renamable $x11, $x0
+ PseudoRET implicit $x10
+...
+---
name: sllw
body: |
bb.0:
>From dc4b2e5ed21f3a003536da2740ee847230b4b75a Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Tue, 6 May 2025 14:45:37 +0100
Subject: [PATCH 16/18] handle sltiu rd, zero, 0
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 6 +++---
.../CodeGen/RISCV/machine-copyprop-optimizeinstr.mir | 10 +++++-----
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index e44af9a77add3..683fa9df4164a 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -4063,9 +4063,9 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
break;
case RISCV::SLTIU:
// sltiu rd, zero, NZC => addi rd, zero, 1
- if (MI.getOperand(1).getReg() == RISCV::X0 &&
- MI.getOperand(2).getImm() != 0) {
- MI.getOperand(2).setImm(1);
+ // sltiu rd, zero, 0 => addi rd, zero, 0
+ if (MI.getOperand(1).getReg() == RISCV::X0) {
+ MI.getOperand(2).setImm(MI.getOperand(2).getImm() != 0);
MI.setDesc(get(RISCV::ADDI));
return true;
}
diff --git a/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir b/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir
index 677bd0ec8d84b..896adec08840a 100644
--- a/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir
+++ b/llvm/test/CodeGen/RISCV/machine-copyprop-optimizeinstr.mir
@@ -476,10 +476,10 @@ body: |
PseudoRET implicit $x10
...
---
-name: sltiu
+name: sltiu1
body: |
bb.0:
- ; CHECK-LABEL: name: sltiu
+ ; CHECK-LABEL: name: sltiu1
; CHECK: renamable $x10 = ADDI $x0, 1
; CHECK-NEXT: PseudoRET implicit $x10
renamable $x11 = COPY $x0
@@ -487,11 +487,11 @@ body: |
PseudoRET implicit $x10
...
---
-name: sltiu_noopt
+name: sltiu2
body: |
bb.0:
- ; CHECK-LABEL: name: sltiu_noopt
- ; CHECK: renamable $x10 = SLTIU $x0, 0
+ ; CHECK-LABEL: name: sltiu2
+ ; CHECK: renamable $x10 = ADDI $x0, 0
; CHECK-NEXT: PseudoRET implicit $x10
renamable $x11 = COPY $x0
renamable $x10 = SLTIU renamable $x11, 0
>From c765d58adccbcc665c55ae718a3ea4a816b5d221 Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Tue, 6 May 2025 14:47:54 +0100
Subject: [PATCH 17/18] Add suggested comments for 'normalize' pre-transforms
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 683fa9df4164a..609f8d6f0fa3c 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -3894,7 +3894,7 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
break;
case RISCV::OR:
case RISCV::XOR:
- // Normalize:
+ // Normalize (so we hit the next if clause).
// [x]or rd, zero, rs => [x]or rd, rs, zero
if (MI.getOperand(1).getReg() == RISCV::X0)
commuteInstruction(MI);
@@ -3938,7 +3938,7 @@ bool RISCVInstrInfo::optimizeInstruction(MachineInstr &MI) const {
}
break;
case RISCV::ADDW:
- // Normalize:
+ // Normalize (so we hit the next if clause).
// addw rd, zero, rs => addw rd, rs, zero
if (MI.getOperand(1).getReg() == RISCV::X0)
commuteInstruction(MI);
>From 3ee7da34e3aa72b65fca859c256b2e8ea14765ec Mon Sep 17 00:00:00 2001
From: Alex Bradbury <asb at igalia.com>
Date: Tue, 6 May 2025 14:48:39 +0100
Subject: [PATCH 18/18] Get rid of redundant newline
---
llvm/lib/CodeGen/MachineCopyPropagation.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
index 79036362c31ad..c0cbb27f9fd2b 100644
--- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp
+++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
@@ -873,7 +873,7 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
// Attempt to canonicalize/optimize the instruction now its arguments have
// been mutated.
if (TII->optimizeInstruction(MI)) {
- LLVM_DEBUG(dbgs() << "MCP: After optimizeInstruction: " << MI << "\n");
+ LLVM_DEBUG(dbgs() << "MCP: After optimizeInstruction: " << MI);
}
}
More information about the llvm-commits
mailing list