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 @@ -1394,7 +1394,7 @@ // ldd Rd, P+q // ldd Rd+1, P+q+1 let Constraints = "@earlyclobber $dst" in def LDDWRdPtrQ - : Pseudo<(outs DREGS_WITHOUT_YZ_WORKAROUND + : Pseudo<(outs DREGS : $dst), (ins memri : $memri), diff --git a/llvm/lib/Target/AVR/AVRRegisterInfo.td b/llvm/lib/Target/AVR/AVRRegisterInfo.td --- a/llvm/lib/Target/AVR/AVRRegisterInfo.td +++ b/llvm/lib/Target/AVR/AVRRegisterInfo.td @@ -186,26 +186,6 @@ // allow r30 or r31 as output operands. def DREGSLPM : RegisterClass<"AVR", [i16], 8, (sub DREGS, R31R30)>; -// The 16-bit DREGS register class, excluding the Z pointer register. -// -// This is used by instructions which cause high pointer register -// contention which leads to an assertion in the register allocator. -// -// There is no technical reason why instructions that use this class -// cannot use Z; it's simply a workaround a regalloc bug. -// -// More information can be found in PR39553. -def DREGS_WITHOUT_YZ_WORKAROUND - : RegisterClass<"AVR", [i16], 8, - ( - // Return value and arguments. - add R25R24, R19R18, R21R20, R23R22, - // Scratch registers. - R27R26, - // Callee saved registers. - R17R16, R15R14, R13R12, R11R10, R9R8, R7R6, R5R4, R3R2, - R1R0)>; - // 16-bit register class for immediate instructions. def DLDREGS : RegisterClass<"AVR", [i16], 8, ( diff --git a/llvm/test/CodeGen/AVR/lpmx.ll b/llvm/test/CodeGen/AVR/lpmx.ll --- a/llvm/test/CodeGen/AVR/lpmx.ll +++ b/llvm/test/CodeGen/AVR/lpmx.ll @@ -22,13 +22,12 @@ ; CHECK-O0-NEXT: out 61, r28 ; CHECK-O0-NEXT: std Y+1, r24 ; CHECK-O0-NEXT: std Y+2, r25 -; CHECK-O0-NEXT: ldd r24, Y+1 -; CHECK-O0-NEXT: ldd r25, Y+2 -; CHECK-O0-NEXT: lsl r24 -; CHECK-O0-NEXT: rol r25 -; CHECK-O0-NEXT: subi r24, -lo8(arr0) -; CHECK-O0-NEXT: sbci r25, -hi8(arr0) -; CHECK-O0-NEXT: movw r30, r24 +; CHECK-O0-NEXT: ldd r30, Y+1 +; CHECK-O0-NEXT: ldd r31, Y+2 +; CHECK-O0-NEXT: lsl r30 +; CHECK-O0-NEXT: rol r31 +; CHECK-O0-NEXT: subi r30, -lo8(arr0) +; CHECK-O0-NEXT: sbci r31, -hi8(arr0) ; CHECK-O0-NEXT: lpm r24, Z+ ; CHECK-O0-NEXT: lpm r25, Z ; CHECK-O0-NEXT: adiw r28, 2 @@ -95,11 +94,10 @@ ; CHECK-O0-NEXT: out 61, r28 ; CHECK-O0-NEXT: std Y+1, r24 ; CHECK-O0-NEXT: std Y+2, r25 -; CHECK-O0-NEXT: ldd r24, Y+1 -; CHECK-O0-NEXT: ldd r25, Y+2 -; CHECK-O0-NEXT: subi r24, -lo8(arr1) -; CHECK-O0-NEXT: sbci r25, -hi8(arr1) -; CHECK-O0-NEXT: movw r30, r24 +; CHECK-O0-NEXT: ldd r30, Y+1 +; CHECK-O0-NEXT: ldd r31, Y+2 +; CHECK-O0-NEXT: subi r30, -lo8(arr1) +; CHECK-O0-NEXT: sbci r31, -hi8(arr1) ; CHECK-O0-NEXT: lpm r24, Z ; CHECK-O0-NEXT: adiw r28, 2 ; CHECK-O0-NEXT: in r0, 63