All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.