Constant folding for integer casts (#8095)
This commit is contained in:
parent
b74faf354e
commit
2c8361bd39
3 changed files with 86 additions and 8 deletions
|
|
@ -450,21 +450,38 @@ proc rangeCheck(n: PNode, value: BiggestInt; g: ModuleGraph) =
|
|||
localError(g.config, n.info, "cannot convert " & $value &
|
||||
" to " & typeToString(n.typ))
|
||||
|
||||
proc foldConv*(n, a: PNode; g: ModuleGraph; check = false): PNode =
|
||||
proc foldConv(n, a: PNode; g: ModuleGraph; check = false): PNode =
|
||||
let dstTyp = skipTypes(n.typ, abstractRange)
|
||||
let srcTyp = skipTypes(a.typ, abstractRange)
|
||||
|
||||
# XXX range checks?
|
||||
case skipTypes(n.typ, abstractRange).kind
|
||||
of tyInt..tyInt64, tyUInt..tyUInt64:
|
||||
case skipTypes(a.typ, abstractRange).kind
|
||||
case dstTyp.kind
|
||||
of tyInt..tyInt64, tyUint..tyUInt64:
|
||||
case srcTyp.kind
|
||||
of tyFloat..tyFloat64:
|
||||
result = newIntNodeT(int(getFloat(a)), n, g)
|
||||
of tyChar: result = newIntNodeT(getOrdValue(a), n, g)
|
||||
of tyChar:
|
||||
result = newIntNodeT(getOrdValue(a), n, g)
|
||||
of tyUInt8..tyUInt32, tyInt8..tyInt32:
|
||||
let fromSigned = srcTyp.kind in tyInt..tyInt64
|
||||
let toSigned = dstTyp.kind in tyInt..tyInt64
|
||||
|
||||
let mask = lastOrd(g.config, dstTyp, fixedUnsigned=true)
|
||||
|
||||
var val =
|
||||
if toSigned:
|
||||
a.getOrdValue mod mask
|
||||
else:
|
||||
a.getOrdValue and mask
|
||||
|
||||
result = newIntNodeT(val, n, g)
|
||||
else:
|
||||
result = a
|
||||
result.typ = n.typ
|
||||
if check and result.kind in {nkCharLit..nkUInt64Lit}:
|
||||
rangeCheck(n, result.intVal, g)
|
||||
of tyFloat..tyFloat64:
|
||||
case skipTypes(a.typ, abstractRange).kind
|
||||
case srcTyp.kind
|
||||
of tyInt..tyInt64, tyEnum, tyBool, tyChar:
|
||||
result = newFloatNodeT(toBiggestFloat(getOrdValue(a)), n, g)
|
||||
else:
|
||||
|
|
@ -742,7 +759,8 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode =
|
|||
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
||||
var a = getConstExpr(m, n.sons[1], g)
|
||||
if a == nil: return
|
||||
result = foldConv(n, a, g, check=n.kind == nkHiddenStdConv)
|
||||
# XXX: we should enable `check` for other conversion types too
|
||||
result = foldConv(n, a, g, check=n.kind == nkHiddenSubConv)
|
||||
of nkCast:
|
||||
var a = getConstExpr(m, n.sons[1], g)
|
||||
if a == nil: return
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue