diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -70,6 +70,7 @@
   bool expandLogic(unsigned Op, Block &MBB, BlockIt MBBI);
   bool expandLogicImm(unsigned Op, Block &MBB, BlockIt MBBI);
   bool isLogicImmOpRedundant(unsigned Op, unsigned ImmVal) const;
+  bool isLogicRegOpUndef(unsigned Op, unsigned ImmVal) const;
 
   template <typename Func> bool expandAtomic(Block &MBB, BlockIt MBBI, Func f);
 
@@ -226,6 +227,18 @@
   return false;
 }
 
+bool AVRExpandPseudo::isLogicRegOpUndef(unsigned Op, unsigned ImmVal) const {
+  // ANDI Rd, 0x00 clears all input bits.
+  if (Op == AVR::ANDIRdK && ImmVal == 0x00)
+    return true;
+
+  // ORI Rd, 0xff sets all input bits.
+  if (Op == AVR::ORIRdK && ImmVal == 0xff)
+    return true;
+
+  return false;
+}
+
 bool AVRExpandPseudo::expandLogicImm(unsigned Op, Block &MBB, BlockIt MBBI) {
   MachineInstr &MI = *MBBI;
   Register DstLoReg, DstHiReg;
@@ -247,6 +260,9 @@
 
     // SREG is always implicitly dead
     MIBLO->getOperand(3).setIsDead();
+
+    if (isLogicRegOpUndef(Op, Lo8))
+      MIBLO->getOperand(1).setIsUndef(true);
   }
 
   if (!isLogicImmOpRedundant(Op, Hi8)) {
@@ -258,6 +274,9 @@
 
     if (ImpIsDead)
       MIBHI->getOperand(3).setIsDead();
+
+    if (isLogicRegOpUndef(Op, Hi8))
+      MIBHI->getOperand(1).setIsUndef(true);
   }
 
   MI.eraseFromParent();
diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.cpp b/llvm/lib/Target/AVR/AVRInstrInfo.cpp
--- a/llvm/lib/Target/AVR/AVRInstrInfo.cpp
+++ b/llvm/lib/Target/AVR/AVRInstrInfo.cpp
@@ -58,16 +58,21 @@
       TRI.splitReg(DestReg, DestLo, DestHi);
       TRI.splitReg(SrcReg, SrcLo, SrcHi);
 
+      // Emit the copies.
+      // The original instruction was for a register pair, of which only one
+      // register might have been live. Add 'undef' to satisfy the machine
+      // verifier, when subreg liveness is enabled.
+      // TODO: Eliminate these unnecessary copies.
       if (DestLo == SrcHi) {
         BuildMI(MBB, MI, DL, get(AVR::MOVRdRr), DestHi)
-            .addReg(SrcHi, getKillRegState(KillSrc));
+            .addReg(SrcHi, getKillRegState(KillSrc) | RegState::Undef);
         BuildMI(MBB, MI, DL, get(AVR::MOVRdRr), DestLo)
-            .addReg(SrcLo, getKillRegState(KillSrc));
+            .addReg(SrcLo, getKillRegState(KillSrc) | RegState::Undef);
       } else {
         BuildMI(MBB, MI, DL, get(AVR::MOVRdRr), DestLo)
-            .addReg(SrcLo, getKillRegState(KillSrc));
+            .addReg(SrcLo, getKillRegState(KillSrc) | RegState::Undef);
         BuildMI(MBB, MI, DL, get(AVR::MOVRdRr), DestHi)
-            .addReg(SrcHi, getKillRegState(KillSrc));
+            .addReg(SrcHi, getKillRegState(KillSrc) | RegState::Undef);
       }
     }
   } else {
diff --git a/llvm/lib/Target/AVR/AVRSubtarget.h b/llvm/lib/Target/AVR/AVRSubtarget.h
--- a/llvm/lib/Target/AVR/AVRSubtarget.h
+++ b/llvm/lib/Target/AVR/AVRSubtarget.h
@@ -85,6 +85,8 @@
 
   uint8_t getIORegisterOffset() const { return hasMemMappedGPR() ? 0x20 : 0x0; }
 
+  bool enableSubRegLiveness() const override { return true; }
+
   /// Gets the ELF architecture for the e_flags field
   /// of an ELF object file.
   unsigned getELFArch() const {
diff --git a/llvm/test/CodeGen/AVR/hardware-mul.ll b/llvm/test/CodeGen/AVR/hardware-mul.ll
--- a/llvm/test/CodeGen/AVR/hardware-mul.ll
+++ b/llvm/test/CodeGen/AVR/hardware-mul.ll
@@ -18,19 +18,19 @@
 ; CHECK-LABEL: mult16:
 ; CHECK:       ; %bb.0:
 ; CHECK-NEXT:    muls r22, r25
-; CHECK-NEXT:    mov r20, r0
+; CHECK-NEXT:    mov r25, r0
 ; CHECK-NEXT:    clr r1
 ; CHECK-NEXT:    mul r22, r24
-; CHECK-NEXT:    mov r21, r0
+; CHECK-NEXT:    mov r20, r0
 ; CHECK-NEXT:    mov r18, r1
 ; CHECK-NEXT:    clr r1
-; CHECK-NEXT:    add r18, r20
+; CHECK-NEXT:    add r18, r25
 ; CHECK-NEXT:    muls r23, r24
 ; CHECK-NEXT:    clr r1
 ; CHECK-NEXT:    add r18, r0
 ; CHECK-NEXT:    mov r19, r18
 ; CHECK-NEXT:    clr r18
-; CHECK-NEXT:    mov r24, r21
+; CHECK-NEXT:    mov r24, r20
 ; CHECK-NEXT:    clr r25
 ; CHECK-NEXT:    or r24, r18
 ; CHECK-NEXT:    or r25, r19
diff --git a/llvm/test/CodeGen/AVR/inline-asm/inline-asm3.ll b/llvm/test/CodeGen/AVR/inline-asm/inline-asm3.ll
--- a/llvm/test/CodeGen/AVR/inline-asm/inline-asm3.ll
+++ b/llvm/test/CodeGen/AVR/inline-asm/inline-asm3.ll
@@ -227,14 +227,12 @@
 ; CHECK-NEXT:    mov r30, r22
 ; CHECK-NEXT:    mov r22, r24
 ; CHECK-NEXT:    mov r26, r22
-; CHECK-NEXT:    mov r27, r23
 ; CHECK-NEXT:    ;APP
 ; CHECK-NEXT:    mov r26, r26
 ; CHECK-NEXT:    add r26, r30
 ; CHECK-NEXT:    ;NO_APP
-; CHECK-NEXT:    mov r24, r26
-; CHECK-NEXT:    ; kill: def $r22 killed $r22 killed $r23r22
 ; CHECK-NEXT:    mov r20, r30
+; CHECK-NEXT:    mov r24, r26
 ; CHECK-NEXT:    rcall foo8
 ; CHECK-NEXT:    ret
   %3 = tail call i8 asm sideeffect "mov $0, $1\0Aadd $0, $2", "=e,e,e"(i8 %0, i8 %1)
@@ -294,7 +292,6 @@
 ; CHECK-NEXT:    mov r24, r30
 ; CHECK-NEXT:    add r24, r26
 ; CHECK-NEXT:    ;NO_APP
-; CHECK-NEXT:    ; kill: def $r24 killed $r24 killed $r25r24
 ; CHECK-NEXT:    mov r22, r30
 ; CHECK-NEXT:    mov r20, r26
 ; CHECK-NEXT:    rcall foo8
@@ -345,9 +342,6 @@
 ; CHECK-NEXT:    ;NO_APP
 ; CHECK-NEXT:    mov r24, r30
 ; CHECK-NEXT:    mov r25, r31
-; CHECK-NEXT:    ; kill: def $r24 killed $r24 killed $r25r24
-; CHECK-NEXT:    ; kill: def $r22 killed $r22 killed $r23r22
-; CHECK-NEXT:    ; kill: def $r20 killed $r20 killed $r21r20
 ; CHECK-NEXT:    rcall foo8
 ; CHECK-NEXT:    pop r29
 ; CHECK-NEXT:    pop r28