Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

Regression(r224745): " error in backend: ran out of registers during register allocation" while building chrome with clang/win #22051

Closed Quuxplusone closed 9 years ago

Quuxplusone commented 9 years ago
Bugzilla Link PR22052
Status RESOLVED FIXED
Importance P normal
Reported by Nico Weber (nicolasweber@gmx.de)
Reported on 2014-12-29 12:03:52 -0800
Last modified on 2015-01-12 17:28:36 -0800
Version unspecified
Hardware PC All
CC david.majnemer@gmail.com, ehsan.akhgari@gmail.com, llvm-bugs@lists.llvm.org, rafael@espindo.la, raymond.forbes@gmail.com, rnk@google.com
Fixed by commit(s)
Attachments foo.zip (761989 bytes, application/zip)
Blocks
Blocked by
See also

This started happening for 2 files. Last good revision is r224740, first bad is r224745.

r224741 is libcxx stuff. r224743 is Thumb1 (i.e. ARM) stuff. r224744 looks like code not used in release builds.

r224742 pinkie-swears that it doesn't change observable behavior.

This leaves r224745.

Quuxplusone commented 9 years ago

I'll try to get you a repro.

Quuxplusone commented 9 years ago

Attached foo.zip (761989 bytes, application/zip): repro

Quuxplusone commented 9 years ago

r224745 reverts fairly cleanly, and with it reverted this goes away. So it's r224745 for sure.

Quuxplusone commented 9 years ago
Here's a pretty small repro:

$ cat repro.ii
struct RdpClientWindow {
  RdpClientWindow();
  virtual void Invoke() { RdpClientWindow::_GetSinkMap(); }
  static void _GetSinkMap() {
    void (__stdcall RdpClientWindow::*map)() =
        &RdpClientWindow::OnAuthenticationWarningDisplayed;
  }
  virtual void __stdcall OnAuthenticationWarningDisplayed();
};
RdpClientWindow::RdpClientWindow() {}

$ bin/clang-cl -m32 /c repro.ii
error: ran out of registers during register allocation
Instruction uses an allocated register
UNREACHABLE executed at /Users/thakis/src/llvm-
svn/lib/CodeGen/RegAllocFast.cpp:365!
0  clang-3.6                0x00000001037d8419
llvm::sys::PrintStackTrace(__sFILE*) + 57
1  clang-3.6                0x00000001037d8beb SignalHandler(int) + 571
2  libsystem_platform.dylib 0x00007fff8caeb5aa _sigtramp + 26
3  clang-3.6                0x0000000103a34842
clang::TextDiagnostic::printDiagnosticMessage(llvm::raw_ostream&, bool,
llvm::StringRef, unsigned int, unsigned int, bool) + 898
4  clang-3.6                0x00000001037d8996 abort + 22
5  clang-3.6                0x000000010378e2c1
llvm::llvm_unreachable_internal(char const*, char const*, unsigned int) + 481
6  clang-3.6                0x00000001032de386 (anonymous
namespace)::RAFast::AllocateBasicBlock() + 12726
7  clang-3.6                0x00000001032dafdf (anonymous
namespace)::RAFast::runOnMachineFunction(llvm::MachineFunction&) + 815
8  clang-3.6                0x0000000103267c0c
llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 124
9  clang-3.6                0x000000010347627e
llvm::FPPassManager::runOnFunction(llvm::Function&) + 318
10 clang-3.6                0x00000001034764db
llvm::FPPassManager::runOnModule(llvm::Module&) + 43
11 clang-3.6                0x0000000103476a83
llvm::legacy::PassManagerImpl::run(llvm::Module&) + 1091

(this is on os x, not even a windows triple)
Quuxplusone commented 9 years ago
reduced:
target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
target triple = "i386-apple-windows-msvc"

%struct.RdpClientWindow.0.1.4 = type { i32 (...)** }

define x86_stdcallcc void
@"\01??_9RdpClientWindow@@$B3AE"(%struct.RdpClientWindow.0.1.4* %this, ...) {
entry:
  musttail call x86_stdcallcc void (%struct.RdpClientWindow.0.1.4*, ...)* null(%struct.RdpClientWindow.0.1.4* %this, ...)
  ret void
}
Quuxplusone commented 9 years ago
a little nicer:
target triple = "i386-pc-windows-msvc"

%Ty = type { i32 (...)** }

define x86_stdcallcc void @f(%Ty* %this, ...) {
entry:
  musttail call x86_stdcallcc void (%Ty*, ...)* null(%Ty* %this, ...)
  ret void
}
Quuxplusone commented 9 years ago

_Bug 22174 has been marked as a duplicate of this bug._

Quuxplusone commented 9 years ago
(In reply to comment #6)
> a little nicer:
> target triple = "i386-pc-windows-msvc"
>
> %Ty = type { i32 (...)** }
>
> define x86_stdcallcc void @f(%Ty* %this, ...) {
> entry:
>   musttail call x86_stdcallcc void (%Ty*, ...)* null(%Ty* %this, ...)
>   ret void
> }

Wat, why the hell are we using registers for stdcall functions...
Quuxplusone commented 9 years ago
(In reply to comment #8)
> (In reply to comment #6)
> > a little nicer:
> > target triple = "i386-pc-windows-msvc"
> >
> > %Ty = type { i32 (...)** }
> >
> > define x86_stdcallcc void @f(%Ty* %this, ...) {
> > entry:
> >   musttail call x86_stdcallcc void (%Ty*, ...)* null(%Ty* %this, ...)
> >   ret void
> > }
>
> Wat, why the hell are we using registers for stdcall functions...

Note that it's not just stdcall.  The only calling convention that doesn't
trigger this is __thiscall.  The rest (__cdecl, __stdcall and __fastcall) all
lead to the same result.
Quuxplusone commented 9 years ago

The problem is that I was attempting to forward all possible register parameters by forcibly setting the inreg flag and seeing what registers got used by the given convention. LLVM supports using the 'inreg' flag and the attribute((regparm(N))) attribute with the normal C calling convention to pass args in ECX, EDX, and EAX.

Unfortunately, that leaves us with no remaining scratch registers on x86, making it very difficult to lower an indirect call. We'd have the same problem on Linux x86_64 if r11 were not reserved for this purpose.

The fix is to give up on forwarding all possible inreg parameters. We still need to pretend that the inreg flag is present for fastcall and vectorcall, because that's how the frontend is supposed to lower them.

Quuxplusone commented 9 years ago

Should be fixed in r225729.