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, 2 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