summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2022-03-22 15:36:49 +0100
committerGitHub <noreply@github.com>2022-03-22 15:36:49 +0100
commitc4a0d4c5e35f09430a1c3d465fc62eb1001b7f9f (patch)
tree944f1a52319ac720874295334f143ada4ccac2f0
parent731eabc9309997775c8be41f3e5eb5512460aad0 (diff)
downloadNim-c4a0d4c5e35f09430a1c3d465fc62eb1001b7f9f.tar.gz
fixes #19615; emit better code for integer divisions when the divisor… (#19626)
* fixes #19615; emit better code for integer divisions when the divisor is known at compile-time

* proper bugfix: unsigned numbers cannot be -1
-rw-r--r--compiler/ccgexprs.nim22
1 files changed, 16 insertions, 6 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 9848366a1..1a3e217b2 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -584,13 +584,23 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
   else:
     # we handle div by zero here so that we know that the compilerproc's
     # result is only for overflows.
+    var needsOverflowCheck = true
     if m in {mDivI, mModI}:
-      linefmt(p, cpsStmts, "if ($1 == 0){ #raiseDivByZero(); $2}$n",
-              [rdLoc(b), raiseInstr(p)])
-
-    let res = binaryArithOverflowRaw(p, t, a, b,
-      if t.kind == tyInt64: prc64[m] else: prc[m])
-    putIntoDest(p, d, e, "($#)($#)" % [getTypeDesc(p.module, e.typ), res])
+      var canBeZero = true
+      if e[2].kind in {nkIntLit..nkUInt64Lit}:
+        canBeZero = e[2].intVal == 0
+      if e[2].kind in {nkIntLit..nkInt64Lit}:
+        needsOverflowCheck = e[2].intVal == -1
+      if canBeZero:
+        linefmt(p, cpsStmts, "if ($1 == 0){ #raiseDivByZero(); $2}$n",
+                [rdLoc(b), raiseInstr(p)])
+    if needsOverflowCheck:
+      let res = binaryArithOverflowRaw(p, t, a, b,
+        if t.kind == tyInt64: prc64[m] else: prc[m])
+      putIntoDest(p, d, e, "($#)($#)" % [getTypeDesc(p.module, e.typ), res])
+    else:
+      let res = "($1)($2 $3 $4)" % [getTypeDesc(p.module, e.typ), rdLoc(a), rope(opr[m]), rdLoc(b)]
+      putIntoDest(p, d, e, res)
 
 proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
   var