[commit: ghc] master: Test for undef bugs in the LLVM backend when validating (d50609e)
git at git.haskell.org
git at git.haskell.org
Wed Jan 27 10:31:03 UTC 2016
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/d50609e8f7a9c3a19d9d75c6133e742c9b584732/ghc
>---------------------------------------------------------------
commit d50609e8f7a9c3a19d9d75c6133e742c9b584732
Author: Reid Barton <rwbarton at gmail.com>
Date: Wed Jan 27 11:05:59 2016 +0100
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
>---------------------------------------------------------------
d50609e8f7a9c3a19d9d75c6133e742c9b584732
compiler/llvmGen/Llvm/Types.hs | 26 +++++++++++++++++++++++++-
compiler/main/DynFlags.hs | 2 ++
mk/flavours/validate.mk | 1 +
3 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/compiler/llvmGen/Llvm/Types.hs b/compiler/llvmGen/Llvm/Types.hs
index d533b4a..5c2ce5e 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
diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs
index 83de48c..b86d1a7 100644
--- a/compiler/main/DynFlags.hs
+++ b/compiler/main/DynFlags.hs
@@ -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,
diff --git a/mk/flavours/validate.mk b/mk/flavours/validate.mk
index 94892d4..1a636fa 100644
--- a/mk/flavours/validate.mk
+++ b/mk/flavours/validate.mk
@@ -1,4 +1,5 @@
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
More information about the ghc-commits
mailing list