LLVM backend fails to bootstrap GHC
The fix for #14251 (closed) ended up regressing the ability for GHC to bootstrap itself using the LLVM backend on x86. Specifically, the register padding logic breaks when compiling stg_stack_underflow_frame_ret
in StgMiscClosures.cmm
:
$ _build/stage0/bin/ghc -Wall -dynamic-too -hisuf hi -osuf o -hcsuf hc -static -hide-all-packages -no-user-package-db '-package-db _build/stage1/lib/package.conf.d' '-this-unit-id rts-1.0' -i -i_build/stage1/rts/build -i_build/stage1/rts/build/autogen -irts/. -Iincludes -I_build/stage1/lib -I_build/stage1/rts/build -I_build/stage1/rts/build/build -I_build/stage1/rts/build/../includes -I_build/stage1/rts/build/includes -I_build/stage1/rts/build/includes/dist-derivedconstants/header -Irts/build -Irts/../includes -Irts/includes -Irts/includes/dist-derivedconstants/header -I_build/stage1/lib -optc-I_build/stage1/lib -optP-include -optP_build/stage1/rts/build/autogen/cabal_macros.h -ghcversion-file=_build/stage1/lib/ghcversion.h -outputdir _build/stage1/rts/build -Wnoncanonical-monad-instances -optc-Wno-error=inline -c rts/StgMiscClosures.cmm -o _build/stage1/rts/build/cmm/StgMiscClosures.o -O -H64m -this-unit-id rts -XHaskell98 -ghcversion-file=/home/ben/ghc/ghc/_build/stage1/lib/ghcversion.h -O2 -Irts -I_build/stage1/rts/build '-DRtsWay="rts_v"' -DFS_NAMESPACE=rts -DCOMPILING_RTS -Wno-deprecated-flags -Wcpp-undef -fllvm
ghc: panic! (the 'impossible' happened)
(GHC version 8.11.0.20200313:
getFPRPadding
fprRegNums = [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6]
live = [F1, F2, F3, F4, F5, F6, D1, D2, D3, D4, D5, D6, XMM1, XMM2, XMM3,
XMM4, XMM5, XMM6]
i = 2
acc = []
regNum = 1
Call stack:
CallStack (from HasCallStack):
callStackDoc, called at compiler/utils/Outputable.hs:1233:37 in ghc:Outputable
pprPanic, called at compiler/GHC/CmmToLlvm/Base.hs:256:27 in ghc:GHC.CmmToLlvm.Base
Please report this as a GHC bug: https://www.haskell.org/ghc/reportabug
The problem appears to be that this function keeps all registers live:
stg_stack_underflow_frame_ret() { // [R1, R2, R3, R4, R5, R6, R7,
R8, F1, F2, F3, F4, F5, F6, D1, D2, D3, D4, D5, D6, L1,
XMM1, XMM2, XMM3, XMM4, XMM5, XMM6]
{ info_tbls: [(cA,
label: stg_stack_underflow_frame_info
rep: tag:35 StackRep [False]
srt: Nothing)]
stack_info: arg_space: 0 updfr_space: Nothing
}
...
}
Yet these overlap in register number (e.g. fprRegNum (FloatReg n) == fprRegNum (DoubleReg n)
).