From d7e92b55de4abce1ba80749e88ebb4c12d616789 Mon Sep 17 00:00:00 2001 From: Dylan McKay Date: Sat, 1 Jun 2019 12:38:56 +0000 Subject: [PATCH] [AVR] Disable register coalescing to the PTRDISPREGS class If we would allow register coalescing on PTRDISPREGS class then register allocator can lock Z register to some virtual register. Larger instructions requiring a memory acces then fail during the register allocation phase since there is no available register to hold a pointer if Y register was already taken for a stack frame. This patch prevents it by keeping Z register spillable. It does it by not allowing coalescer to lock it. Original discussion on https://github.com/avr-rust/rust/issues/128. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362298 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AVR/AVRRegisterInfo.cpp | 15 +++++++++++++++ lib/Target/AVR/AVRRegisterInfo.h | 7 +++++++ test/CodeGen/AVR/PR37143.ll | 6 +++--- test/CodeGen/AVR/store.ll | 4 ++-- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/lib/Target/AVR/AVRRegisterInfo.cpp b/lib/Target/AVR/AVRRegisterInfo.cpp index 8dc31fe066b..0aae34d7dfd 100644 --- a/lib/Target/AVR/AVRRegisterInfo.cpp +++ b/lib/Target/AVR/AVRRegisterInfo.cpp @@ -16,6 +16,7 @@ #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/IR/Function.h" #include "llvm/CodeGen/TargetFrameLowering.h" @@ -272,4 +273,18 @@ void AVRRegisterInfo::splitReg(unsigned Reg, HiReg = getSubReg(Reg, AVR::sub_hi); } +bool AVRRegisterInfo::shouldCoalesce(MachineInstr *MI, + const TargetRegisterClass *SrcRC, + unsigned SubReg, + const TargetRegisterClass *DstRC, + unsigned DstSubReg, + const TargetRegisterClass *NewRC, + LiveIntervals &LIS) const { + if(this->getRegClass(AVR::PTRDISPREGSRegClassID)->hasSubClassEq(NewRC)) { + return false; + } + + return TargetRegisterInfo::shouldCoalesce(MI, SrcRC, SubReg, DstRC, DstSubReg, NewRC, LIS); +} + } // end of namespace llvm diff --git a/lib/Target/AVR/AVRRegisterInfo.h b/lib/Target/AVR/AVRRegisterInfo.h index 2365039dbe3..e8354925fed 100644 --- a/lib/Target/AVR/AVRRegisterInfo.h +++ b/lib/Target/AVR/AVRRegisterInfo.h @@ -55,6 +55,13 @@ public: return true; } + bool shouldCoalesce(MachineInstr *MI, + const TargetRegisterClass *SrcRC, + unsigned SubReg, + const TargetRegisterClass *DstRC, + unsigned DstSubReg, + const TargetRegisterClass *NewRC, + LiveIntervals &LIS) const override; }; } // end namespace llvm diff --git a/test/CodeGen/AVR/PR37143.ll b/test/CodeGen/AVR/PR37143.ll index db157edc22f..72f4a2fd372 100644 --- a/test/CodeGen/AVR/PR37143.ll +++ b/test/CodeGen/AVR/PR37143.ll @@ -1,9 +1,9 @@ ; RUN: llc -mattr=avr6,sram < %s -march=avr | FileCheck %s -; CHECK: ld {{r[0-9]+}}, [[PTR:[YZ]]] +; CHECK: ld {{r[0-9]+}}, [[PTR:[XYZ]]] ; CHECK: ldd {{r[0-9]+}}, [[PTR]]+1 -; CHECK: st [[PTR]], {{r[0-9]+}} -; CHECK: std [[PTR]]+1, {{r[0-9]+}} +; CHECK: st [[PTR2:[XYZ]]], {{r[0-9]+}} +; CHECK: std [[PTR2]]+1, {{r[0-9]+}} define void @load_store_16(i16* nocapture %ptr) local_unnamed_addr #1 { entry: %0 = load i16, i16* %ptr, align 2 diff --git a/test/CodeGen/AVR/store.ll b/test/CodeGen/AVR/store.ll index bad3f61a013..81bad775387 100644 --- a/test/CodeGen/AVR/store.ll +++ b/test/CodeGen/AVR/store.ll @@ -45,9 +45,9 @@ define void @store16disp(i16* %x, i16 %y) { define void @store16nodisp(i16* %x, i16 %y) { ; CHECK-LABEL: store16nodisp: +; CHECK: subi r24, 192 +; CHECK: sbci r25, 255 ; CHECK: movw r30, r24 -; CHECK: subi r30, 192 -; CHECK: sbci r31, 255 ; CHECK: st {{[YZ]}}, r22 ; CHECK: std {{[YZ]}}+1, r23 %arrayidx = getelementptr inbounds i16, i16* %x, i16 32 -- 2.50.1