Ticket #7571: 0001-Ensure-the-LLVM-codegen-correctly-handles-literals-i.patch

File 0001-Ensure-the-LLVM-codegen-correctly-handles-literals-i.patch, 5.8 KB (added by thoughtpolice, 3 years ago)

Fix reference to 'Note' in commit.

  • compiler/llvmGen/LlvmCodeGen/CodeGen.hs

    From 92aaa8ac514cb8d1d177ef727c5db28b77b00f30 Mon Sep 17 00:00:00 2001
    From: Austin Seipp <[email protected]>
    Date: Sun, 13 Jan 2013 04:34:05 +0000
    Subject: [PATCH] Ensure the LLVM codegen correctly handles literals in a
     branch. #7571
    
    This was causing a failure to build GHC HEAD on my ODROID-U2 ARM
    machine. In general, hand-written C-- like in StgStdThunks.cmm would
    have tripped this on any platform, meaning bootstrapping with the
    LLVM backend was probably broken before.
    
    In general, we need to be sure that when generating code for literals,
    we properly narrow the type of the literal to i1. See Note [Literals
    and branch conditions] in the LlvmCodeGen.CodeGen module.
    
    This fixes Trac #7571.
    
    Signed-off-by: Austin Seipp <[email protected]>
    ---
     compiler/llvmGen/LlvmCodeGen/CodeGen.hs |   86 +++++++++++++++++++++++++------
     1 file changed, 70 insertions(+), 16 deletions(-)
    
    diff --git a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
    index 763656a..f6cd118 100644
    a b import UniqSupply 
    3131import Unique
    3232import Util
    3333
    34 import Data.List ( partition )
    35 
     34import Data.List  ( partition )
     35import Data.Maybe ( fromMaybe )
    3636
    3737type LlvmStatements = OrdList LlvmStatement
    3838
    genCondBranch :: LlvmEnv -> CmmExpr -> BlockId -> BlockId -> UniqSM StmtData 
    706706genCondBranch env cond idT idF = do
    707707    let labelT = blockIdToLlvm idT
    708708    let labelF = blockIdToLlvm idF
     709    -- See Note [Literals and branch conditions]
    709710    (env', vc, stmts, top) <- exprToVarOpt env i1Option cond
    710711    if getVarType vc == i1
    711712        then do
    genCondBranch env cond idT idF = do 
    714715        else
    715716            panic $ "genCondBranch: Cond expr not bool! (" ++ show vc ++ ")"
    716717
     718{- Note [Literals and branch conditions]
     719~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     720
     721It is important that whenever we generate branch conditions for
     722literals like '1', they are properly narrowed to an LLVM expression of
     723type 'i1' (for bools.) Otherwise, nobody is happy. So when we convert
     724a CmmExpr to an LLVM expression for a branch conditional, exprToVarOpt
     725must be certain to return a properly narrowed type. genLit is
     726responsible for this, in the case of literal integers.
     727
     728Often, we won't see direct statements like:
     729
     730    if(1) {
     731      ...
     732    } else {
     733      ...
     734    }
     735
     736at this point in the pipeline, because the Glorious Code Generator
     737will do trivial branch elimination in the sinking pass (among others,)
     738which will eliminate the expression entirely.
     739
     740However, it's certainly possible and reasonable for this to occur in
     741hand-written C-- code. Consider something like:
     742
     743    #ifndef SOME_CONDITIONAL
     744    #define CHECK_THING(x) 1
     745    #else
     746    #define CHECK_THING(x) some_operation((x))
     747    #endif
     748
     749    f() {
     750
     751      if (CHECK_THING(xyz)) {
     752        ...
     753      } else {
     754        ...
     755      }
     756
     757    }
     758
     759In such an instance, CHECK_THING might result in an *expression* in
     760one case, and a *literal* in the other, depending on what in
     761particular was #define'd. So we must be sure to properly narrow the
     762literal in this case to i1 as it won't be eliminated beforehand.
     763
     764For a real example of this, see ./rts/StgStdThunks.cmm
     765
     766-}
     767
     768
    717769
    718770-- | Switch branch
    719771--
    exprToVarOpt :: LlvmEnv -> EOption -> CmmExpr -> UniqSM ExprData 
    770822exprToVarOpt env opt e = case e of
    771823
    772824    CmmLit lit
    773         -> genLit env lit
     825        -> genLit opt env lit -- See Note [Literals and branch conditions]
    774826
    775827    CmmLoad e' ty
    776828        -> genLoad env e' ty
    allocReg _ = panic $ "allocReg: Global reg encountered! Global registers should" 
    12061258
    12071259
    12081260-- | Generate code for a literal
    1209 genLit :: LlvmEnv -> CmmLit -> UniqSM ExprData
    1210 genLit env (CmmInt i w)
    1211   = return (env, mkIntLit (LMInt $ widthInBits w) i, nilOL, [])
     1261genLit :: EOption -> LlvmEnv -> CmmLit -> UniqSM ExprData
     1262genLit (EOption opt) env (CmmInt i w)
     1263  -- See Note [Literals and branch conditions]
     1264  = let width = fromMaybe (LMInt $ widthInBits w) opt
     1265    in return (env, mkIntLit width i, nilOL, [])
    12121266
    1213 genLit env (CmmFloat r w)
     1267genLit _ env (CmmFloat r w)
    12141268  = return (env, LMLitVar $ LMFloatLit (fromRational r) (widthToLlvmFloat w),
    12151269              nilOL, [])
    12161270
    1217 genLit env cmm@(CmmLabel l)
     1271genLit _ env cmm@(CmmLabel l)
    12181272  = let dflags = getDflags env
    12191273        label = strCLabel_llvm env l
    12201274        ty = funLookup label env
    genLit env cmm@(CmmLabel l) 
    12361290                (v1, s1) <- doExpr lmty $ Cast LM_Ptrtoint var (llvmWord dflags)
    12371291                return (env, v1, unitOL s1, [])
    12381292
    1239 genLit env (CmmLabelOff label off) = do
     1293genLit opt env (CmmLabelOff label off) = do
    12401294    let dflags = getDflags env
    1241     (env', vlbl, stmts, stat) <- genLit env (CmmLabel label)
     1295    (env', vlbl, stmts, stat) <- genLit opt env (CmmLabel label)
    12421296    let voff = toIWord dflags off
    12431297    (v1, s1) <- doExpr (getVarType vlbl) $ LlvmOp LM_MO_Add vlbl voff
    12441298    return (env', v1, stmts `snocOL` s1, stat)
    12451299
    1246 genLit env (CmmLabelDiffOff l1 l2 off) = do
     1300genLit opt env (CmmLabelDiffOff l1 l2 off) = do
    12471301    let dflags = getDflags env
    1248     (env1, vl1, stmts1, stat1) <- genLit env (CmmLabel l1)
    1249     (env2, vl2, stmts2, stat2) <- genLit env1 (CmmLabel l2)
     1302    (env1, vl1, stmts1, stat1) <- genLit opt env (CmmLabel l1)
     1303    (env2, vl2, stmts2, stat2) <- genLit opt env1 (CmmLabel l2)
    12501304    let voff = toIWord dflags off
    12511305    let ty1 = getVarType vl1
    12521306    let ty2 = getVarType vl2
    genLit env (CmmLabelDiffOff l1 l2 off) = do 
    12621316        else
    12631317            panic "genLit: CmmLabelDiffOff encountered with different label ty!"
    12641318
    1265 genLit env (CmmBlock b)
    1266   = genLit env (CmmLabel $ infoTblLbl b)
     1319genLit opt env (CmmBlock b)
     1320  = genLit opt env (CmmLabel $ infoTblLbl b)
    12671321
    1268 genLit _ CmmHighStackMark
     1322genLit _ _ CmmHighStackMark
    12691323  = panic "genStaticLit - CmmHighStackMark unsupported!"
    12701324
    12711325