linux-sparse.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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).