Ticket #7580: 0001-Fix-invalid-MachOp-coercions-when-extending-truncati.patch

File 0001-Fix-invalid-MachOp-coercions-when-extending-truncati.patch, 3.1 KB (added by thoughtpolice, 3 years ago)

Add reference to trac # in commit msg

  • compiler/llvmGen/LlvmCodeGen/CodeGen.hs

    From 0797b9083ece44fe6ca7f1be18c9136a30a2aa86 Mon Sep 17 00:00:00 2001
    From: Austin Seipp <[email protected]>
    Date: Mon, 14 Jan 2013 06:09:54 -0600
    Subject: [PATCH] Fix invalid MachOp coercions when extending/truncating. Fix
     Trac #7580.
    
    LLVM really dislikes it when we try to coerce a value to a type with the
    same width, so we must take care to eliminate such things. In a similar
    vein to #7571, we were using exprToVar which defaults to using a
    word-size for the result type of the variable, as opposed to the size we
    need to convert from.
    
    See Note [Generating MachOp coercions]
    
    Signed-off-by: Austin Seipp <[email protected]>
    ---
     compiler/llvmGen/LlvmCodeGen/CodeGen.hs | 31 ++++++++++++++++++++++++++++---
     1 file changed, 28 insertions(+), 3 deletions(-)
    
    diff --git a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
    index f6cd118..b463cd4 100644
    a b genMachOp env _ op [x] = case op of 
    936936            return (env', v1, stmts `snocOL` s1, top)
    937937
    938938        sameConv from ty reduce expand = do
    939             x'@(env', vx, stmts, top) <- exprToVar env x
     939
     940            let szOption = EOption $ Just (widthToLlvmInt from)
     941            x'@(env', vx, stmts, top) <- exprToVarOpt env szOption x
     942            -- Coerce with a cast operator, inserting a new instruction
     943            -- See Note [Generating MachOp coercions]
    940944            let sameConv' op = do
    941945                (v1, s1) <- doExpr ty $ Cast op vx ty
    942946                return (env', v1, stmts `snocOL` s1, top)
     947
     948            -- Determine whether to extend/truncate the result or not
    943949            let toWidth = llvmWidthInBits dflags ty
    944             -- LLVM doesn't like trying to convert to same width, so
    945             -- need to check for that as we do get Cmm code doing it.
    946950            case widthInBits from  of
    947951                 w | w < toWidth -> sameConv' expand
    948952                 w | w > toWidth -> sameConv' reduce
    genMachOp env _ op [x] = case op of 
    951955        panicOp = panic $ "LLVM.CodeGen.genMachOp: non unary op encourntered"
    952956                       ++ "with one argument! (" ++ show op ++ ")"
    953957
     958{- Note [Generating MachOp coercions]
     959
     960When we generate coercions for MachOps, we need to be certain that the
     961type of the expression we get from the Cmm -> LLVM conversion is of
     962the same width as the input Cmm type.
     963
     964Much like Note [Literals and branch conditions], we use exprToVarOpt
     965to enforce the result is of the type we need to coerce *from*, and
     966then we insert the coercion operator. We must do this because LLVM
     967really dislikes conversions of the form:
     968
     969   %r = zext i64 1 to i64;
     970
     971so we need to eliminate such redundant instructions. If we don't,
     972build failures abound. Do NOT use exprToVar, as it defaults to the
     973word size we're building with (which is probably wrong.)
     974
     975See Trac #7580 for a concrete example.
     976
     977-}
     978
    954979-- Handle GlobalRegs pointers
    955980genMachOp env opt o@(MO_Add _) e@[(CmmReg (CmmGlobal r)), (CmmLit (CmmInt n _))]
    956981    = genMachOp_fast env opt o r (fromInteger n) e