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 @@ -1473,14 +1473,22 @@ MachineInstr &MI = *MBBI; unsigned OpShift, OpCarry; Register DstReg = MI.getOperand(0).getReg(); - Register ZeroReg = STI.getZeroRegister(); + Register TmpReg = STI.getTmpRegister(); bool DstIsDead = MI.getOperand(0).isDead(); bool DstIsKill = MI.getOperand(1).isKill(); OpShift = AVR::ADDRdRr; OpCarry = AVR::ADCRdRr; + // xor r0, r0 // add r16, r16 - // adc r16, r1 + // adc r16, r0 + + // We clear the temp register other than directly use the zero register, + // due to aykevl's comment in https://reviews.llvm.org/D152063 . + buildMI(MBB, MBBI, AVR::EORRdRr) + .addReg(TmpReg, RegState::Define) + .addReg(TmpReg) + .addReg(TmpReg); // Shift part buildMI(MBB, MBBI, OpShift) @@ -1492,7 +1500,7 @@ auto MIB = buildMI(MBB, MBBI, OpCarry) .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead)) .addReg(DstReg, getKillRegState(DstIsKill)) - .addReg(ZeroReg); + .addReg(TmpReg); MIB->getOperand(3).setIsDead(); // SREG is always dead MIB->getOperand(4).setIsKill(); // SREG is always implicitly killed diff --git a/llvm/test/CodeGen/AVR/pseudo/ROLBrd.mir b/llvm/test/CodeGen/AVR/pseudo/ROLBrd.mir --- a/llvm/test/CodeGen/AVR/pseudo/ROLBrd.mir +++ b/llvm/test/CodeGen/AVR/pseudo/ROLBrd.mir @@ -1,4 +1,6 @@ # RUN: llc -O0 -run-pass=avr-expand-pseudo %s -o - | FileCheck %s +# RUN: llc -O0 -run-pass=avr-expand-pseudo -mattr=+avrtiny %s -o - \ +# RUN: | FileCheck --check-prefix=TINY %s # This test checks the expansion of the 8-bit ROLB (rotate) pseudo instruction. @@ -14,11 +16,17 @@ name: test_rolbrd body: | bb.0.entry: - liveins: $r14 + liveins: $r24 ; CHECK-LABEL: test_rolbrd + ; CHECK: $r0 = EORRdRr $r0, $r0, implicit-def $sreg + ; CHECK-NEXT: $r24 = ADDRdRr killed $r24, killed $r24, implicit-def $sreg + ; CHECK-NEXT: $r24 = ADCRdRr $r24, $r0, implicit-def dead $sreg, implicit killed $sreg - ; CHECK: $r14 = ADDRdRr killed $r14, killed $r14, implicit-def $sreg - ; CHECK-NEXT: $r14 = ADCRdRr $r14, $r1, implicit-def dead $sreg, implicit killed $sreg - $r14 = ROLBRd $r14, implicit-def $sreg + ; TINY-LABEL: test_rolbrd + ; TINY: $r16 = EORRdRr $r16, $r16, implicit-def $sreg + ; TINY-NEXT: $r24 = ADDRdRr killed $r24, killed $r24, implicit-def $sreg + ; TINY-NEXT: $r24 = ADCRdRr $r24, $r16, implicit-def dead $sreg, implicit killed $sreg + + $r24 = ROLBRd $r24, implicit-def $sreg ... diff --git a/llvm/test/CodeGen/AVR/rot.ll b/llvm/test/CodeGen/AVR/rot.ll --- a/llvm/test/CodeGen/AVR/rot.ll +++ b/llvm/test/CodeGen/AVR/rot.ll @@ -1,22 +1,22 @@ -; RUN: llc < %s -march=avr | FileCheck %s +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 +; RUN: llc < %s -mtriple=avr | FileCheck %s ; Bit rotation tests. -; CHECK-LABEL: rol8: define i8 @rol8(i8 %val, i8 %amt) { - ; CHECK: andi r22, 7 - - ; CHECK-NEXT: dec r22 - ; CHECK-NEXT: brmi .LBB0_2 - -; CHECK-NEXT: .LBB0_1: - ; CHECK-NEXT: lsl r24 - ; CHECK-NEXT: adc r24, r1 - ; CHECK-NEXT: dec r22 - ; CHECK-NEXT: brpl .LBB0_1 - -; CHECK-NEXT: .LBB0_2: - ; CHECK-NEXT: ret +; CHECK-LABEL: rol8: +; CHECK: ; %bb.0: +; CHECK-NEXT: andi r22, 7 +; CHECK-NEXT: dec r22 +; CHECK-NEXT: brmi .LBB0_2 +; CHECK-NEXT: .LBB0_1: ; =>This Inner Loop Header: Depth=1 +; CHECK-NEXT: clr r0 +; CHECK-NEXT: lsl r24 +; CHECK-NEXT: adc r24, r0 +; CHECK-NEXT: dec r22 +; CHECK-NEXT: brpl .LBB0_1 +; CHECK-NEXT: .LBB0_2: +; CHECK-NEXT: ret %mod = urem i8 %amt, 8 %inv = sub i8 8, %mod @@ -28,23 +28,20 @@ ret i8 %rotl } - -; CHECK-LABEL: ror8: define i8 @ror8(i8 %val, i8 %amt) { - ; CHECK: andi r22, 7 - - ; CHECK-NEXT: dec r22 - ; CHECK-NEXT: brmi .LBB1_2 - -; CHECK-NEXT: .LBB1_1: - ; CHECK-NEXT: bst r24, 0 - ; CHECK-NEXT: ror r24 - ; CHECK-NEXT: bld r24, 7 - ; CHECK-NEXT: dec r22 - ; CHECK-NEXT: brpl .LBB1_1 - -; CHECK-NEXT: .LBB1_2: - ; CHECK-NEXT: ret +; CHECK-LABEL: ror8: +; CHECK: ; %bb.0: +; CHECK-NEXT: andi r22, 7 +; CHECK-NEXT: dec r22 +; CHECK-NEXT: brmi .LBB1_2 +; CHECK-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; CHECK-NEXT: bst r24, 0 +; CHECK-NEXT: ror r24 +; CHECK-NEXT: bld r24, 7 +; CHECK-NEXT: dec r22 +; CHECK-NEXT: brpl .LBB1_1 +; CHECK-NEXT: .LBB1_2: +; CHECK-NEXT: ret %mod = urem i8 %amt, 8 %inv = sub i8 8, %mod diff --git a/llvm/test/CodeGen/AVR/rotate.ll b/llvm/test/CodeGen/AVR/rotate.ll --- a/llvm/test/CodeGen/AVR/rotate.ll +++ b/llvm/test/CodeGen/AVR/rotate.ll @@ -4,8 +4,9 @@ define i8 @rotl8_1(i8 %x) { ; CHECK-LABEL: rotl8_1: ; CHECK: ; %bb.0: ; %start +; CHECK-NEXT: clr r0 ; CHECK-NEXT: lsl r24 -; CHECK-NEXT: adc r24, r1 +; CHECK-NEXT: adc r24, r0 ; CHECK-NEXT: ret start: %0 = call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 1) @@ -15,12 +16,15 @@ define i8 @rotl8_3(i8 %x) { ; CHECK-LABEL: rotl8_3: ; CHECK: ; %bb.0: ; %start +; CHECK-NEXT: clr r0 ; CHECK-NEXT: lsl r24 -; CHECK-NEXT: adc r24, r1 +; CHECK-NEXT: adc r24, r0 +; CHECK-NEXT: clr r0 ; CHECK-NEXT: lsl r24 -; CHECK-NEXT: adc r24, r1 +; CHECK-NEXT: adc r24, r0 +; CHECK-NEXT: clr r0 ; CHECK-NEXT: lsl r24 -; CHECK-NEXT: adc r24, r1 +; CHECK-NEXT: adc r24, r0 ; CHECK-NEXT: ret start: %0 = call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 3) @@ -30,16 +34,21 @@ define i8 @rotl8_5(i8 %x) { ; CHECK-LABEL: rotl8_5: ; CHECK: ; %bb.0: ; %start +; CHECK-NEXT: clr r0 ; CHECK-NEXT: lsl r24 -; CHECK-NEXT: adc r24, r1 +; CHECK-NEXT: adc r24, r0 +; CHECK-NEXT: clr r0 ; CHECK-NEXT: lsl r24 -; CHECK-NEXT: adc r24, r1 +; CHECK-NEXT: adc r24, r0 +; CHECK-NEXT: clr r0 ; CHECK-NEXT: lsl r24 -; CHECK-NEXT: adc r24, r1 +; CHECK-NEXT: adc r24, r0 +; CHECK-NEXT: clr r0 ; CHECK-NEXT: lsl r24 -; CHECK-NEXT: adc r24, r1 +; CHECK-NEXT: adc r24, r0 +; CHECK-NEXT: clr r0 ; CHECK-NEXT: lsl r24 -; CHECK-NEXT: adc r24, r1 +; CHECK-NEXT: adc r24, r0 ; CHECK-NEXT: ret start: %0 = call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 5) @@ -49,20 +58,27 @@ define i8 @rotl8_7(i8 %x) { ; CHECK-LABEL: rotl8_7: ; CHECK: ; %bb.0: ; %start +; CHECK-NEXT: clr r0 ; CHECK-NEXT: lsl r24 -; CHECK-NEXT: adc r24, r1 +; CHECK-NEXT: adc r24, r0 +; CHECK-NEXT: clr r0 ; CHECK-NEXT: lsl r24 -; CHECK-NEXT: adc r24, r1 +; CHECK-NEXT: adc r24, r0 +; CHECK-NEXT: clr r0 ; CHECK-NEXT: lsl r24 -; CHECK-NEXT: adc r24, r1 +; CHECK-NEXT: adc r24, r0 +; CHECK-NEXT: clr r0 ; CHECK-NEXT: lsl r24 -; CHECK-NEXT: adc r24, r1 +; CHECK-NEXT: adc r24, r0 +; CHECK-NEXT: clr r0 ; CHECK-NEXT: lsl r24 -; CHECK-NEXT: adc r24, r1 +; CHECK-NEXT: adc r24, r0 +; CHECK-NEXT: clr r0 ; CHECK-NEXT: lsl r24 -; CHECK-NEXT: adc r24, r1 +; CHECK-NEXT: adc r24, r0 +; CHECK-NEXT: clr r0 ; CHECK-NEXT: lsl r24 -; CHECK-NEXT: adc r24, r1 +; CHECK-NEXT: adc r24, r0 ; CHECK-NEXT: ret start: %0 = call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 7) @@ -77,8 +93,9 @@ ; CHECK-NEXT: brmi .LBB4_2 ; CHECK-NEXT: .LBB4_1: ; %start ; CHECK-NEXT: ; =>This Inner Loop Header: Depth=1 +; CHECK-NEXT: clr r0 ; CHECK-NEXT: lsl r24 -; CHECK-NEXT: adc r24, r1 +; CHECK-NEXT: adc r24, r0 ; CHECK-NEXT: dec r22 ; CHECK-NEXT: brpl .LBB4_1 ; CHECK-NEXT: .LBB4_2: ; %start