[PATCH] D97745: [AVR] Set R31R30 as clobbered after ADJCALLSTACKDOWN

Ayke via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 1 16:30:48 PST 2021


aykevl created this revision.
aykevl added reviewers: dylanmckay, benshi001.
Herald added subscribers: Jim, hiraditya.
aykevl requested review of this revision.
Herald added a project: LLVM.

In most cases, using R31R30 is fine because the call (which always
precedes ADJCALLSTACKDOWN) will clobber R31R30 anyway. However, in some
rare cases the register allocator might insert an instruction between
the call and the ADJCALLSTACKDOWN instruction and expect the register
pair to be live afterwards. I think this happens as a result of
rematerialization. Therefore, to fix this, the instruction needs to have
Defs set to R31R30.

Setting the Defs field does have the effect of making the instruction
look dead, which it certainly is not. This is fixed by setting
hasSideEffects to true.

---

Note that I can only reproduce the bug on a special branch that I'm working on. Maybe it is reproduce outside that branch with some effort. However, because it looks like a potential bug (and because it fixes a TODO) I've decided to create a patch to fix this anyway.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D97745

Files:
  llvm/lib/Target/AVR/AVRInstrInfo.td


Index: llvm/lib/Target/AVR/AVRInstrInfo.td
===================================================================
--- llvm/lib/Target/AVR/AVRInstrInfo.td
+++ llvm/lib/Target/AVR/AVRInstrInfo.td
@@ -364,11 +364,13 @@
                                 "#ADJCALLSTACKDOWN",
                                 [(AVRcallseq_start timm:$amt, timm:$amt2)]>;
 
-  // R31R30 is used to update SP, since it is a scratch reg and this instruction
-  // is placed after the function call then R31R30 should be always free.
-  //let Defs = [R31R30],
-  //Uses = [R31R30] in
-  //:TODO: if we enable this, the pseudo is killed because it looks dead
+  // R31R30 is used to update SP. It is normally free because it is a
+  // call-clobbered register but it is necessary to set it as a def as the
+  // register allocator might use it in rare cases (for rematerialization, it
+  // seems). hasSideEffects needs to be set to true so this instruction isn't
+  // considered dead.
+  let Defs = [R31R30],
+  hasSideEffects=1 in
   def ADJCALLSTACKUP : Pseudo<(outs),
                               (ins i16imm:$amt1, i16imm:$amt2),
                               "#ADJCALLSTACKUP",


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D97745.327318.patch
Type: text/x-patch
Size: 1157 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210302/9399e5d8/attachment.bin>


More information about the llvm-commits mailing list