globalRegMaybe inconsistencies on aarch64
CmmSink claims in one place globalRegMaybe isn't available on ARM:
isTrivial :: Platform -> CmmExpr -> Bool
isTrivial _ (CmmReg (CmmLocal _)) = True
isTrivial platform (CmmReg (CmmGlobal (GlobalRegUse r _))) = -- see Note [Inline GlobalRegs?]
if isARM (platformArch platform)
then True -- CodeGen.Platform.ARM does not have globalRegMaybe
else isJust (globalRegMaybe platform r)
-- GlobalRegs that are loads from BaseReg are not trivial
isTrivial _ (CmmLit _) = True
isTrivial _ _ = False
However CmmSink also has unguarded calls to globalRegMaybe
which should be reachable on ARM in the conflicts
function:
-- (6) suspendThread clobbers every global register not backed by a real
-- register. It also clobbers heap and stack but this is handled by (5)
| CmmUnsafeForeignCall (PrimTarget MO_SuspendThread) _ _ <- node
, foldRegsUsed platform (\b g -> globalRegMaybe platform g == Nothing || b) False rhs
= True
So if this were true I would expect this to fail.
Indeed in CodeGen.Platform.h
we have:
globalRegMaybe :: GlobalReg -> Maybe RealReg
#if defined(MACHREGS_i386) || defined(MACHREGS_x86_64) \
|| defined(MACHREGS_powerpc) \
|| defined(MACHREGS_arm) || defined(MACHREGS_aarch64) \
|| defined(MACHREGS_s390x) || defined(MACHREGS_riscv64) \
|| defined(MACHREGS_wasm32) \
|| defined(MACHREGS_loongarch64)
# if defined(REG_Base)
globalRegMaybe BaseReg = Just (RealRegSingle REG_Base)
# endif
# if defined(REG_R1)
globalRegMaybe (VanillaReg 1) = Just (RealRegSingle REG_R1)
# endif
# if defined(REG_R2)
globalRegMaybe (VanillaReg 2) = Just (RealRegSingle REG_R2)
# endif
...
Which should work for aarch64 just fine. So I think this is no longer the case and the special casing can be removed.