diff --git a/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/lib/Target/AVR/AVRExpandPseudoInsts.cpp index 36f24a2b4ae..65a58cd31c3 100644 --- a/lib/Target/AVR/AVRExpandPseudoInsts.cpp +++ b/lib/Target/AVR/AVRExpandPseudoInsts.cpp @@ -74,6 +74,7 @@ private: bool expandArith(unsigned OpLo, unsigned OpHi, Block &MBB, BlockIt MBBI); bool expandLogic(unsigned Op, Block &MBB, BlockIt MBBI); bool expandLogicImm(unsigned Op, Block &MBB, BlockIt MBBI); + bool isLogicImmOpRedundant(unsigned Op, unsigned ImmVal) const; template bool expandAtomic(Block &MBB, BlockIt MBBI, Func f); @@ -199,6 +200,16 @@ expandLogic(unsigned Op, Block &MBB, BlockIt MBBI) { return true; } +bool AVRExpandPseudo:: + isLogicImmOpRedundant(unsigned Op, unsigned ImmVal) const { + + // ORI Rd, 0x0 is redundant. + if (Op == AVR::ORIRdK && ImmVal == 0x0) + return true; + + return false; +} + bool AVRExpandPseudo:: expandLogicImm(unsigned Op, Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; @@ -212,21 +223,25 @@ expandLogicImm(unsigned Op, Block &MBB, BlockIt MBBI) { unsigned Hi8 = (Imm >> 8) & 0xff; TRI->splitReg(DstReg, DstLoReg, DstHiReg); - auto MIBLO = buildMI(MBB, MBBI, Op) - .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) - .addReg(DstLoReg, getKillRegState(SrcIsKill)) - .addImm(Lo8); + if (!isLogicImmOpRedundant(Op, Lo8)) { + auto MIBLO = buildMI(MBB, MBBI, Op) + .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) + .addReg(DstLoReg, getKillRegState(SrcIsKill)) + .addImm(Lo8); - // SREG is always implicitly dead - MIBLO->getOperand(3).setIsDead(); + // SREG is always implicitly dead + MIBLO->getOperand(3).setIsDead(); + } - auto MIBHI = buildMI(MBB, MBBI, Op) - .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) - .addReg(DstHiReg, getKillRegState(SrcIsKill)) - .addImm(Hi8); + if (!isLogicImmOpRedundant(Op, Hi8)) { + auto MIBHI = buildMI(MBB, MBBI, Op) + .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) + .addReg(DstHiReg, getKillRegState(SrcIsKill)) + .addImm(Hi8); - if (ImpIsDead) - MIBHI->getOperand(3).setIsDead(); + if (ImpIsDead) + MIBHI->getOperand(3).setIsDead(); + } MI.eraseFromParent(); return true; diff --git a/test/CodeGen/AVR/PR31344.ll b/test/CodeGen/AVR/PR31344.ll new file mode 100644 index 00000000000..1e7bdb1370f --- /dev/null +++ b/test/CodeGen/AVR/PR31344.ll @@ -0,0 +1,35 @@ +; RUN: llc < %s -march=avr | FileCheck %s + +; Unit test for: PR 31344 + +define i16 @or16_reg_imm_0xff00(i16 %a) { +; CHECK-LABEL: or16_reg_imm_0xff00 +; CHECK-NOT: ori {{r[0-9]+}}, 0 +; CHECK: ori {{r[0-9]+}}, 255 + %result = or i16 %a, 65280 + ret i16 %result +} + +define i16 @or16_reg_imm_0xffb3(i16 %a) { +; CHECK-LABEL: or16_reg_imm_0xffb3 +; CHECK: ori {{r[0-9]+}}, 179 +; CHECK: ori {{r[0-9]+}}, 255 + %result = or i16 %a, 65459 + ret i16 %result +} + +define i16 @or16_reg_imm_0x00ff(i16 %a) { +; CHECK-LABEL: or16_reg_imm_0x00ff +; CHECK: ori {{r[0-9]+}}, 255 +; CHECK-NOT: ori {{r[0-9]+}}, 0 + %result = or i16 %a, 255 + ret i16 %result +} + +define i16 @or16_reg_imm_0xb3ff(i16 %a) { +; CHECK-LABEL: or16_reg_imm_0xb3ff +; CHECK: ori {{r[0-9]+}}, 255 +; CHECK: ori {{r[0-9]+}}, 179 + %result = or i16 %a, 46079 + ret i16 %result +} diff --git a/test/CodeGen/AVR/integration/blink.ll b/test/CodeGen/AVR/integration/blink.ll index 66c62020bf7..ef88e3ea24b 100644 --- a/test/CodeGen/AVR/integration/blink.ll +++ b/test/CodeGen/AVR/integration/blink.ll @@ -40,8 +40,7 @@ entry: ; CHECK: in [[TMPREG:r[0-9]+]], 4 ; CHECK-NEXT: ori [[TMPREG]], 32 - ; This next line is unnecessary, but we CodeGen it anyway. We should probably optimize this out (PR31344). - ; CHECK-NEXT: ori {{r[0-9]+}}, 0 + ; CHECK-NOT: ori {{r[0-9]+}}, 0 ; CHECK-NEXT: out 4, [[TMPREG]] ; CHECK-NEXT: ret @@ -65,8 +64,7 @@ entry: ; CHECK: in [[TMPREG:r[0-9]+]], 5 ; CHECK-NEXT: ori [[TMPREG]], 32 - ; This next line is unnecessary, but we CodeGen it anyway. We should probably optimize this out (PR31344). - ; CHECK-NEXT: ori {{r[0-9]+}}, 0 + ; CHECK-NOT: ori {{r[0-9]+}}, 0 ; CHECK-NEXT: out 5, [[TMPREG]] ; CHECK-NEXT: ret