[llvm] 245e25f - AMDGPU: Implement isAsmClobberable

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 2 11:20:16 PST 2022


Author: Matt Arsenault
Date: 2022-02-02T14:20:12-05:00
New Revision: 245e25f9c3b4273ee77f5d066ef8b8526f881b69

URL: https://github.com/llvm/llvm-project/commit/245e25f9c3b4273ee77f5d066ef8b8526f881b69
DIFF: https://github.com/llvm/llvm-project/commit/245e25f9c3b4273ee77f5d066ef8b8526f881b69.diff

LOG: AMDGPU: Implement isAsmClobberable

Warn on inline assembly clobbering reserved registers. It should also
warn on at least some reserved register defs, but that isn't happening
right now. If you have a def and re-use of a register we reserve, the
register coalescer will eliminate the intermediate virtual
register. When the reserved reg def is introduced later by the
backend, it will end up clobbering the value the register coalescer
assumed was live through the range.

There is also isInlineAsmReadOnlyReg, although I don't understand what
the distinction really is. It's called in SelectionDAGBuilder, long
before the set of reserved registers is frozen so I'm not sure how
that can possibly work reliably.

Unfortunately this is also using the ugly tablegenerated names for the
registers.

Added: 
    llvm/test/CodeGen/AMDGPU/inline-asm-reserved-regs.ll

Modified: 
    llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
    llvm/lib/Target/AMDGPU/SIRegisterInfo.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
index 21aed4ececb57..3c2f07e91b261 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
@@ -690,6 +690,11 @@ BitVector SIRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
   return Reserved;
 }
 
+bool SIRegisterInfo::isAsmClobberable(const MachineFunction &MF,
+                                      MCRegister PhysReg) const {
+  return !MF.getRegInfo().isReserved(PhysReg);
+}
+
 bool SIRegisterInfo::shouldRealignStack(const MachineFunction &MF) const {
   const SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>();
   // On entry, the base address is 0, so it can't possibly need any more

diff  --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.h b/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
index f1fe0a1d93291..1035fb735d37f 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
@@ -64,6 +64,8 @@ class SIRegisterInfo final : public AMDGPUGenRegisterInfo {
   MCRegister reservedPrivateSegmentBufferReg(const MachineFunction &MF) const;
 
   BitVector getReservedRegs(const MachineFunction &MF) const override;
+  bool isAsmClobberable(const MachineFunction &MF,
+                        MCRegister PhysReg) const override;
 
   const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
   const MCPhysReg *getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;

diff  --git a/llvm/test/CodeGen/AMDGPU/inline-asm-reserved-regs.ll b/llvm/test/CodeGen/AMDGPU/inline-asm-reserved-regs.ll
new file mode 100644
index 0000000000000..9776e39d11403
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/inline-asm-reserved-regs.ll
@@ -0,0 +1,52 @@
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -verify-machineinstrs -o /dev/null 2>&1 %s | FileCheck -check-prefix=ERR %s
+
+; ERR: warning: inline asm clobber list contains reserved registers: VGPR42
+; ERR: note: Reserved registers on the clobber list may not be preserved across the asm statement, and clobbering them may lead to undefined behaviour.
+define amdgpu_kernel void @clobber_occupancy_limited_vgpr() #0 {
+entry:
+  call void asm sideeffect "; clobber $0", "~{v42}"()
+  ret void
+}
+
+; ERR: warning: inline asm clobber list contains reserved registers: VGPR42_VGPR43
+; ERR: note: Reserved registers on the clobber list may not be preserved across the asm statement, and clobbering them may lead to undefined behaviour.
+define amdgpu_kernel void @clobber_occupancy_limited_vgpr64() #0 {
+entry:
+  call void asm sideeffect "; clobber $0", "~{v[42:43]}"()
+  ret void
+}
+
+; ERR: warning: inline asm clobber list contains reserved registers: M0
+; ERR: note: Reserved registers on the clobber list may not be preserved across the asm statement, and clobbering them may lead to undefined behaviour.
+define amdgpu_kernel void @clobber_m0() {
+entry:
+  call void asm sideeffect "; clobber $0", "~{m0}"()
+  ret void
+}
+
+; ERR: warning: inline asm clobber list contains reserved registers: EXEC
+; ERR: note: Reserved registers on the clobber list may not be preserved across the asm statement, and clobbering them may lead to undefined behaviour.
+define amdgpu_kernel void @clobber_exec() {
+entry:
+  call void asm sideeffect "; clobber $0", "~{exec}"()
+  ret void
+}
+
+; ERR: warning: inline asm clobber list contains reserved registers: EXEC_LO
+; ERR: note: Reserved registers on the clobber list may not be preserved across the asm statement, and clobbering them may lead to undefined behaviour.
+define amdgpu_kernel void @clobber_exec_lo() {
+entry:
+  call void asm sideeffect "; clobber $0", "~{exec_lo}"()
+  ret void
+}
+
+; FIXME: This should warn too
+; ERR-NOT: warning
+define amdgpu_kernel void @def_exec(i64 addrspace(1)* %ptr) {
+entry:
+  %exec = call i64 asm sideeffect "; def $0", "={exec}"()
+  store i64 %exec, i64 addrspace(1)* %ptr
+  ret void
+}
+
+attributes #0 = { "amdgpu-waves-per-eu"="10,10" }


        


More information about the llvm-commits mailing list