[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:53:33 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) {
----------------
asb wrote:
Thanks, I'd been checking for snez in my script and just transcribed that into a pattern. But it makes more sense to be more general. I now handle `sltiu rd, zero, NZC` and `sltiu rd, zero, 0` for completeness. Though there are zero instances in current codegen.
https://github.com/llvm/llvm-project/pull/137973
More information about the llvm-commits
mailing list