linux-sparse.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] more simplification of constant multiplicative ops
@ 2016-12-07 15:46 Luc Van Oostenryck
  2016-12-07 15:46 ` [PATCH 1/5] move OP_MUL simplification in a separate function Luc Van Oostenryck
                   ` (4 more replies)
  0 siblings, 5 replies; 25+ messages in thread
From: Luc Van Oostenryck @ 2016-12-07 15:46 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

This serie add a few more simplification of multiplicative operators
(multiplication, division & modulo) with constants 1 or -1.
Only simplifications that doesn't depend on undefined behavior are done.


Luc Van Oostenryck (5):
  move OP_MUL simplification in a separate function
  simplify '(x / 1)' to 'x'
  simplify '(x * -1)' to '-x'
  simplify '(x / -1)' to '-x' (but only for signed division)
  simplify '(x % 1)' into '0'

 simplify.c                          | 40 +++++++++++++++++++++++++++++++++++++
 validation/optim/muldiv-by-one.c    | 19 ++++++++++++++++++
 validation/optim/muldiv-by-zero.c   | 13 ++++++++++++
 validation/optim/muldiv-minus-one.c | 15 ++++++++++++++
 4 files changed, 87 insertions(+)
 create mode 100644 validation/optim/muldiv-by-one.c
 create mode 100644 validation/optim/muldiv-by-zero.c
 create mode 100644 validation/optim/muldiv-minus-one.c


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 1/5] move OP_MUL simplification in a separate function
  2016-12-07 15:46 [PATCH 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
@ 2016-12-07 15:46 ` Luc Van Oostenryck
  2016-12-07 15:46 ` [PATCH 2/5] simplify '(x / 1)' to 'x' Luc Van Oostenryck
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 25+ messages in thread
From: Luc Van Oostenryck @ 2016-12-07 15:46 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

This patch contains no functional changes.
It just moves the code for simplification of OP_MUL{U,S} with
constant operands in its own function in preparation for some
additional simplifications coming in the same serie.

Also add some test cases for the concerned simplifications.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 simplify.c                        | 17 +++++++++++++++++
 validation/optim/muldiv-by-one.c  | 13 +++++++++++++
 validation/optim/muldiv-by-zero.c | 13 +++++++++++++
 3 files changed, 43 insertions(+)
 create mode 100644 validation/optim/muldiv-by-one.c
 create mode 100644 validation/optim/muldiv-by-zero.c

diff --git a/simplify.c b/simplify.c
index b5cd0ea7..b242b64d 100644
--- a/simplify.c
+++ b/simplify.c
@@ -310,6 +310,21 @@ static int simplify_asr(struct instruction *insn, pseudo_t pseudo, long long val
 	return 0;
 }
 
+static int simplify_mul_div(struct instruction *insn, long long value)
+{
+	if (value == 1)
+		return replace_with_pseudo(insn, insn->src1);
+
+	switch (insn->opcode) {
+	case OP_MULS:
+	case OP_MULU:
+		if (value == 0)
+			return replace_with_pseudo(insn, insn->src2);
+	}
+
+	return 0;
+}
+
 static int simplify_constant_rightside(struct instruction *insn)
 {
 	long long value = insn->src2->value;
@@ -334,6 +349,8 @@ static int simplify_constant_rightside(struct instruction *insn)
 		return simplify_asr(insn, insn->src1, value);
 
 	case OP_MULU: case OP_MULS:
+		return simplify_mul_div(insn, value);
+
 	case OP_AND_BOOL:
 		if (value == 1)
 			return replace_with_pseudo(insn, insn->src1);
diff --git a/validation/optim/muldiv-by-one.c b/validation/optim/muldiv-by-one.c
new file mode 100644
index 00000000..ac8ac95b
--- /dev/null
+++ b/validation/optim/muldiv-by-one.c
@@ -0,0 +1,13 @@
+typedef	unsigned int ui;
+typedef	         int si;
+
+si smul1(si a) {  return a * 1; }
+ui umul1(ui a) {  return a * 1; }
+
+/*
+ * check-name: muldiv-by-one
+ * check-command: test-linearize -Wno-decl $file
+ * check-output-ignore
+ *
+ * check-output-excludes: mul[us]\\.
+ */
diff --git a/validation/optim/muldiv-by-zero.c b/validation/optim/muldiv-by-zero.c
new file mode 100644
index 00000000..07b7b1a7
--- /dev/null
+++ b/validation/optim/muldiv-by-zero.c
@@ -0,0 +1,13 @@
+typedef	unsigned int ui;
+typedef	         int si;
+
+si smul0(si a) {  return a * 0; }
+ui umul0(ui a) {  return a * 0; }
+
+/*
+ * check-name: muldiv-by-zero
+ * check-command: test-linearize -Wno-decl $file
+ * check-output-ignore
+ *
+ * check-output-excludes: mul[us]\\.
+ */
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 2/5] simplify '(x / 1)' to 'x'
  2016-12-07 15:46 [PATCH 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
  2016-12-07 15:46 ` [PATCH 1/5] move OP_MUL simplification in a separate function Luc Van Oostenryck
@ 2016-12-07 15:46 ` Luc Van Oostenryck
  2017-02-07  2:53   ` Christopher Li
  2016-12-07 15:46 ` [PATCH 3/5] simplify '(x * -1)' to '-x' Luc Van Oostenryck
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 25+ messages in thread
From: Luc Van Oostenryck @ 2016-12-07 15:46 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

Currently we simplify multiplication by 1 but nothing
for the similar divide by 1.

This patch add the missing simplification together with
its test cases.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 simplify.c                       | 5 +++++
 validation/optim/muldiv-by-one.c | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/simplify.c b/simplify.c
index b242b64d..5541fc4c 100644
--- a/simplify.c
+++ b/simplify.c
@@ -320,6 +320,10 @@ static int simplify_mul_div(struct instruction *insn, long long value)
 	case OP_MULU:
 		if (value == 0)
 			return replace_with_pseudo(insn, insn->src2);
+	/* Fall through */
+	case OP_DIVS:
+	case OP_DIVU:
+		break;
 	}
 
 	return 0;
@@ -348,6 +352,7 @@ static int simplify_constant_rightside(struct instruction *insn)
 	case OP_ASR:
 		return simplify_asr(insn, insn->src1, value);
 
+	case OP_DIVU: case OP_DIVS:
 	case OP_MULU: case OP_MULS:
 		return simplify_mul_div(insn, value);
 
diff --git a/validation/optim/muldiv-by-one.c b/validation/optim/muldiv-by-one.c
index ac8ac95b..f6dd7cb2 100644
--- a/validation/optim/muldiv-by-one.c
+++ b/validation/optim/muldiv-by-one.c
@@ -3,6 +3,8 @@ typedef	         int si;
 
 si smul1(si a) {  return a * 1; }
 ui umul1(ui a) {  return a * 1; }
+si sdiv1(si a) {  return a / 1; }
+ui udiv1(ui a) {  return a / 1; }
 
 /*
  * check-name: muldiv-by-one
@@ -10,4 +12,5 @@ ui umul1(ui a) {  return a * 1; }
  * check-output-ignore
  *
  * check-output-excludes: mul[us]\\.
+ * check-output-excludes: div[us]\\.
  */
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 3/5] simplify '(x * -1)' to '-x'
  2016-12-07 15:46 [PATCH 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
  2016-12-07 15:46 ` [PATCH 1/5] move OP_MUL simplification in a separate function Luc Van Oostenryck
  2016-12-07 15:46 ` [PATCH 2/5] simplify '(x / 1)' to 'x' Luc Van Oostenryck
@ 2016-12-07 15:46 ` Luc Van Oostenryck
  2016-12-07 15:46 ` [PATCH 4/5] simplify '(x / -1)' to '-x' (but only for signed division) Luc Van Oostenryck
  2016-12-07 15:46 ` [PATCH 5/5] simplify '(x % 1)' into '0' Luc Van Oostenryck
  4 siblings, 0 replies; 25+ messages in thread
From: Luc Van Oostenryck @ 2016-12-07 15:46 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

Currently we simplify multiplication by 1 but nothing is
done for multiplication by -1 which is equivalent to the
negation of its first operand.

This patch add this simplification.

Also add small test cases showing the simplification.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 simplify.c                          | 12 ++++++++++++
 validation/optim/muldiv-minus-one.c | 13 +++++++++++++
 2 files changed, 25 insertions(+)
 create mode 100644 validation/optim/muldiv-minus-one.c

diff --git a/simplify.c b/simplify.c
index 5541fc4c..6c7c79e9 100644
--- a/simplify.c
+++ b/simplify.c
@@ -312,6 +312,9 @@ static int simplify_asr(struct instruction *insn, pseudo_t pseudo, long long val
 
 static int simplify_mul_div(struct instruction *insn, long long value)
 {
+	unsigned long long sbit = 1ULL << (insn->size - 1);
+	unsigned long long bits = sbit | (sbit - 1);
+
 	if (value == 1)
 		return replace_with_pseudo(insn, insn->src1);
 
@@ -320,6 +323,15 @@ static int simplify_mul_div(struct instruction *insn, long long value)
 	case OP_MULU:
 		if (value == 0)
 			return replace_with_pseudo(insn, insn->src2);
+
+		if (!(value & sbit))	// positive
+			break;
+
+		value |= ~bits;
+		if (value == -1) {
+			insn->opcode = OP_NEG;
+			return REPEAT_CSE;
+		}
 	/* Fall through */
 	case OP_DIVS:
 	case OP_DIVU:
diff --git a/validation/optim/muldiv-minus-one.c b/validation/optim/muldiv-minus-one.c
new file mode 100644
index 00000000..729b7344
--- /dev/null
+++ b/validation/optim/muldiv-minus-one.c
@@ -0,0 +1,13 @@
+typedef	unsigned int u32;
+
+int smulm1(int a) { return a * -1; }
+u32 umulm1(u32 a) { return a * (u32) -1; }
+
+/*
+ * check-name: muldiv-minus-one
+ * check-command: test-linearize -Wno-decl $file
+ * check-output-ignore
+ *
+ * check-output-excludes: mul[us]\\.
+ * check-output-contains: neg\\.
+ */
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 4/5] simplify '(x / -1)' to '-x' (but only for signed division)
  2016-12-07 15:46 [PATCH 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
                   ` (2 preceding siblings ...)
  2016-12-07 15:46 ` [PATCH 3/5] simplify '(x * -1)' to '-x' Luc Van Oostenryck
@ 2016-12-07 15:46 ` Luc Van Oostenryck
  2016-12-07 15:46 ` [PATCH 5/5] simplify '(x % 1)' into '0' Luc Van Oostenryck
  4 siblings, 0 replies; 25+ messages in thread
From: Luc Van Oostenryck @ 2016-12-07 15:46 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

A previous patch added the simplification for multiply by -1
but we can do the same for the signed divide.

This patch add this simplification
Also add the corresponding test cases.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 simplify.c                          | 3 ++-
 validation/optim/muldiv-minus-one.c | 2 ++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/simplify.c b/simplify.c
index 6c7c79e9..e3e5ff6e 100644
--- a/simplify.c
+++ b/simplify.c
@@ -324,6 +324,8 @@ static int simplify_mul_div(struct instruction *insn, long long value)
 		if (value == 0)
 			return replace_with_pseudo(insn, insn->src2);
 
+	/* Fall through */
+	case OP_DIVS:
 		if (!(value & sbit))	// positive
 			break;
 
@@ -333,7 +335,6 @@ static int simplify_mul_div(struct instruction *insn, long long value)
 			return REPEAT_CSE;
 		}
 	/* Fall through */
-	case OP_DIVS:
 	case OP_DIVU:
 		break;
 	}
diff --git a/validation/optim/muldiv-minus-one.c b/validation/optim/muldiv-minus-one.c
index 729b7344..05a5f915 100644
--- a/validation/optim/muldiv-minus-one.c
+++ b/validation/optim/muldiv-minus-one.c
@@ -2,6 +2,7 @@ typedef	unsigned int u32;
 
 int smulm1(int a) { return a * -1; }
 u32 umulm1(u32 a) { return a * (u32) -1; }
+int sdivm1(int a) { return a * -1; }
 
 /*
  * check-name: muldiv-minus-one
@@ -9,5 +10,6 @@ u32 umulm1(u32 a) { return a * (u32) -1; }
  * check-output-ignore
  *
  * check-output-excludes: mul[us]\\.
+ * check-output-excludes: divs\\.
  * check-output-contains: neg\\.
  */
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 5/5] simplify '(x % 1)' into '0'
  2016-12-07 15:46 [PATCH 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
                   ` (3 preceding siblings ...)
  2016-12-07 15:46 ` [PATCH 4/5] simplify '(x / -1)' to '-x' (but only for signed division) Luc Van Oostenryck
@ 2016-12-07 15:46 ` Luc Van Oostenryck
  4 siblings, 0 replies; 25+ messages in thread
From: Luc Van Oostenryck @ 2016-12-07 15:46 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

For completeness, add the dual simplification 'x * 1 => x'
for modulo: 'x % 1 => 0'.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 simplify.c                       | 5 +++++
 validation/optim/muldiv-by-one.c | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/simplify.c b/simplify.c
index e3e5ff6e..9a6222c9 100644
--- a/simplify.c
+++ b/simplify.c
@@ -365,6 +365,11 @@ static int simplify_constant_rightside(struct instruction *insn)
 	case OP_ASR:
 		return simplify_asr(insn, insn->src1, value);
 
+	case OP_MODU: case OP_MODS:
+		if (value == 1)
+			return replace_with_pseudo(insn, value_pseudo(0));
+		return 0;
+
 	case OP_DIVU: case OP_DIVS:
 	case OP_MULU: case OP_MULS:
 		return simplify_mul_div(insn, value);
diff --git a/validation/optim/muldiv-by-one.c b/validation/optim/muldiv-by-one.c
index f6dd7cb2..5d9b458e 100644
--- a/validation/optim/muldiv-by-one.c
+++ b/validation/optim/muldiv-by-one.c
@@ -5,6 +5,8 @@ si smul1(si a) {  return a * 1; }
 ui umul1(ui a) {  return a * 1; }
 si sdiv1(si a) {  return a / 1; }
 ui udiv1(ui a) {  return a / 1; }
+si smod1(si a) {  return a % 1; }
+ui umod1(ui a) {  return a % 1; }
 
 /*
  * check-name: muldiv-by-one
@@ -13,4 +15,5 @@ ui udiv1(ui a) {  return a / 1; }
  *
  * check-output-excludes: mul[us]\\.
  * check-output-excludes: div[us]\\.
+ * check-output-excludes: mod[us]\\.
  */
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH 2/5] simplify '(x / 1)' to 'x'
  2016-12-07 15:46 ` [PATCH 2/5] simplify '(x / 1)' to 'x' Luc Van Oostenryck
@ 2017-02-07  2:53   ` Christopher Li
  2017-02-07 14:52     ` Luc Van Oostenryck
  0 siblings, 1 reply; 25+ messages in thread
From: Christopher Li @ 2017-02-07  2:53 UTC (permalink / raw)
  To: Luc Van Oostenryck; +Cc: Linux-Sparse

On Wed, Dec 7, 2016 at 11:46 PM, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
> Currently we simplify multiplication by 1 but nothing
> for the similar divide by 1.
>
> --- a/simplify.c
> +++ b/simplify.c
> @@ -320,6 +320,10 @@ static int simplify_mul_div(struct instruction *insn, long long value)
>         case OP_MULU:
>                 if (value == 0)
>                         return replace_with_pseudo(insn, insn->src2);
> +       /* Fall through */
> +       case OP_DIVS:
> +       case OP_DIVU:
> +               break;

This patch has already applied to sparse-next. Just one minor comment that
if the fall through is just a break. It is better just break there. If
the later code
need to use the fall though, just add the fall through part with the later code.

I think the later patch change this code any way.


Chris

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 2/5] simplify '(x / 1)' to 'x'
  2017-02-07  2:53   ` Christopher Li
@ 2017-02-07 14:52     ` Luc Van Oostenryck
  2017-02-07 18:29       ` Christopher Li
  0 siblings, 1 reply; 25+ messages in thread
From: Luc Van Oostenryck @ 2017-02-07 14:52 UTC (permalink / raw)
  To: Christopher Li; +Cc: Linux-Sparse

On Tue, Feb 07, 2017 at 10:53:16AM +0800, Christopher Li wrote:
> On Wed, Dec 7, 2016 at 11:46 PM, Luc Van Oostenryck
> <luc.vanoostenryck@gmail.com> wrote:
> > Currently we simplify multiplication by 1 but nothing
> > for the similar divide by 1.
> >
> > --- a/simplify.c
> > +++ b/simplify.c
> > @@ -320,6 +320,10 @@ static int simplify_mul_div(struct instruction *insn, long long value)
> >         case OP_MULU:
> >                 if (value == 0)
> >                         return replace_with_pseudo(insn, insn->src2);
> > +       /* Fall through */
> > +       case OP_DIVS:
> > +       case OP_DIVU:
> > +               break;
> 
> This patch has already applied to sparse-next. Just one minor comment that
> if the fall through is just a break. It is better just break there. If
> the later code
> need to use the fall though, just add the fall through part with the later code.

Mmmh yes. In fact here these 4 lines are not needed at all.
It's most probably leftover of some code restructuration.

Do you want that I send a new version of this patch?

Luc

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 2/5] simplify '(x / 1)' to 'x'
  2017-02-07 14:52     ` Luc Van Oostenryck
@ 2017-02-07 18:29       ` Christopher Li
  2017-02-07 19:00         ` [PATCH v2 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
  0 siblings, 1 reply; 25+ messages in thread
From: Christopher Li @ 2017-02-07 18:29 UTC (permalink / raw)
  To: Luc Van Oostenryck; +Cc: Linux-Sparse

On Tue, Feb 7, 2017 at 10:52 PM, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
>
> Mmmh yes. In fact here these 4 lines are not needed at all.
> It's most probably leftover of some code restructuration.
>
> Do you want that I send a new version of this patch?

If you have a new version of this patch or series. I am happy to replace
the old version and apply the new one. I can rebase sparse-next.

Chris

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v2 0/5] more simplification of constant multiplicative ops
  2017-02-07 18:29       ` Christopher Li
@ 2017-02-07 19:00         ` Luc Van Oostenryck
  2017-02-07 19:00           ` [PATCH v2 1/5] move OP_MUL simplification in a separate function Luc Van Oostenryck
                             ` (5 more replies)
  0 siblings, 6 replies; 25+ messages in thread
From: Luc Van Oostenryck @ 2017-02-07 19:00 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

This serie add a few more simplification of multiplicative operators
(multiplication, division & modulo) with constants 1 or -1.
Only simplifications that doesn't depend on undefined behavior are done.

Changes since v1:
- no functional changes
- remove unneeded case + break in patch 2

Luc Van Oostenryck (5):
  move OP_MUL simplification in a separate function
  simplify '(x / 1)' to 'x'
  simplify '(x * -1)' to '-x'
  simplify '(x / -1)' to '-x' (but only for signed division)
  simplify '(x % 1)' into '0'

 simplify.c                          | 36 ++++++++++++++++++++++++++++++++++++
 validation/optim/muldiv-by-one.c    | 19 +++++++++++++++++++
 validation/optim/muldiv-by-zero.c   | 13 +++++++++++++
 validation/optim/muldiv-minus-one.c | 15 +++++++++++++++
 4 files changed, 83 insertions(+)
 create mode 100644 validation/optim/muldiv-by-one.c
 create mode 100644 validation/optim/muldiv-by-zero.c
 create mode 100644 validation/optim/muldiv-minus-one.c

-- 
2.11.0


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v2 1/5] move OP_MUL simplification in a separate function
  2017-02-07 19:00         ` [PATCH v2 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
@ 2017-02-07 19:00           ` Luc Van Oostenryck
  2017-02-07 19:00           ` [PATCH v2 2/5] simplify '(x / 1)' to 'x' Luc Van Oostenryck
                             ` (4 subsequent siblings)
  5 siblings, 0 replies; 25+ messages in thread
From: Luc Van Oostenryck @ 2017-02-07 19:00 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

This patch contains no functional changes.
It just moves the code for simplification of OP_MUL{U,S} with
constant operands in its own function in preparation for some
additional simplifications coming in the same serie.

Also add some test cases for the concerned simplifications.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 simplify.c                        | 17 +++++++++++++++++
 validation/optim/muldiv-by-one.c  | 13 +++++++++++++
 validation/optim/muldiv-by-zero.c | 13 +++++++++++++
 3 files changed, 43 insertions(+)
 create mode 100644 validation/optim/muldiv-by-one.c
 create mode 100644 validation/optim/muldiv-by-zero.c

diff --git a/simplify.c b/simplify.c
index b5cd0ea77..b242b64d6 100644
--- a/simplify.c
+++ b/simplify.c
@@ -310,6 +310,21 @@ static int simplify_asr(struct instruction *insn, pseudo_t pseudo, long long val
 	return 0;
 }
 
+static int simplify_mul_div(struct instruction *insn, long long value)
+{
+	if (value == 1)
+		return replace_with_pseudo(insn, insn->src1);
+
+	switch (insn->opcode) {
+	case OP_MULS:
+	case OP_MULU:
+		if (value == 0)
+			return replace_with_pseudo(insn, insn->src2);
+	}
+
+	return 0;
+}
+
 static int simplify_constant_rightside(struct instruction *insn)
 {
 	long long value = insn->src2->value;
@@ -334,6 +349,8 @@ static int simplify_constant_rightside(struct instruction *insn)
 		return simplify_asr(insn, insn->src1, value);
 
 	case OP_MULU: case OP_MULS:
+		return simplify_mul_div(insn, value);
+
 	case OP_AND_BOOL:
 		if (value == 1)
 			return replace_with_pseudo(insn, insn->src1);
diff --git a/validation/optim/muldiv-by-one.c b/validation/optim/muldiv-by-one.c
new file mode 100644
index 000000000..ac8ac95b2
--- /dev/null
+++ b/validation/optim/muldiv-by-one.c
@@ -0,0 +1,13 @@
+typedef	unsigned int ui;
+typedef	         int si;
+
+si smul1(si a) {  return a * 1; }
+ui umul1(ui a) {  return a * 1; }
+
+/*
+ * check-name: muldiv-by-one
+ * check-command: test-linearize -Wno-decl $file
+ * check-output-ignore
+ *
+ * check-output-excludes: mul[us]\\.
+ */
diff --git a/validation/optim/muldiv-by-zero.c b/validation/optim/muldiv-by-zero.c
new file mode 100644
index 000000000..07b7b1a79
--- /dev/null
+++ b/validation/optim/muldiv-by-zero.c
@@ -0,0 +1,13 @@
+typedef	unsigned int ui;
+typedef	         int si;
+
+si smul0(si a) {  return a * 0; }
+ui umul0(ui a) {  return a * 0; }
+
+/*
+ * check-name: muldiv-by-zero
+ * check-command: test-linearize -Wno-decl $file
+ * check-output-ignore
+ *
+ * check-output-excludes: mul[us]\\.
+ */
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v2 2/5] simplify '(x / 1)' to 'x'
  2017-02-07 19:00         ` [PATCH v2 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
  2017-02-07 19:00           ` [PATCH v2 1/5] move OP_MUL simplification in a separate function Luc Van Oostenryck
@ 2017-02-07 19:00           ` Luc Van Oostenryck
  2017-02-07 19:00           ` [PATCH v2 3/5] simplify '(x * -1)' to '-x' Luc Van Oostenryck
                             ` (3 subsequent siblings)
  5 siblings, 0 replies; 25+ messages in thread
From: Luc Van Oostenryck @ 2017-02-07 19:00 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

Currently we simplify multiplication by 1 but nothing
for the similar divide by 1.

This patch add the missing simplification together with
its test cases.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 simplify.c                       | 1 +
 validation/optim/muldiv-by-one.c | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/simplify.c b/simplify.c
index b242b64d6..91021dbb1 100644
--- a/simplify.c
+++ b/simplify.c
@@ -348,6 +348,7 @@ static int simplify_constant_rightside(struct instruction *insn)
 	case OP_ASR:
 		return simplify_asr(insn, insn->src1, value);
 
+	case OP_DIVU: case OP_DIVS:
 	case OP_MULU: case OP_MULS:
 		return simplify_mul_div(insn, value);
 
diff --git a/validation/optim/muldiv-by-one.c b/validation/optim/muldiv-by-one.c
index ac8ac95b2..f6dd7cb2c 100644
--- a/validation/optim/muldiv-by-one.c
+++ b/validation/optim/muldiv-by-one.c
@@ -3,6 +3,8 @@ typedef	         int si;
 
 si smul1(si a) {  return a * 1; }
 ui umul1(ui a) {  return a * 1; }
+si sdiv1(si a) {  return a / 1; }
+ui udiv1(ui a) {  return a / 1; }
 
 /*
  * check-name: muldiv-by-one
@@ -10,4 +12,5 @@ ui umul1(ui a) {  return a * 1; }
  * check-output-ignore
  *
  * check-output-excludes: mul[us]\\.
+ * check-output-excludes: div[us]\\.
  */
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v2 3/5] simplify '(x * -1)' to '-x'
  2017-02-07 19:00         ` [PATCH v2 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
  2017-02-07 19:00           ` [PATCH v2 1/5] move OP_MUL simplification in a separate function Luc Van Oostenryck
  2017-02-07 19:00           ` [PATCH v2 2/5] simplify '(x / 1)' to 'x' Luc Van Oostenryck
@ 2017-02-07 19:00           ` Luc Van Oostenryck
  2017-02-07 19:00           ` [PATCH v2 4/5] simplify '(x / -1)' to '-x' (but only for signed division) Luc Van Oostenryck
                             ` (2 subsequent siblings)
  5 siblings, 0 replies; 25+ messages in thread
From: Luc Van Oostenryck @ 2017-02-07 19:00 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

Currently we simplify multiplication by 1 but nothing is
done for multiplication by -1 which is equivalent to the
negation of its first operand.

This patch add this simplification.

Also add small test cases showing the simplification.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 simplify.c                          | 11 +++++++++++
 validation/optim/muldiv-minus-one.c | 13 +++++++++++++
 2 files changed, 24 insertions(+)
 create mode 100644 validation/optim/muldiv-minus-one.c

diff --git a/simplify.c b/simplify.c
index 91021dbb1..363cc5ad7 100644
--- a/simplify.c
+++ b/simplify.c
@@ -312,6 +312,9 @@ static int simplify_asr(struct instruction *insn, pseudo_t pseudo, long long val
 
 static int simplify_mul_div(struct instruction *insn, long long value)
 {
+	unsigned long long sbit = 1ULL << (insn->size - 1);
+	unsigned long long bits = sbit | (sbit - 1);
+
 	if (value == 1)
 		return replace_with_pseudo(insn, insn->src1);
 
@@ -320,6 +323,14 @@ static int simplify_mul_div(struct instruction *insn, long long value)
 	case OP_MULU:
 		if (value == 0)
 			return replace_with_pseudo(insn, insn->src2);
+		if (!(value & sbit))	// positive
+			break;
+
+		value |= ~bits;
+		if (value == -1) {
+			insn->opcode = OP_NEG;
+			return REPEAT_CSE;
+		}
 	}
 
 	return 0;
diff --git a/validation/optim/muldiv-minus-one.c b/validation/optim/muldiv-minus-one.c
new file mode 100644
index 000000000..729b73443
--- /dev/null
+++ b/validation/optim/muldiv-minus-one.c
@@ -0,0 +1,13 @@
+typedef	unsigned int u32;
+
+int smulm1(int a) { return a * -1; }
+u32 umulm1(u32 a) { return a * (u32) -1; }
+
+/*
+ * check-name: muldiv-minus-one
+ * check-command: test-linearize -Wno-decl $file
+ * check-output-ignore
+ *
+ * check-output-excludes: mul[us]\\.
+ * check-output-contains: neg\\.
+ */
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v2 4/5] simplify '(x / -1)' to '-x' (but only for signed division)
  2017-02-07 19:00         ` [PATCH v2 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
                             ` (2 preceding siblings ...)
  2017-02-07 19:00           ` [PATCH v2 3/5] simplify '(x * -1)' to '-x' Luc Van Oostenryck
@ 2017-02-07 19:00           ` Luc Van Oostenryck
  2017-02-07 19:39             ` Rasmus Villemoes
  2017-02-07 19:00           ` [PATCH v2 " Luc Van Oostenryck
  2017-02-07 19:18           ` [PATCH v2 0/5] more simplification of constant multiplicative ops Christopher Li
  5 siblings, 1 reply; 25+ messages in thread
From: Luc Van Oostenryck @ 2017-02-07 19:00 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

A previous patch added the simplification for multiply by -1
but we can do the same for the signed divide.

This patch add this simplification
Also add the corresponding test cases.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 simplify.c                          | 2 ++
 validation/optim/muldiv-minus-one.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/simplify.c b/simplify.c
index 363cc5ad7..86d2f5da9 100644
--- a/simplify.c
+++ b/simplify.c
@@ -323,6 +323,8 @@ static int simplify_mul_div(struct instruction *insn, long long value)
 	case OP_MULU:
 		if (value == 0)
 			return replace_with_pseudo(insn, insn->src2);
+	/* Fall through */
+	case OP_DIVS:
 		if (!(value & sbit))	// positive
 			break;
 
diff --git a/validation/optim/muldiv-minus-one.c b/validation/optim/muldiv-minus-one.c
index 729b73443..05a5f915c 100644
--- a/validation/optim/muldiv-minus-one.c
+++ b/validation/optim/muldiv-minus-one.c
@@ -2,6 +2,7 @@ typedef	unsigned int u32;
 
 int smulm1(int a) { return a * -1; }
 u32 umulm1(u32 a) { return a * (u32) -1; }
+int sdivm1(int a) { return a * -1; }
 
 /*
  * check-name: muldiv-minus-one
@@ -9,5 +10,6 @@ u32 umulm1(u32 a) { return a * (u32) -1; }
  * check-output-ignore
  *
  * check-output-excludes: mul[us]\\.
+ * check-output-excludes: divs\\.
  * check-output-contains: neg\\.
  */
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v2 5/5] simplify '(x % 1)' into '0'
  2017-02-07 19:00         ` [PATCH v2 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
                             ` (3 preceding siblings ...)
  2017-02-07 19:00           ` [PATCH v2 4/5] simplify '(x / -1)' to '-x' (but only for signed division) Luc Van Oostenryck
@ 2017-02-07 19:00           ` Luc Van Oostenryck
  2017-02-07 19:18           ` [PATCH v2 0/5] more simplification of constant multiplicative ops Christopher Li
  5 siblings, 0 replies; 25+ messages in thread
From: Luc Van Oostenryck @ 2017-02-07 19:00 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

For completeness, add the dual simplification 'x * 1 => x'
for modulo: 'x % 1 => 0'.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 simplify.c                       | 5 +++++
 validation/optim/muldiv-by-one.c | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/simplify.c b/simplify.c
index 86d2f5da9..b0d229a92 100644
--- a/simplify.c
+++ b/simplify.c
@@ -361,6 +361,11 @@ static int simplify_constant_rightside(struct instruction *insn)
 	case OP_ASR:
 		return simplify_asr(insn, insn->src1, value);
 
+	case OP_MODU: case OP_MODS:
+		if (value == 1)
+			return replace_with_pseudo(insn, value_pseudo(0));
+		return 0;
+
 	case OP_DIVU: case OP_DIVS:
 	case OP_MULU: case OP_MULS:
 		return simplify_mul_div(insn, value);
diff --git a/validation/optim/muldiv-by-one.c b/validation/optim/muldiv-by-one.c
index f6dd7cb2c..5d9b458e0 100644
--- a/validation/optim/muldiv-by-one.c
+++ b/validation/optim/muldiv-by-one.c
@@ -5,6 +5,8 @@ si smul1(si a) {  return a * 1; }
 ui umul1(ui a) {  return a * 1; }
 si sdiv1(si a) {  return a / 1; }
 ui udiv1(ui a) {  return a / 1; }
+si smod1(si a) {  return a % 1; }
+ui umod1(ui a) {  return a % 1; }
 
 /*
  * check-name: muldiv-by-one
@@ -13,4 +15,5 @@ ui udiv1(ui a) {  return a / 1; }
  *
  * check-output-excludes: mul[us]\\.
  * check-output-excludes: div[us]\\.
+ * check-output-excludes: mod[us]\\.
  */
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 0/5] more simplification of constant multiplicative ops
  2017-02-07 19:00         ` [PATCH v2 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
                             ` (4 preceding siblings ...)
  2017-02-07 19:00           ` [PATCH v2 " Luc Van Oostenryck
@ 2017-02-07 19:18           ` Christopher Li
  5 siblings, 0 replies; 25+ messages in thread
From: Christopher Li @ 2017-02-07 19:18 UTC (permalink / raw)
  To: Luc Van Oostenryck; +Cc: Linux-Sparse

On Wed, Feb 8, 2017 at 3:00 AM, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
> This serie add a few more simplification of multiplicative operators
> (multiplication, division & modulo) with constants 1 or -1.
> Only simplifications that doesn't depend on undefined behavior are done.
>
> Changes since v1:

Just double checking. I suppose to take out the old version
of the patch already applied in spase-next then apply this
series, right?

Chris

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 4/5] simplify '(x / -1)' to '-x' (but only for signed division)
  2017-02-07 19:00           ` [PATCH v2 4/5] simplify '(x / -1)' to '-x' (but only for signed division) Luc Van Oostenryck
@ 2017-02-07 19:39             ` Rasmus Villemoes
  2017-02-07 20:28               ` Luc Van Oostenryck
  0 siblings, 1 reply; 25+ messages in thread
From: Rasmus Villemoes @ 2017-02-07 19:39 UTC (permalink / raw)
  To: Luc Van Oostenryck; +Cc: linux-sparse, Christopher Li

On Tue, Feb 07 2017, Luc Van Oostenryck <luc.vanoostenryck@gmail.com> wrote:

>  int smulm1(int a) { return a * -1; }
>  u32 umulm1(u32 a) { return a * (u32) -1; }
> +int sdivm1(int a) { return a * -1; }

You probably meant / rather than *. Also, shouldn't you also add a test that
when a is unsigned, a/-1 does _not_ get transformed to -a?

Rasmus

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 4/5] simplify '(x / -1)' to '-x' (but only for signed division)
  2017-02-07 19:39             ` Rasmus Villemoes
@ 2017-02-07 20:28               ` Luc Van Oostenryck
  2017-02-07 20:33                 ` Christopher Li
  0 siblings, 1 reply; 25+ messages in thread
From: Luc Van Oostenryck @ 2017-02-07 20:28 UTC (permalink / raw)
  To: Rasmus Villemoes; +Cc: linux-sparse, Christopher Li

On Tue, Feb 07, 2017 at 08:39:22PM +0100, Rasmus Villemoes wrote:
> On Tue, Feb 07 2017, Luc Van Oostenryck <luc.vanoostenryck@gmail.com> wrote:
> 
> >  int smulm1(int a) { return a * -1; }
> >  u32 umulm1(u32 a) { return a * (u32) -1; }
> > +int sdivm1(int a) { return a * -1; }
> 
> You probably meant / rather than *.
Indeed, nice catch. Thanks.

> Also, shouldn't you also add a test that
> when a is unsigned, a/-1 does _not_ get transformed to -a?
Hummm , yes but ... well, I'll see what I can do.

Luc

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v2 4/5] simplify '(x / -1)' to '-x' (but only for signed division)
  2017-02-07 20:28               ` Luc Van Oostenryck
@ 2017-02-07 20:33                 ` Christopher Li
  2017-02-07 20:50                   ` [PATCH v3 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
  0 siblings, 1 reply; 25+ messages in thread
From: Christopher Li @ 2017-02-07 20:33 UTC (permalink / raw)
  To: Luc Van Oostenryck; +Cc: Rasmus Villemoes, Linux-Sparse

On Wed, Feb 8, 2017 at 4:28 AM, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:

>
>> Also, shouldn't you also add a test that
>> when a is unsigned, a/-1 does _not_ get transformed to -a?
> Hummm , yes but ... well, I'll see what I can do.

Let me know if there is a V3 coming then.

Chris

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v3 0/5] more simplification of constant multiplicative ops
  2017-02-07 20:33                 ` Christopher Li
@ 2017-02-07 20:50                   ` Luc Van Oostenryck
  2017-02-07 20:50                     ` [PATCH v3 1/5] move OP_MUL simplification in a separate function Luc Van Oostenryck
                                       ` (4 more replies)
  0 siblings, 5 replies; 25+ messages in thread
From: Luc Van Oostenryck @ 2017-02-07 20:50 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Rasmus Villemoes, Luc Van Oostenryck

This serie add a few more simplification of multiplicative operators
(multiplication, division & modulo) with constants 1 or -1.
Only simplifications that doesn't depend on undefined behavior are done.

Changes since v1:
- no functional changes
- remove unneeded case + break in patch 2

Changes since v2:
- fix copy-paste error in test case for OP_DIVS by -1
- add test case for OP_DIVU by -1
Both thanks to Rasmus Villemoes.


Luc Van Oostenryck (5):
  move OP_MUL simplification in a separate function
  simplify '(x / 1)' to 'x'
  simplify '(x * -1)' to '-x'
  simplify '(x / -1)' to '-x' (but only for signed division)
  simplify '(x % 1)' into '0'

 simplify.c                          | 36 ++++++++++++++++++++++++++++++++++++
 validation/optim/muldiv-by-one.c    | 19 +++++++++++++++++++
 validation/optim/muldiv-by-zero.c   | 13 +++++++++++++
 validation/optim/muldiv-minus-one.c | 18 ++++++++++++++++++
 4 files changed, 86 insertions(+)
 create mode 100644 validation/optim/muldiv-by-one.c
 create mode 100644 validation/optim/muldiv-by-zero.c
 create mode 100644 validation/optim/muldiv-minus-one.c

-- 
2.11.0


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v3 1/5] move OP_MUL simplification in a separate function
  2017-02-07 20:50                   ` [PATCH v3 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
@ 2017-02-07 20:50                     ` Luc Van Oostenryck
  2017-02-07 20:50                     ` [PATCH v3 2/5] simplify '(x / 1)' to 'x' Luc Van Oostenryck
                                       ` (3 subsequent siblings)
  4 siblings, 0 replies; 25+ messages in thread
From: Luc Van Oostenryck @ 2017-02-07 20:50 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Rasmus Villemoes, Luc Van Oostenryck

This patch contains no functional changes.
It just moves the code for simplification of OP_MUL{U,S} with
constant operands in its own function in preparation for some
additional simplifications coming in the same serie.

Also add some test cases for the concerned simplifications.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 simplify.c                        | 17 +++++++++++++++++
 validation/optim/muldiv-by-one.c  | 13 +++++++++++++
 validation/optim/muldiv-by-zero.c | 13 +++++++++++++
 3 files changed, 43 insertions(+)
 create mode 100644 validation/optim/muldiv-by-one.c
 create mode 100644 validation/optim/muldiv-by-zero.c

diff --git a/simplify.c b/simplify.c
index b5cd0ea77..b242b64d6 100644
--- a/simplify.c
+++ b/simplify.c
@@ -310,6 +310,21 @@ static int simplify_asr(struct instruction *insn, pseudo_t pseudo, long long val
 	return 0;
 }
 
+static int simplify_mul_div(struct instruction *insn, long long value)
+{
+	if (value == 1)
+		return replace_with_pseudo(insn, insn->src1);
+
+	switch (insn->opcode) {
+	case OP_MULS:
+	case OP_MULU:
+		if (value == 0)
+			return replace_with_pseudo(insn, insn->src2);
+	}
+
+	return 0;
+}
+
 static int simplify_constant_rightside(struct instruction *insn)
 {
 	long long value = insn->src2->value;
@@ -334,6 +349,8 @@ static int simplify_constant_rightside(struct instruction *insn)
 		return simplify_asr(insn, insn->src1, value);
 
 	case OP_MULU: case OP_MULS:
+		return simplify_mul_div(insn, value);
+
 	case OP_AND_BOOL:
 		if (value == 1)
 			return replace_with_pseudo(insn, insn->src1);
diff --git a/validation/optim/muldiv-by-one.c b/validation/optim/muldiv-by-one.c
new file mode 100644
index 000000000..ac8ac95b2
--- /dev/null
+++ b/validation/optim/muldiv-by-one.c
@@ -0,0 +1,13 @@
+typedef	unsigned int ui;
+typedef	         int si;
+
+si smul1(si a) {  return a * 1; }
+ui umul1(ui a) {  return a * 1; }
+
+/*
+ * check-name: muldiv-by-one
+ * check-command: test-linearize -Wno-decl $file
+ * check-output-ignore
+ *
+ * check-output-excludes: mul[us]\\.
+ */
diff --git a/validation/optim/muldiv-by-zero.c b/validation/optim/muldiv-by-zero.c
new file mode 100644
index 000000000..07b7b1a79
--- /dev/null
+++ b/validation/optim/muldiv-by-zero.c
@@ -0,0 +1,13 @@
+typedef	unsigned int ui;
+typedef	         int si;
+
+si smul0(si a) {  return a * 0; }
+ui umul0(ui a) {  return a * 0; }
+
+/*
+ * check-name: muldiv-by-zero
+ * check-command: test-linearize -Wno-decl $file
+ * check-output-ignore
+ *
+ * check-output-excludes: mul[us]\\.
+ */
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 2/5] simplify '(x / 1)' to 'x'
  2017-02-07 20:50                   ` [PATCH v3 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
  2017-02-07 20:50                     ` [PATCH v3 1/5] move OP_MUL simplification in a separate function Luc Van Oostenryck
@ 2017-02-07 20:50                     ` Luc Van Oostenryck
  2017-02-07 20:50                     ` [PATCH v3 3/5] simplify '(x * -1)' to '-x' Luc Van Oostenryck
                                       ` (2 subsequent siblings)
  4 siblings, 0 replies; 25+ messages in thread
From: Luc Van Oostenryck @ 2017-02-07 20:50 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Rasmus Villemoes, Luc Van Oostenryck

Currently we simplify multiplication by 1 but nothing
for the similar divide by 1.

This patch add the missing simplification together with
its test cases.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 simplify.c                       | 1 +
 validation/optim/muldiv-by-one.c | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/simplify.c b/simplify.c
index b242b64d6..91021dbb1 100644
--- a/simplify.c
+++ b/simplify.c
@@ -348,6 +348,7 @@ static int simplify_constant_rightside(struct instruction *insn)
 	case OP_ASR:
 		return simplify_asr(insn, insn->src1, value);
 
+	case OP_DIVU: case OP_DIVS:
 	case OP_MULU: case OP_MULS:
 		return simplify_mul_div(insn, value);
 
diff --git a/validation/optim/muldiv-by-one.c b/validation/optim/muldiv-by-one.c
index ac8ac95b2..f6dd7cb2c 100644
--- a/validation/optim/muldiv-by-one.c
+++ b/validation/optim/muldiv-by-one.c
@@ -3,6 +3,8 @@ typedef	         int si;
 
 si smul1(si a) {  return a * 1; }
 ui umul1(ui a) {  return a * 1; }
+si sdiv1(si a) {  return a / 1; }
+ui udiv1(ui a) {  return a / 1; }
 
 /*
  * check-name: muldiv-by-one
@@ -10,4 +12,5 @@ ui umul1(ui a) {  return a * 1; }
  * check-output-ignore
  *
  * check-output-excludes: mul[us]\\.
+ * check-output-excludes: div[us]\\.
  */
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 3/5] simplify '(x * -1)' to '-x'
  2017-02-07 20:50                   ` [PATCH v3 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
  2017-02-07 20:50                     ` [PATCH v3 1/5] move OP_MUL simplification in a separate function Luc Van Oostenryck
  2017-02-07 20:50                     ` [PATCH v3 2/5] simplify '(x / 1)' to 'x' Luc Van Oostenryck
@ 2017-02-07 20:50                     ` Luc Van Oostenryck
  2017-02-07 20:50                     ` [PATCH v3 4/5] simplify '(x / -1)' to '-x' (but only for signed division) Luc Van Oostenryck
  2017-02-07 20:50                     ` [PATCH v3 5/5] simplify '(x % 1)' into '0' Luc Van Oostenryck
  4 siblings, 0 replies; 25+ messages in thread
From: Luc Van Oostenryck @ 2017-02-07 20:50 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Rasmus Villemoes, Luc Van Oostenryck

Currently we simplify multiplication by 1 but nothing is
done for multiplication by -1 which is equivalent to the
negation of its first operand.

This patch add this simplification.

Also add small test cases showing the simplification.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 simplify.c                          | 11 +++++++++++
 validation/optim/muldiv-minus-one.c | 13 +++++++++++++
 2 files changed, 24 insertions(+)
 create mode 100644 validation/optim/muldiv-minus-one.c

diff --git a/simplify.c b/simplify.c
index 91021dbb1..363cc5ad7 100644
--- a/simplify.c
+++ b/simplify.c
@@ -312,6 +312,9 @@ static int simplify_asr(struct instruction *insn, pseudo_t pseudo, long long val
 
 static int simplify_mul_div(struct instruction *insn, long long value)
 {
+	unsigned long long sbit = 1ULL << (insn->size - 1);
+	unsigned long long bits = sbit | (sbit - 1);
+
 	if (value == 1)
 		return replace_with_pseudo(insn, insn->src1);
 
@@ -320,6 +323,14 @@ static int simplify_mul_div(struct instruction *insn, long long value)
 	case OP_MULU:
 		if (value == 0)
 			return replace_with_pseudo(insn, insn->src2);
+		if (!(value & sbit))	// positive
+			break;
+
+		value |= ~bits;
+		if (value == -1) {
+			insn->opcode = OP_NEG;
+			return REPEAT_CSE;
+		}
 	}
 
 	return 0;
diff --git a/validation/optim/muldiv-minus-one.c b/validation/optim/muldiv-minus-one.c
new file mode 100644
index 000000000..729b73443
--- /dev/null
+++ b/validation/optim/muldiv-minus-one.c
@@ -0,0 +1,13 @@
+typedef	unsigned int u32;
+
+int smulm1(int a) { return a * -1; }
+u32 umulm1(u32 a) { return a * (u32) -1; }
+
+/*
+ * check-name: muldiv-minus-one
+ * check-command: test-linearize -Wno-decl $file
+ * check-output-ignore
+ *
+ * check-output-excludes: mul[us]\\.
+ * check-output-contains: neg\\.
+ */
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 4/5] simplify '(x / -1)' to '-x' (but only for signed division)
  2017-02-07 20:50                   ` [PATCH v3 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
                                       ` (2 preceding siblings ...)
  2017-02-07 20:50                     ` [PATCH v3 3/5] simplify '(x * -1)' to '-x' Luc Van Oostenryck
@ 2017-02-07 20:50                     ` Luc Van Oostenryck
  2017-02-07 20:50                     ` [PATCH v3 5/5] simplify '(x % 1)' into '0' Luc Van Oostenryck
  4 siblings, 0 replies; 25+ messages in thread
From: Luc Van Oostenryck @ 2017-02-07 20:50 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Rasmus Villemoes, Luc Van Oostenryck

A previous patch added the simplification for multiply by -1
but we can do the same for the signed divide.

This patch add this simplification
Also add the corresponding test cases.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 simplify.c                          | 2 ++
 validation/optim/muldiv-minus-one.c | 5 +++++
 2 files changed, 7 insertions(+)

diff --git a/simplify.c b/simplify.c
index 363cc5ad7..86d2f5da9 100644
--- a/simplify.c
+++ b/simplify.c
@@ -323,6 +323,8 @@ static int simplify_mul_div(struct instruction *insn, long long value)
 	case OP_MULU:
 		if (value == 0)
 			return replace_with_pseudo(insn, insn->src2);
+	/* Fall through */
+	case OP_DIVS:
 		if (!(value & sbit))	// positive
 			break;
 
diff --git a/validation/optim/muldiv-minus-one.c b/validation/optim/muldiv-minus-one.c
index 729b73443..42b086afd 100644
--- a/validation/optim/muldiv-minus-one.c
+++ b/validation/optim/muldiv-minus-one.c
@@ -2,6 +2,8 @@ typedef	unsigned int u32;
 
 int smulm1(int a) { return a * -1; }
 u32 umulm1(u32 a) { return a * (u32) -1; }
+int sdivm1(int a) { return a / -1; }
+u32 udivm1(u32 a) { return a / (u32) -1; }
 
 /*
  * check-name: muldiv-minus-one
@@ -9,5 +11,8 @@ u32 umulm1(u32 a) { return a * (u32) -1; }
  * check-output-ignore
  *
  * check-output-excludes: mul[us]\\.
+ * check-output-excludes: divs\\.
  * check-output-contains: neg\\.
+ * check-output-contains: divu\\.
+ * check-output-pattern-3-times: neg\\.
  */
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 5/5] simplify '(x % 1)' into '0'
  2017-02-07 20:50                   ` [PATCH v3 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
                                       ` (3 preceding siblings ...)
  2017-02-07 20:50                     ` [PATCH v3 4/5] simplify '(x / -1)' to '-x' (but only for signed division) Luc Van Oostenryck
@ 2017-02-07 20:50                     ` Luc Van Oostenryck
  4 siblings, 0 replies; 25+ messages in thread
From: Luc Van Oostenryck @ 2017-02-07 20:50 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Rasmus Villemoes, Luc Van Oostenryck

For completeness, add the dual simplification 'x * 1 => x'
for modulo: 'x % 1 => 0'.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 simplify.c                       | 5 +++++
 validation/optim/muldiv-by-one.c | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/simplify.c b/simplify.c
index 86d2f5da9..b0d229a92 100644
--- a/simplify.c
+++ b/simplify.c
@@ -361,6 +361,11 @@ static int simplify_constant_rightside(struct instruction *insn)
 	case OP_ASR:
 		return simplify_asr(insn, insn->src1, value);
 
+	case OP_MODU: case OP_MODS:
+		if (value == 1)
+			return replace_with_pseudo(insn, value_pseudo(0));
+		return 0;
+
 	case OP_DIVU: case OP_DIVS:
 	case OP_MULU: case OP_MULS:
 		return simplify_mul_div(insn, value);
diff --git a/validation/optim/muldiv-by-one.c b/validation/optim/muldiv-by-one.c
index f6dd7cb2c..5d9b458e0 100644
--- a/validation/optim/muldiv-by-one.c
+++ b/validation/optim/muldiv-by-one.c
@@ -5,6 +5,8 @@ si smul1(si a) {  return a * 1; }
 ui umul1(ui a) {  return a * 1; }
 si sdiv1(si a) {  return a / 1; }
 ui udiv1(ui a) {  return a / 1; }
+si smod1(si a) {  return a % 1; }
+ui umod1(ui a) {  return a % 1; }
 
 /*
  * check-name: muldiv-by-one
@@ -13,4 +15,5 @@ ui udiv1(ui a) {  return a / 1; }
  *
  * check-output-excludes: mul[us]\\.
  * check-output-excludes: div[us]\\.
+ * check-output-excludes: mod[us]\\.
  */
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2017-02-07 20:53 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-12-07 15:46 [PATCH 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
2016-12-07 15:46 ` [PATCH 1/5] move OP_MUL simplification in a separate function Luc Van Oostenryck
2016-12-07 15:46 ` [PATCH 2/5] simplify '(x / 1)' to 'x' Luc Van Oostenryck
2017-02-07  2:53   ` Christopher Li
2017-02-07 14:52     ` Luc Van Oostenryck
2017-02-07 18:29       ` Christopher Li
2017-02-07 19:00         ` [PATCH v2 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
2017-02-07 19:00           ` [PATCH v2 1/5] move OP_MUL simplification in a separate function Luc Van Oostenryck
2017-02-07 19:00           ` [PATCH v2 2/5] simplify '(x / 1)' to 'x' Luc Van Oostenryck
2017-02-07 19:00           ` [PATCH v2 3/5] simplify '(x * -1)' to '-x' Luc Van Oostenryck
2017-02-07 19:00           ` [PATCH v2 4/5] simplify '(x / -1)' to '-x' (but only for signed division) Luc Van Oostenryck
2017-02-07 19:39             ` Rasmus Villemoes
2017-02-07 20:28               ` Luc Van Oostenryck
2017-02-07 20:33                 ` Christopher Li
2017-02-07 20:50                   ` [PATCH v3 0/5] more simplification of constant multiplicative ops Luc Van Oostenryck
2017-02-07 20:50                     ` [PATCH v3 1/5] move OP_MUL simplification in a separate function Luc Van Oostenryck
2017-02-07 20:50                     ` [PATCH v3 2/5] simplify '(x / 1)' to 'x' Luc Van Oostenryck
2017-02-07 20:50                     ` [PATCH v3 3/5] simplify '(x * -1)' to '-x' Luc Van Oostenryck
2017-02-07 20:50                     ` [PATCH v3 4/5] simplify '(x / -1)' to '-x' (but only for signed division) Luc Van Oostenryck
2017-02-07 20:50                     ` [PATCH v3 5/5] simplify '(x % 1)' into '0' Luc Van Oostenryck
2017-02-07 19:00           ` [PATCH v2 " Luc Van Oostenryck
2017-02-07 19:18           ` [PATCH v2 0/5] more simplification of constant multiplicative ops Christopher Li
2016-12-07 15:46 ` [PATCH 3/5] simplify '(x * -1)' to '-x' Luc Van Oostenryck
2016-12-07 15:46 ` [PATCH 4/5] simplify '(x / -1)' to '-x' (but only for signed division) Luc Van Oostenryck
2016-12-07 15:46 ` [PATCH 5/5] simplify '(x % 1)' into '0' Luc Van Oostenryck

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).