* [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
* 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
* [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