Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC

Commits:

5 changed files:

Changes:

  • changelog.d/27915
    1
    +section: codegen
    
    2
    +synopsis: Fix a panic ("Can't find weight for edge that should have one") in the
    
    3
    +  x86-64 native code generator when a basic block contains several
    
    4
    +  word-to-float conversions.
    
    5
    +mrs: !16787
    
    6
    +issues: #27915

  • compiler/GHC/CmmToAsm/X86/CodeGen.hs
    ... ... @@ -4359,6 +4359,8 @@ genPrim bid (MO_AtomicRMW width amop) [dst] [addr, n]
    4359 4359
       = genAtomicRMW bid width amop dst addr n
    
    4360 4360
     genPrim bid (MO_Ctz width) [dst] [src]
    
    4361 4361
       = genCtz bid width dst src
    
    4362
    +genPrim bid (MO_UF_Conv width) [dst] [src]
    
    4363
    +  = genWordToFloat bid width dst src
    
    4362 4364
     
    
    4363 4365
     -- Then we deal with cases which not introducing new blocks in the stream.
    
    4364 4366
     genPrim bid prim dst args
    
    ... ... @@ -4385,7 +4387,6 @@ genSimplePrim bid (MO_PopCnt width) [dst] [src] = genPopCnt bid wi
    4385 4387
     genSimplePrim bid (MO_Pdep width)      [dst]   [src,mask]     = genPdep bid width dst src mask
    
    4386 4388
     genSimplePrim bid (MO_Pext width)      [dst]   [src,mask]     = genPext bid width dst src mask
    
    4387 4389
     genSimplePrim bid (MO_Clz width)       [dst]   [src]          = genClz bid width dst src
    
    4388
    -genSimplePrim bid (MO_UF_Conv width)   [dst]   [src]          = genWordToFloat bid width dst src
    
    4389 4390
     genSimplePrim _   (MO_AtomicRead w mo)  [dst]  [addr]         = genAtomicRead w mo dst addr
    
    4390 4391
     genSimplePrim _   (MO_AtomicWrite w mo) []     [addr,val]     = genAtomicWrite w mo addr val
    
    4391 4392
     genSimplePrim bid (MO_Cmpxchg width)   [dst]   [addr,old,new] = genCmpXchg bid width dst addr old new
    
    ... ... @@ -6924,7 +6925,11 @@ The constant 65536.0 (= 0x47800000 in float32 bit-pattern) is loaded
    6924 6925
     via a MOV + MOVD, avoiding a memory load.
    
    6925 6926
     -}
    
    6926 6927
     
    
    6927
    -genWordToFloat :: BlockId -> Width -> CmmFormal -> CmmActual -> NatM InstrBlock
    
    6928
    +-- | Convert an unsigned word to a float.
    
    6929
    +--
    
    6930
    +-- On x86-64 this introduces new blocks: the returned BlockId is the new current
    
    6931
    +-- block (#27915). See Note [Keeping track of the current block].
    
    6932
    +genWordToFloat :: BlockId -> Width -> CmmFormal -> CmmActual -> NatM (InstrBlock, Maybe BlockId)
    
    6928 6933
     genWordToFloat bid width dst src = do
    
    6929 6934
       is32Bit <- is32BitPlatform
    
    6930 6935
       platform <- getPlatform
    
    ... ... @@ -6946,7 +6951,7 @@ genWordToFloat bid width dst src = do
    6946 6951
             cst_r  <- getNewRegNat srcFormat
    
    6947 6952
             cst_v  <- getNewRegNat dstFormat
    
    6948 6953
             flip_r <- getNewRegNat srcFormat
    
    6949
    -        return $ code_src `appOL` toOL
    
    6954
    +        return $ (,Nothing) $ code_src `appOL` toOL
    
    6950 6955
               [ MOV srcFormat (OpImm (ImmInt 0x4F000000)) (OpReg cst_r)         -- load the constant
    
    6951 6956
               , MOVD srcFormat (floatFormat W32) (OpReg cst_r) (OpReg cst_v)
    
    6952 6957
               , CVTSS2SD cst_v cst_v
    
    ... ... @@ -6968,7 +6973,7 @@ genWordToFloat bid width dst src = do
    6968 6973
             cst_r  <- getNewRegNat srcFormat
    
    6969 6974
             high_r <- getNewRegNat srcFormat
    
    6970 6975
             low_r  <- getNewRegNat srcFormat
    
    6971
    -        return $ code_src `appOL` toOL
    
    6976
    +        return $ (,Nothing) $ code_src `appOL` toOL
    
    6972 6977
               [ MOV srcFormat (OpImm (ImmInt 0x47800000)) (OpReg cst_r) -- load the constant
    
    6973 6978
               , MOVD srcFormat dstFormat (OpReg cst_r) (OpReg cst_v)
    
    6974 6979
               , MOVZxL II16 (OpReg src_r) (OpReg low_r)                  -- low_r   = low 16 bits
    
    ... ... @@ -7006,7 +7011,7 @@ genWordToFloat bid width dst src = do
    7006 7011
                        . addWeightEdge lblLarge lblAfter   1
    
    7007 7012
                        . delEdge bid lblAfter )
    
    7008 7013
     
    
    7009
    -      return $ appOL (code_src)
    
    7014
    +      return $ (,Just lblAfter) $ appOL (code_src)
    
    7010 7015
             $ toOL
    
    7011 7016
             [ TEST srcFormat (OpReg src_r) (OpReg src_r)
    
    7012 7017
             , JXX NEG lblLarge
    

  • testsuite/tests/codeGen/should_run/T27915.hs
    1
    +{-# LANGUAGE BangPatterns #-}
    
    2
    +-- Two word-to-float conversions in one Cmm block, in a loop where the register
    
    3
    +-- assignment differs at the back edge. The x86-64 NCG used to emit an
    
    4
    +-- out-of-sync CFG and panic with "Can't find weight for edge that should have
    
    5
    +-- one" (#27915).
    
    6
    +module Main where
    
    7
    +
    
    8
    +go :: Word -> Word -> Word -> Double -> Double
    
    9
    +go 0 _ _ !acc = acc
    
    10
    +go n a b !acc = go (n-1) b a (acc + fromIntegral a * fromIntegral b)
    
    11
    +{-# NOINLINE go #-}
    
    12
    +
    
    13
    +goF :: Word -> Word -> Word -> Float -> Float
    
    14
    +goF 0 _ _ !acc = acc
    
    15
    +goF n a b !acc = goF (n-1) b a (acc + fromIntegral a * fromIntegral b)
    
    16
    +{-# NOINLINE goF #-}
    
    17
    +
    
    18
    +main :: IO ()
    
    19
    +main = do
    
    20
    +  print (go 10 3 maxBound 0)
    
    21
    +  print (goF 10 3 maxBound 0)

  • testsuite/tests/codeGen/should_run/T27915.stdout
    1
    +5.5340232221128655e20
    
    2
    +5.5340232e20

  • testsuite/tests/codeGen/should_run/all.T
    ... ... @@ -127,6 +127,7 @@ test('T7319', exit_code(1), compile_and_run, [''])
    127 127
     
    
    128 128
     test('Word2Float32', unless(wordsize(32), skip), compile_and_run, [''])
    
    129 129
     test('Word2Float64', unless(wordsize(64), skip), compile_and_run, [''])
    
    130
    +test('T27915', normal, compile_and_run, ['-O'])
    
    130 131
     
    
    131 132
     test('T7361', normal, compile_and_run, [''])
    
    132 133
     test('T7600', normal, compile_and_run, [''])