Commit d50609e8 authored by rwbarton's avatar rwbarton Committed by Ben Gamari
Browse files

Test for undef bugs in the LLVM backend when validating

In an attempt to catch bugs involving using undef values, replace
undef literals by values likely to cause crashes or test failures.
We do this only when validating since it is a deoptimization.

This depends on D1857 to catch such bugs in the RTS (such as #11487).

Test Plan:
Did a build with
```
BuildFlavour = quick-llvm
SRC_HC_OPTS_STAGE1 = -fllvm-fill-undef-with-garbage
```
The build crashed when running ghc-stage2, as expected.

Reviewers: austin, bgamari

Reviewed By: bgamari

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D1858
parent 0d92d9cb
......@@ -217,7 +217,31 @@ ppLit f@(LMFloatLit _ _) = sdocWithDynFlags (\dflags ->
error $ "Can't print this float literal!" ++ showSDoc dflags (ppr f))
ppLit (LMVectorLit ls ) = char '<' <+> ppCommaJoin ls <+> char '>'
ppLit (LMNullLit _ ) = text "null"
ppLit (LMUndefLit _ ) = text "undef"
-- Trac 11487 was an issue where we passed undef for some arguments
-- that were actually live. By chance the registers holding those
-- arguments usually happened to have the right values anyways, but
-- that was not guaranteed. To find such bugs reliably, we set the
-- flag below when validating, which replaces undef literals (at
-- common types) with values that are likely to cause a crash or test
-- failure.
ppLit (LMUndefLit t ) = sdocWithDynFlags f
where f dflags
| gopt Opt_LlvmFillUndefWithGarbage dflags,
Just lit <- garbageLit t = ppLit lit
| otherwise = text "undef"
garbageLit :: LlvmType -> Maybe LlvmLit
garbageLit t@(LMInt w) = Just (LMIntLit (0xbbbbbbbbbbbbbbb0 `mod` (2^w)) t)
-- Use a value that looks like an untagged pointer, so we are more
-- likely to try to enter it
garbageLit t
| isFloat t = Just (LMFloatLit 12345678.9 t)
garbageLit t@(LMPointer _) = Just (LMNullLit t)
-- Using null isn't totally ideal, since some functions may check for null.
-- But producing another value is inconvenient since it needs a cast,
-- and the knowledge for how to format casts is in PpLlvm.
garbageLit _ = Nothing
-- More cases could be added, but this should do for now.
-- | Return the 'LlvmType' of the 'LlvmVar'
getVarType :: LlvmVar -> LlvmType
......
......@@ -422,6 +422,7 @@ data GeneralFlag
| Opt_PedanticBottoms -- Be picky about how we treat bottom
| Opt_LlvmTBAA -- Use LLVM TBAA infastructure for improving AA (hidden flag)
| Opt_LlvmPassVectorsInRegisters -- Pass SIMD vectors in registers (requires a patched LLVM) (hidden flag)
| Opt_LlvmFillUndefWithGarbage -- Testing for undef bugs (hidden flag)
| Opt_IrrefutableTuples
| Opt_CmmSink
| Opt_CmmElimCommonBlocks
......@@ -3055,6 +3056,7 @@ fFlags = [
flagSpec "liberate-case" Opt_LiberateCase,
flagHiddenSpec "llvm-pass-vectors-in-regs" Opt_LlvmPassVectorsInRegisters,
flagHiddenSpec "llvm-tbaa" Opt_LlvmTBAA,
flagHiddenSpec "llvm-fill-undef-with-garbage" Opt_LlvmFillUndefWithGarbage,
flagSpec "loopification" Opt_Loopification,
flagSpec "omit-interface-pragmas" Opt_OmitInterfacePragmas,
flagSpec "omit-yields" Opt_OmitYields,
......
SRC_HC_OPTS = -O0 -H64m
SRC_HC_OPTS_STAGE1 = -fllvm-fill-undef-with-garbage # See Trac 11487
GhcStage1HcOpts = -O
GhcStage2HcOpts = -O -dcore-lint
GhcLibHcOpts = -O -dcore-lint
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment