* [PATCH 0/3] remove early simplification of casts during evaluation
@ 2021-04-18 11:56 Luc Van Oostenryck
2021-04-18 11:56 ` [PATCH 1/3] add testcases for simplification of casts Luc Van Oostenryck
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Luc Van Oostenryck @ 2021-04-18 11:56 UTC (permalink / raw)
To: linux-sparse; +Cc: Luc Van Oostenryck
This series removes an early simplification of casts during evaluation
which was wrong in some contexts (for example when applied to a bool)
but adds the equivalent optimization back at simplification where it can
be safely done at IR level.
Luc Van Oostenryck (3):
add testcases for simplification of casts.
simplify TRUNC(NOT(x)) --> NOT(TRUNC(x))
remove early simplification of casts during evaluation
evaluate.c | 44 +-------------------------------
simplify.c | 15 +++++++++++
validation/eval/not-cast-bool.c | 14 ++++++++++
validation/eval/not-cast-float.c | 14 ++++++++++
validation/optim/and-extendx.c | 24 -----------------
validation/optim/trunc-not0.c | 20 +++++++++++++++
6 files changed, 64 insertions(+), 67 deletions(-)
create mode 100644 validation/eval/not-cast-bool.c
create mode 100644 validation/eval/not-cast-float.c
delete mode 100644 validation/optim/and-extendx.c
create mode 100644 validation/optim/trunc-not0.c
base-commit: eb4cdd21b7d0cedbbeff7f70e24473706ccce5a6
--
2.31.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/3] add testcases for simplification of casts.
2021-04-18 11:56 [PATCH 0/3] remove early simplification of casts during evaluation Luc Van Oostenryck
@ 2021-04-18 11:56 ` Luc Van Oostenryck
2021-04-18 11:56 ` [PATCH 2/3] simplify TRUNC(NOT(x)) --> NOT(TRUNC(x)) Luc Van Oostenryck
2021-04-18 11:56 ` [PATCH 3/3] remove early simplification of casts during evaluation Luc Van Oostenryck
2 siblings, 0 replies; 4+ messages in thread
From: Luc Van Oostenryck @ 2021-04-18 11:56 UTC (permalink / raw)
To: linux-sparse; +Cc: Luc Van Oostenryck
and remove one that didn't made much sense.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
validation/eval/not-cast-bool.c | 15 +++++++++++++++
validation/eval/not-cast-float.c | 15 +++++++++++++++
validation/optim/and-extendx.c | 24 ------------------------
validation/optim/trunc-not0.c | 21 +++++++++++++++++++++
4 files changed, 51 insertions(+), 24 deletions(-)
create mode 100644 validation/eval/not-cast-bool.c
create mode 100644 validation/eval/not-cast-float.c
delete mode 100644 validation/optim/and-extendx.c
create mode 100644 validation/optim/trunc-not0.c
diff --git a/validation/eval/not-cast-bool.c b/validation/eval/not-cast-bool.c
new file mode 100644
index 000000000000..af4224125c34
--- /dev/null
+++ b/validation/eval/not-cast-bool.c
@@ -0,0 +1,15 @@
+static _Bool foo(void)
+{
+ unsigned char c = 1;
+ _Bool b = ~c;
+ return b;
+}
+
+/*
+ * check-name: not-cast-bool
+ * check-command: test-linearize -Wno-decl $file
+ * check-known-to-fail
+ *
+ * check-output-ignore
+ * check-output-returns: 1
+ */
diff --git a/validation/eval/not-cast-float.c b/validation/eval/not-cast-float.c
new file mode 100644
index 000000000000..445b91d7563e
--- /dev/null
+++ b/validation/eval/not-cast-float.c
@@ -0,0 +1,15 @@
+static int foo(void)
+{
+ int i = 123;
+ float x = ~i;
+ return (x < 0);
+}
+
+/*
+ * check-name: eval-bool-zext-neg
+ * check-command: test-linearize -Wno-decl $file
+ * check-known-to-fail
+ *
+ * check-output-ignore
+ * check-output-returns: 1
+ */
diff --git a/validation/optim/and-extendx.c b/validation/optim/and-extendx.c
deleted file mode 100644
index 5c181c93384e..000000000000
--- a/validation/optim/and-extendx.c
+++ /dev/null
@@ -1,24 +0,0 @@
-typedef unsigned short u16;
-typedef short s16;
-typedef unsigned int u32;
-typedef int s32;
-typedef unsigned long long u64;
-typedef long long s64;
-
-u64 ufoo(int x)
-{
- return x & 0x7fff;
-}
-
-u64 sfoo(int x)
-{
- return x & 0x7fff;
-}
-
-/*
- * check-name: and-extend
- * check-command: test-linearize -Wno-decl $file
- *
- * check-output-ignore
- * check-output-contains: and\\.64.*0x7fff
- */
diff --git a/validation/optim/trunc-not0.c b/validation/optim/trunc-not0.c
new file mode 100644
index 000000000000..febed165b0c4
--- /dev/null
+++ b/validation/optim/trunc-not0.c
@@ -0,0 +1,21 @@
+typedef __INT32_TYPE__ int32;
+typedef __INT64_TYPE__ int64;
+
+static _Bool sfoo(int64 a) { return ((int32) ~a) == (~ (int32)a); }
+static _Bool sbar(int64 a) { return (~(int32) ~a) == (int32)a; }
+
+
+typedef __UINT32_TYPE__ uint32;
+typedef __UINT64_TYPE__ uint64;
+
+static _Bool ufoo(uint64 a) { return ((uint32) ~a) == (~ (uint32)a); }
+static _Bool ubar(uint64 a) { return (~(uint32) ~a) == (uint32)a; }
+
+/*
+ * check-name: trunc-not0
+ * check-command: test-linearize -Wno-decl $file
+ * check-known-to-fail
+ *
+ * check-output-ignore
+ * check-output-returns: 1
+ */
--
2.31.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/3] simplify TRUNC(NOT(x)) --> NOT(TRUNC(x))
2021-04-18 11:56 [PATCH 0/3] remove early simplification of casts during evaluation Luc Van Oostenryck
2021-04-18 11:56 ` [PATCH 1/3] add testcases for simplification of casts Luc Van Oostenryck
@ 2021-04-18 11:56 ` Luc Van Oostenryck
2021-04-18 11:56 ` [PATCH 3/3] remove early simplification of casts during evaluation Luc Van Oostenryck
2 siblings, 0 replies; 4+ messages in thread
From: Luc Van Oostenryck @ 2021-04-18 11:56 UTC (permalink / raw)
To: linux-sparse; +Cc: Luc Van Oostenryck
The goal is double:
1) be able to do the NOT operation on the smaller type
2) more importantly, give the opportunity to the TRUNC to
cancel with a previous ZEXT if there is one.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
simplify.c | 15 +++++++++++++++
validation/optim/trunc-not0.c | 1 -
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/simplify.c b/simplify.c
index 9e3514d838a9..b2311d397b23 100644
--- a/simplify.c
+++ b/simplify.c
@@ -2288,6 +2288,21 @@ static int simplify_cast(struct instruction *insn)
return replace_pseudo(insn, &insn->src1, def->src1);
}
break;
+ case OP_NOT:
+ switch (insn->opcode) {
+ case OP_TRUNC:
+ if (!one_use(src))
+ break;
+
+ // TRUNC(NOT(x)) --> NOT(TRUNC(x))
+ insn->opcode = OP_NOT;
+ def->orig_type = def->type;
+ def->opcode = OP_TRUNC;
+ def->type = insn->type;
+ def->size = insn->size;
+ return REPEAT_CSE;
+ }
+ break;
case OP_OR:
switch (insn->opcode) {
case OP_TRUNC:
diff --git a/validation/optim/trunc-not0.c b/validation/optim/trunc-not0.c
index febed165b0c4..882b446d9197 100644
--- a/validation/optim/trunc-not0.c
+++ b/validation/optim/trunc-not0.c
@@ -14,7 +14,6 @@ static _Bool ubar(uint64 a) { return (~(uint32) ~a) == (uint32)a; }
/*
* check-name: trunc-not0
* check-command: test-linearize -Wno-decl $file
- * check-known-to-fail
*
* check-output-ignore
* check-output-returns: 1
--
2.31.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/3] remove early simplification of casts during evaluation
2021-04-18 11:56 [PATCH 0/3] remove early simplification of casts during evaluation Luc Van Oostenryck
2021-04-18 11:56 ` [PATCH 1/3] add testcases for simplification of casts Luc Van Oostenryck
2021-04-18 11:56 ` [PATCH 2/3] simplify TRUNC(NOT(x)) --> NOT(TRUNC(x)) Luc Van Oostenryck
@ 2021-04-18 11:56 ` Luc Van Oostenryck
2 siblings, 0 replies; 4+ messages in thread
From: Luc Van Oostenryck @ 2021-04-18 11:56 UTC (permalink / raw)
To: linux-sparse; +Cc: Luc Van Oostenryck
The current code will simplify away some casts at evaluation time
but doesn't take in account some special cases:
* (bool)~<int> is not equivalent to ~(bool)<int> (anything not all 0 or 1)
* (float)~<int> is not equivalent to ~(float)<int> which doesn't make sense.
* (int)(float)<int> is not a no-op if the (float) overflows
This kind of simplification is better done on the IR where the different
kind of casts correspond to distinct instructions.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
evaluate.c | 44 +-------------------------------
validation/eval/not-cast-bool.c | 1 -
validation/eval/not-cast-float.c | 1 -
3 files changed, 1 insertion(+), 45 deletions(-)
diff --git a/evaluate.c b/evaluate.c
index eea6b7adcf64..61f59ee3908e 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -226,12 +226,6 @@ static struct symbol *bigger_int_type(struct symbol *left, struct symbol *right)
return utype;
}
-static int same_cast_type(struct symbol *orig, struct symbol *new)
-{
- return orig->bit_size == new->bit_size &&
- orig->bit_offset == new->bit_offset;
-}
-
static struct symbol *base_type(struct symbol *node, unsigned long *modp, struct ident **asp)
{
unsigned long mod = 0;
@@ -316,10 +310,7 @@ static struct symbol *cast_to_bool(struct expression *expr);
/*
* This gets called for implicit casts in assignments and
- * integer promotion. We often want to try to move the
- * cast down, because the ops involved may have been
- * implicitly cast up, and we can get rid of the casts
- * early.
+ * integer promotion.
*/
static struct expression * cast_to(struct expression *old, struct symbol *type)
{
@@ -330,39 +321,6 @@ static struct expression * cast_to(struct expression *old, struct symbol *type)
if (old->ctype != &null_ctype && is_same_type(old, type))
return old;
- /*
- * See if we can simplify the op. Move the cast down.
- */
- switch (old->type) {
- case EXPR_PREOP:
- if (old->ctype->bit_size < type->bit_size)
- break;
- if (old->op == '~') {
- old->ctype = type;
- old->unop = cast_to(old->unop, type);
- return old;
- }
- break;
-
- case EXPR_IMPLIED_CAST:
- warn_for_different_enum_types(old->pos, old->ctype, type);
-
- if (old->ctype->bit_size >= type->bit_size) {
- struct expression *orig = old->cast_expression;
- if (same_cast_type(orig->ctype, type))
- return orig;
- if (old->ctype->bit_offset == type->bit_offset) {
- old->ctype = type;
- old->cast_type = type;
- return old;
- }
- }
- break;
-
- default:
- /* nothing */;
- }
-
expr = alloc_expression(old->pos, EXPR_IMPLIED_CAST);
expr->ctype = type;
expr->cast_type = type;
diff --git a/validation/eval/not-cast-bool.c b/validation/eval/not-cast-bool.c
index af4224125c34..acd8bbf293db 100644
--- a/validation/eval/not-cast-bool.c
+++ b/validation/eval/not-cast-bool.c
@@ -8,7 +8,6 @@ static _Bool foo(void)
/*
* check-name: not-cast-bool
* check-command: test-linearize -Wno-decl $file
- * check-known-to-fail
*
* check-output-ignore
* check-output-returns: 1
diff --git a/validation/eval/not-cast-float.c b/validation/eval/not-cast-float.c
index 445b91d7563e..d474d69bdda3 100644
--- a/validation/eval/not-cast-float.c
+++ b/validation/eval/not-cast-float.c
@@ -8,7 +8,6 @@ static int foo(void)
/*
* check-name: eval-bool-zext-neg
* check-command: test-linearize -Wno-decl $file
- * check-known-to-fail
*
* check-output-ignore
* check-output-returns: 1
--
2.31.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-04-18 11:56 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-18 11:56 [PATCH 0/3] remove early simplification of casts during evaluation Luc Van Oostenryck
2021-04-18 11:56 ` [PATCH 1/3] add testcases for simplification of casts Luc Van Oostenryck
2021-04-18 11:56 ` [PATCH 2/3] simplify TRUNC(NOT(x)) --> NOT(TRUNC(x)) Luc Van Oostenryck
2021-04-18 11:56 ` [PATCH 3/3] remove early simplification of casts during evaluation 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).