diff --git a/llvm/lib/Target/AVR/AVRISelLowering.h b/llvm/lib/Target/AVR/AVRISelLowering.h --- a/llvm/lib/Target/AVR/AVRISelLowering.h +++ b/llvm/lib/Target/AVR/AVRISelLowering.h @@ -187,6 +187,8 @@ private: MachineBasicBlock *insertShift(MachineInstr &MI, MachineBasicBlock *BB) const; MachineBasicBlock *insertMul(MachineInstr &MI, MachineBasicBlock *BB) const; + MachineBasicBlock *insertCopyR1(MachineInstr &MI, + MachineBasicBlock *BB) const; }; } // end namespace llvm diff --git a/llvm/lib/Target/AVR/AVRISelLowering.cpp b/llvm/lib/Target/AVR/AVRISelLowering.cpp --- a/llvm/lib/Target/AVR/AVRISelLowering.cpp +++ b/llvm/lib/Target/AVR/AVRISelLowering.cpp @@ -1695,6 +1695,18 @@ return BB; } +// Insert a read from R1, which almost always contains the value 0. +MachineBasicBlock * +AVRTargetLowering::insertCopyR1(MachineInstr &MI, MachineBasicBlock *BB) const { + const TargetInstrInfo &TII = *Subtarget.getInstrInfo(); + MachineBasicBlock::iterator I(MI); + BuildMI(*BB, I, MI.getDebugLoc(), TII.get(AVR::COPY)) + .add(MI.getOperand(0)) + .addReg(AVR::R1); + MI.eraseFromParent(); + return BB; +} + MachineBasicBlock * AVRTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const { @@ -1717,6 +1729,8 @@ case AVR::MULRdRr: case AVR::MULSRdRr: return insertMul(MI, MBB); + case AVR::CopyR1: + return insertCopyR1(MI, MBB); } assert((Opc == AVR::Select16 || Opc == AVR::Select8) && diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.td b/llvm/lib/Target/AVR/AVRInstrInfo.td --- a/llvm/lib/Target/AVR/AVRInstrInfo.td +++ b/llvm/lib/Target/AVR/AVRInstrInfo.td @@ -2377,6 +2377,10 @@ : $src, i8 : $cnt))]>; +// lowered to a copy from R1, which contains the value zero. +let usesCustomInserter=1 in +def CopyR1 : Pseudo<(outs GPR8:$rd), (ins), "clrz\t$rd", [(set i8:$rd, 0)]>; + //===----------------------------------------------------------------------===// // Non-Instruction Patterns //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/AVR/smul-with-overflow.ll b/llvm/test/CodeGen/AVR/smul-with-overflow.ll --- a/llvm/test/CodeGen/AVR/smul-with-overflow.ll +++ b/llvm/test/CodeGen/AVR/smul-with-overflow.ll @@ -18,7 +18,7 @@ ; CHECK: ldi [[RET:r[0-9]+]], 1 ; CHECK: cp {{.*}}[[HIGH]], {{.*}}[[LOW]] ; CHECK: brne [[LABEL:.LBB[_0-9]+]] -; CHECK: ldi {{.*}}[[RET]], 0 +; CHECK: mov {{.*}}[[RET]], r1 ; CHECK: {{.*}}[[LABEL]] ; CHECK: ret } diff --git a/llvm/test/CodeGen/AVR/store-undef.ll b/llvm/test/CodeGen/AVR/store-undef.ll --- a/llvm/test/CodeGen/AVR/store-undef.ll +++ b/llvm/test/CodeGen/AVR/store-undef.ll @@ -6,8 +6,7 @@ ; CHECK-LABEL: foo define void @foo() { - ; CHECK: ldi [[SRC:r[0-9]+]], 0 - ; CHECK-NEXT: st [[PTRREG:X|Y|Z]], [[SRC]] + ; CHECK: st [[PTRREG:X|Y|Z]], r1 store i8 0, i8* undef, align 4 ret void } diff --git a/llvm/test/CodeGen/AVR/umul-with-overflow.ll b/llvm/test/CodeGen/AVR/umul-with-overflow.ll --- a/llvm/test/CodeGen/AVR/umul-with-overflow.ll +++ b/llvm/test/CodeGen/AVR/umul-with-overflow.ll @@ -14,7 +14,7 @@ ; CHECK: ldi [[RET:r[0-9]+]], 1 ; CHECK: cpi {{.*}}[[HIGH]], 0 ; CHECK: brne [[LABEL:.LBB[_0-9]+]] -; CHECK: ldi {{.*}}[[RET]], 0 +; CHECK: mov {{.*}}[[RET]], r1 ; CHECK: {{.*}}[[LABEL]] ; CHECK: ret }