Index: lib/Target/AVR/AVRExpandPseudoInsts.cpp =================================================================== --- lib/Target/AVR/AVRExpandPseudoInsts.cpp +++ lib/Target/AVR/AVRExpandPseudoInsts.cpp @@ -74,6 +74,7 @@ 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 expandLogicImmNeeded(unsigned Op, unsigned ImmVal); template bool expandAtomic(Block &MBB, BlockIt MBBI, Func f); @@ -200,6 +201,16 @@ } bool AVRExpandPseudo:: + expandLogicImmNeeded(unsigned Op, unsigned ImmVal) { + + // ORI Rd, 0x0 is redundant. + if (Op == AVR::ORIRdK && ImmVal == 0x0) + return false; + + return true; +} + +bool AVRExpandPseudo:: expandLogicImm(unsigned Op, Block &MBB, BlockIt MBBI) { MachineInstr &MI = *MBBI; unsigned DstLoReg, DstHiReg; @@ -211,22 +222,31 @@ unsigned Lo8 = Imm & 0xff; unsigned Hi8 = (Imm >> 8) & 0xff; TRI->splitReg(DstReg, DstLoReg, DstHiReg); + bool Expand; - auto MIBLO = buildMI(MBB, MBBI, Op) - .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) - .addReg(DstLoReg, getKillRegState(SrcIsKill)) - .addImm(Lo8); + Expand = expandLogicImmNeeded(Op, Lo8); - // SREG is always implicitly dead - MIBLO->getOperand(3).setIsDead(); + if (Expand) { + auto MIBLO = buildMI(MBB, MBBI, Op) + .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) + .addReg(DstLoReg, getKillRegState(SrcIsKill)) + .addImm(Lo8); - auto MIBHI = buildMI(MBB, MBBI, Op) - .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) - .addReg(DstHiReg, getKillRegState(SrcIsKill)) - .addImm(Hi8); + // SREG is always implicitly dead + MIBLO->getOperand(3).setIsDead(); + } - if (ImpIsDead) - MIBHI->getOperand(3).setIsDead(); + Expand = expandLogicImmNeeded(Op, Hi8); + + if (Expand) { + auto MIBHI = buildMI(MBB, MBBI, Op) + .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) + .addReg(DstHiReg, getKillRegState(SrcIsKill)) + .addImm(Hi8); + + if (ImpIsDead) + MIBHI->getOperand(3).setIsDead(); + } MI.eraseFromParent(); return true; Index: test/CodeGen/AVR/PR31344.ll =================================================================== --- /dev/null +++ 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 +} Index: test/CodeGen/AVR/integration/blink.ll =================================================================== --- test/CodeGen/AVR/integration/blink.ll +++ test/CodeGen/AVR/integration/blink.ll @@ -40,8 +40,7 @@ ; 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 @@ ; 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