Skip to content

Commit 8466d7c

Browse files
authored
Merge pull request #794 from viperproject/meilers_fix_782
Only simplify div and mod for positive arguments (like Carbon does)
2 parents 5ecdc3c + 5097b5e commit 8466d7c

2 files changed

Lines changed: 17 additions & 9 deletions

File tree

src/main/scala/viper/silver/ast/utility/Simplifier.scala

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,15 @@ object Simplifier {
116116
IntLit(left - right)(root.pos, root.info)
117117
case root @ Mul(IntLit(left), IntLit(right)) =>
118118
IntLit(left * right)(root.pos, root.info)
119-
case root @ Div(IntLit(left), IntLit(right)) if right != bigIntZero =>
119+
/* In the general case, Viper uses the SMT division and modulo. Scala's division is not in-sync with SMT division.
120+
For nonnegative dividends and divisors, all used division and modulo definitions coincide. So, in order to not
121+
not make any assumptions on the SMT division, division and modulo are simplified only if the dividend and divisor
122+
are nonnegative. Also see Carbon PR #448.
123+
*/
124+
case root @ Div(IntLit(left), IntLit(right)) if left >= bigIntZero && right > bigIntZero =>
120125
IntLit(left / right)(root.pos, root.info)
121-
case root @ Mod(IntLit(left), IntLit(right)) if right != bigIntZero =>
122-
IntLit((right.abs + (left % right)) % right.abs)(root.pos, root.info)
126+
case root @ Mod(IntLit(left), IntLit(right)) if left >= bigIntZero && right > bigIntZero =>
127+
IntLit(left % right)(root.pos, root.info)
123128

124129
// statement simplifications
125130
case Seqn(EmptyStmt, _) => EmptyStmt // remove empty Seqn (including unnecessary scopedDecls)

src/test/scala/SimplifierTests.scala

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,21 @@ class SimplifierTests extends AnyFunSuite with Matchers {
3636
test("div") {
3737
simplify(Div(0, 0)()) should be(Div(0, 0)())
3838
simplify(Div(8, 2)()) should be(4: IntLit)
39+
simplify(Div(-3, 2)()) should be(Div(-3, 2)())
40+
simplify(Div(3, 2)()) should be(1: IntLit)
41+
simplify(Div(3, -2)()) should be(Div(3, -2)())
3942
}
4043

4144
test("mod") {
4245
simplify(Mod(0, 0)()) should be (Mod(0, 0)())
4346
simplify(Mod(8, 3)()) should be (2: IntLit)
4447
simplify(Mod(3, 8)()) should be (3: IntLit)
45-
simplify(Mod(8, -3)()) should be (2: IntLit)
46-
simplify(Mod(3, -8)()) should be (3: IntLit)
47-
simplify(Mod(-8, 3)()) should be (1: IntLit)
48-
simplify(Mod(-3, 8)()) should be (5: IntLit)
49-
simplify(Mod(-8, -3)()) should be (1: IntLit)
50-
simplify(Mod(-3, -8)()) should be (5: IntLit)
48+
simplify(Mod(8, -3)()) should be (Mod(8, -3)())
49+
simplify(Mod(3, -8)()) should be (Mod(3, -8)())
50+
simplify(Mod(-8, 3)()) should be (Mod(-8, 3)())
51+
simplify(Mod(-3, 8)()) should be (Mod(-3, 8)())
52+
simplify(Mod(-8, -3)()) should be (Mod(-8, -3)())
53+
simplify(Mod(-3, -8)()) should be (Mod(-3, -8)())
5154
}
5255

5356
test("equality") {

0 commit comments

Comments
 (0)