[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