Page MenuHomePhabricator

[AVR] Fix the eliminateCallFramePseudos method so that it always expands STDWSPQRr and STDSPQRr
Needs RevisionPublic

Authored by dylanmckay on Jan 28 2021, 10:34 PM.



Before this bug was fixed, the newly added testcase would fail with the message:

LLVM ERROR: Not supported instr: <MCInst XXX <MCOperand Reg:1> <MCOperand Imm:15> <MCOperand Reg:53>>

  where XXX is the OpCode of either the STDWSPQRr instruction or the STDSPQRr instruction.

The issue was that the ISel lowering pass would lower many stack slot stores to these
instructions, but the frame pointer elimination code (that is designed to rewrite these two
instructions to real instructions) was only designed to run for STDWSPQRr/STDSPQRr instructions
that appeared in the basic blocks that contained the FrameSetup/FrameDestroy instructions.

The bug was fixed by modifying the code so that it unconditionally runs on STDWSPQRr/STDSPQRr
instructions and always expands them with the relevant STDWPtrQRr or STDPtrQRr instructions.

The bug is fixed by making the TargetInstrInfo::{isFrameInstr(), getFrameSize()} methods
virtual, and overriding them in the AVR backend. The LLVM middle end now
treats STDWSPQRr/STDSPQRr instructions as zero-sized frame instructions
so that they get the same treatment and are rewritten during call frame
pseudo elimination process, which is the one time we have enough
information to correctly rewrite STDWSPQRr/STDSPQRr operations to the stack

This bug was originally discovered due to the Rust compiler_builtins library. Its 0.1.37 release
contained a 128-bit software division/remainder routine that exercised this buggy branch in the code.

Diff Detail

Unit TestsFailed

50 msx64 debian > LLVM.CodeGen/AVR::call.ll
Script: -- : 'RUN: at line 1'; /mnt/disks/ssd0/agent/llvm-project/build/bin/llc < /mnt/disks/ssd0/agent/llvm-project/llvm/test/CodeGen/AVR/call.ll -march=avr -mattr=avr6 | /mnt/disks/ssd0/agent/llvm-project/build/bin/FileCheck /mnt/disks/ssd0/agent/llvm-project/llvm/test/CodeGen/AVR/call.ll
20 msx64 debian > LLVM.CodeGen/AVR::dynalloca.ll
Script: -- : 'RUN: at line 1'; /mnt/disks/ssd0/agent/llvm-project/build/bin/llc < /mnt/disks/ssd0/agent/llvm-project/llvm/test/CodeGen/AVR/dynalloca.ll -march=avr | /mnt/disks/ssd0/agent/llvm-project/build/bin/FileCheck /mnt/disks/ssd0/agent/llvm-project/llvm/test/CodeGen/AVR/dynalloca.ll
40 msx64 debian > LLVM.CodeGen/AVR::varargs.ll
Script: -- : 'RUN: at line 1'; /mnt/disks/ssd0/agent/llvm-project/build/bin/llc -mattr=sram,movw,addsubiw < /mnt/disks/ssd0/agent/llvm-project/llvm/test/CodeGen/AVR/varargs.ll -march=avr | /mnt/disks/ssd0/agent/llvm-project/build/bin/FileCheck /mnt/disks/ssd0/agent/llvm-project/llvm/test/CodeGen/AVR/varargs.ll
70 msx64 debian > Polly.ScopInfo::user_provided_assumptions.ll
Script: -- : 'RUN: at line 1'; opt -polly-process-unprofitable -polly-remarks-minimal -polly-use-llvm-names -polly-import-jscop-dir=/mnt/disks/ssd0/agent/llvm-project/polly/test/ScopInfo -polly-codegen-verify -pass-remarks-analysis="polly-scops" -polly-scops -disable-output < /mnt/disks/ssd0/agent/llvm-project/polly/test/ScopInfo/user_provided_assumptions.ll 2>&1 | FileCheck /mnt/disks/ssd0/agent/llvm-project/polly/test/ScopInfo/user_provided_assumptions.ll
70 msx64 windows > LLVM.CodeGen/AVR::call.ll
Script: -- : 'RUN: at line 1'; c:\ws\w16-1\llvm-project\premerge-checks\build\bin\llc.exe < C:\ws\w16-1\llvm-project\premerge-checks\llvm\test\CodeGen\AVR\call.ll -march=avr -mattr=avr6 | c:\ws\w16-1\llvm-project\premerge-checks\build\bin\filecheck.exe C:\ws\w16-1\llvm-project\premerge-checks\llvm\test\CodeGen\AVR\call.ll
View Full Test Results (7 Failed)

Event Timeline

dylanmckay created this revision.Jan 28 2021, 10:34 PM
dylanmckay requested review of this revision.Jan 28 2021, 10:34 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 28 2021, 10:34 PM
Herald added a subscriber: wdng. · View Herald Transcript
dylanmckay planned changes to this revision.Feb 9 2021, 4:26 AM

I've discovered an issue, this is not yet ready for review.

dylanmckay updated this revision to Diff 322354.Feb 9 2021, 5:44 AM

Fix an assertion error caused by attempting to get the frame size of non-frame instructions

arsenm requested changes to this revision.Tue, Mar 30, 3:45 PM

This seems like a confusion of what frame instructions means. What do these stores have to do with call frames? The stores should reference frame indexes representing fixed frame objects in the incoming arguments or local objects. The frame adjust instructions are for SP modifications in call sequences where instructions are directly referencing offsets off of the SP, which do not have corresponding frame indexes


Disassembling here is a little bit weird. Why isn't directly emitting asm sufficent?


This sentence doesn't make sense to me. Frame index elimination is unrelated to frame setup / frame destroy.

This revision now requires changes to proceed.Tue, Mar 30, 3:45 PM

I just realized I've been reading "frame pointer elimination" as "frame index elimination" but this change still doesn't make sense to me. Why do you want to treat these stores as frame instructions when they don't modify the stack pointer?