diff mbox series

[14/17] fix simplify_loads() when doing type punning

Message ID 20191210225921.94897-15-luc.vanoostenryck@gmail.com (mailing list archive)
State Mainlined, archived
Headers show
Series improve expansion of constant symbols | expand

Commit Message

Luc Van Oostenryck Dec. 10, 2019, 10:59 p.m. UTC
When doing loads simplification for a location where
floats & integers are mixed, loads are systematically
replaced with the value of their dominating memop (this
checks if the corresponding write or load overlaps).

However, this must not be done if the involved operations
are doing some form of integer/float type punning.

Fix this by refusing to convert load of an integer by a
previous float value or the opposite.

Note: another way to describe this problem would be to say
      that floats need to have their own memory operations:
          OP_FSTORE & OP_FLOAD
      or that instructions need to have some form of 'machine type'
      in addition of the size (like clang's i32/f32, ...).

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 memops.c                                 | 11 +++++++++++
 validation/memops/type-punning-flt2int.c |  1 -
 validation/memops/type-punning-int2flt.c |  1 -
 3 files changed, 11 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/memops.c b/memops.c
index 5df2c0339415..f071e556da8a 100644
--- a/memops.c
+++ b/memops.c
@@ -82,6 +82,15 @@  static int local_pseudo(pseudo_t pseudo)
 		&& !address_taken(pseudo);
 }
 
+static bool compatible_loads(struct instruction *a, struct instruction *b)
+{
+	if (is_integral_type(a->type) && is_float_type(b->type))
+		return false;
+	if (is_float_type(a->type) && is_integral_type(b->type))
+		return false;
+	return true;
+}
+
 static void simplify_loads(struct basic_block *bb)
 {
 	struct instruction *insn;
@@ -114,6 +123,8 @@  static void simplify_loads(struct basic_block *bb)
 							continue;
 						goto next_load;
 					}
+					if (!compatible_loads(insn, dom))
+						goto next_load;
 					/* Yeehaa! Found one! */
 					convert_load_instruction(insn, dom->target);
 					goto next_load;
diff --git a/validation/memops/type-punning-flt2int.c b/validation/memops/type-punning-flt2int.c
index a76c6c1da534..fadaf6876d13 100644
--- a/validation/memops/type-punning-flt2int.c
+++ b/validation/memops/type-punning-flt2int.c
@@ -13,7 +13,6 @@  static int foo(void)
  * check-name: type-punning-float-to-int
  * check description: must not infer the int value from the float
  * check-command: test-linearize $file
- * check-known-to-fail
  *
  * check-output-ignore
  * check-output-contains: load\\.
diff --git a/validation/memops/type-punning-int2flt.c b/validation/memops/type-punning-int2flt.c
index c05ce252f305..061b742352c4 100644
--- a/validation/memops/type-punning-int2flt.c
+++ b/validation/memops/type-punning-int2flt.c
@@ -13,7 +13,6 @@  static float foo(void)
  * check-name: type-punning-int-to-float
  * check description: must not infer the float value from the int
  * check-command: test-linearize $file
- * check-known-to-fail
  *
  * check-output-ignore
  * check-output-contains: load\\.