summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2018-06-21 00:35:17 +0200
committerGitHub <noreply@github.com>2018-06-21 00:35:17 +0200
commit6015749720ca2f5572b742185e9d236bf5a2b835 (patch)
tree23d65b628377457a59a280c62aa59f2d90c162c4
parent1be82d96a682338ba53832bcc2772b7865b47b57 (diff)
parentfb62dd1fae7a405d80f0d4257ddb1f4d48e204f0 (diff)
downloadNim-6015749720ca2f5572b742185e9d236bf5a2b835.tar.gz
Merge pull request #8062 from LemonBoy/fix-7825
Fix constant folding for shl/not
-rw-r--r--compiler/semfold.nim11
-rw-r--r--tests/arithm/tnot.nim58
-rw-r--r--tests/arithm/tshl.nim34
3 files changed, 101 insertions, 2 deletions
diff --git a/compiler/semfold.nim b/compiler/semfold.nim
index 10a223ea2..eceb10470 100644
--- a/compiler/semfold.nim
+++ b/compiler/semfold.nim
@@ -211,7 +211,12 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
   of mUnaryMinusF64: result = newFloatNodeT(- getFloat(a), n, g)
   of mNot: result = newIntNodeT(1 - getInt(a), n, g)
   of mCard: result = newIntNodeT(nimsets.cardSet(g.config, a), n, g)
-  of mBitnotI: result = newIntNodeT(not getInt(a), n, g)
+  of mBitnotI:
+    case skipTypes(n.typ, abstractRange).kind
+    of tyUInt..tyUInt64:
+      result = newIntNodeT((not getInt(a)) and lastOrd(g.config, a.typ, fixedUnsigned=true), n, g)
+    else:
+      result = newIntNodeT(not getInt(a), n, g)
   of mLengthArray: result = newIntNodeT(lengthOrd(g.config, a.typ), n, g)
   of mLengthSeq, mLengthOpenArray, mXLenSeq, mLengthStr, mXLenStr:
     if a.kind == nkNilLit:
@@ -250,8 +255,10 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
     of tyInt8: result = newIntNodeT(int8(getInt(a)) shl int8(getInt(b)), n, g)
     of tyInt16: result = newIntNodeT(int16(getInt(a)) shl int16(getInt(b)), n, g)
     of tyInt32: result = newIntNodeT(int32(getInt(a)) shl int32(getInt(b)), n, g)
-    of tyInt64, tyInt, tyUInt..tyUInt64:
+    of tyInt64, tyInt:
       result = newIntNodeT(`shl`(getInt(a), getInt(b)), n, g)
+    of tyUInt..tyUInt64:
+      result = newIntNodeT(`shl`(getInt(a), getInt(b)) and lastOrd(g.config, a.typ, fixedUnsigned=true), n, g)
     else: internalError(g.config, n.info, "constant folding for shl")
   of mShrI:
     case skipTypes(n.typ, abstractRange).kind
diff --git a/tests/arithm/tnot.nim b/tests/arithm/tnot.nim
new file mode 100644
index 000000000..6a4877b2c
--- /dev/null
+++ b/tests/arithm/tnot.nim
@@ -0,0 +1,58 @@
+discard """
+  output: '''
+-5
+-5
+-5
+-5
+4
+4
+4
+4
+251
+65531
+4294967291
+18446744073709551611
+4
+4
+4
+4
+'''
+"""
+
+# Signed types
+block:
+  const t0: int8  = not 4
+  const t1: int16 = not 4
+  const t2: int32 = not 4
+  const t3: int64 = not 4
+  const t4: int8  = not -5
+  const t5: int16 = not -5
+  const t6: int32 = not -5
+  const t7: int64 = not -5
+  echo t0
+  echo t1
+  echo t2
+  echo t3
+  echo t4
+  echo t5
+  echo t6
+  echo t7
+
+# Unsigned types
+block:
+  const t0: uint8  = not 4'u8
+  const t1: uint16 = not 4'u16
+  const t2: uint32 = not 4'u32
+  const t3: uint64 = not 4'u64
+  const t4: uint8  = not 251'u8
+  const t5: uint16 = not 65531'u16
+  const t6: uint32 = not 4294967291'u32
+  const t7: uint64 = not 18446744073709551611'u64
+  echo t0
+  echo t1
+  echo t2
+  echo t3
+  echo t4
+  echo t5
+  echo t6
+  echo t7
diff --git a/tests/arithm/tshl.nim b/tests/arithm/tshl.nim
new file mode 100644
index 000000000..0aa46d021
--- /dev/null
+++ b/tests/arithm/tshl.nim
@@ -0,0 +1,34 @@
+discard """
+  output: '''
+0
+0
+1
+1
+0
+0
+0
+1
+'''
+"""
+
+# Signed types
+block:
+  const t0: int8  = 1'i8 shl 8
+  const t1: int16 = 1'i16 shl 16
+  const t2: int32 = 1'i32 shl 32
+  const t3: int64 = 1'i64 shl 64
+  echo t0
+  echo t1
+  echo t2
+  echo t3
+
+# Unsigned types
+block:
+  const t0: uint8  = 1'u8 shl 8
+  const t1: uint16 = 1'u16 shl 16
+  const t2: uint32 = 1'u32 shl 32
+  const t3: uint64 = 1'u64 shl 64
+  echo t0
+  echo t1
+  echo t2
+  echo t3