diff options
author | Reid Barton <rwbarton@gmail.com> | 2016-01-27 11:05:59 +0100 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2016-01-27 11:32:15 +0100 |
commit | d50609e8f7a9c3a19d9d75c6133e742c9b584732 (patch) | |
tree | 86d6694c1e504b7c5d3c092957999a09e269eebd /compiler/llvmGen | |
parent | 0d92d9cb6d65fd00f9910c3f6f85bc6c68f5543b (diff) | |
download | haskell-d50609e8f7a9c3a19d9d75c6133e742c9b584732.tar.gz |
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
Diffstat (limited to 'compiler/llvmGen')
-rw-r--r-- | compiler/llvmGen/Llvm/Types.hs | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/compiler/llvmGen/Llvm/Types.hs b/compiler/llvmGen/Llvm/Types.hs index d533b4a993..5c2ce5e3ee 100644 --- a/compiler/llvmGen/Llvm/Types.hs +++ b/compiler/llvmGen/Llvm/Types.hs @@ -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 |