[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:55:35 PDT 2025
================
@@ -3872,6 +3888,206 @@ MachineInstr *RISCVInstrInfo::commuteInstructionImpl(MachineInstr &MI,
#undef CASE_VFMA_OPCODE_VV
#undef CASE_VFMA_SPLATS
+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)
+ 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 => addi rd, zero, 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;
+ 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;
+ 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 => 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:
+ 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
+ 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 => 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
+ if (MI.getOperand(1).getReg() == RISCV::X0) {
+ 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) {
+ MI.setDesc(get(RISCV::ADDI));
+ return true;
+ }
+ break;
+ case RISCV::SLTU:
+ case RISCV::ADD_UW:
+ // 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);
+ 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) {
+ MI.removeOperand(1);
+ MI.addOperand(MachineOperand::CreateImm(0));
+ MI.setDesc(get(RISCV::ADDI));
+ }
+ break;
+ case RISCV::SEXT_H:
+ case RISCV::SEXT_B:
+ case RISCV::ZEXT_H_RV32:
+ case RISCV::ZEXT_H_RV64:
+ // 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));
+ return true;
+ }
+ break;
+ case RISCV::SLL:
+ case RISCV::SRL:
+ case RISCV::SRA:
----------------
asb wrote:
I've added that case. Scanning for this, there is only a single instance in the llvm-test-suite output (an `sll a0, a0, zero` in 7zip-benchmark). But I think it makes sense to be exhaustive for the opcodes that are matched (i.e. if we match an opcode it makes sense to implement all the obvious patterns, even if we skip some opcodes altogether).
https://github.com/llvm/llvm-project/pull/137973
More information about the llvm-commits
mailing list