aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-12-05 23:41:47 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-12-10 23:26:23 +0100
commit5d02fb958506ba44d85b449bef68883c68d6ecfa (patch)
tree8abfeab6e1d54690e23b89c86a1745670bf54a82
parent706254f20d357735884c5e7b78c03d49bcad9cd3 (diff)
downloadsparse-5d02fb958506ba44d85b449bef68883c68d6ecfa.tar.gz
fix simplify_loads() when doing type punning
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>
-rw-r--r--memops.c11
-rw-r--r--validation/memops/type-punning-flt2int.c1
-rw-r--r--validation/memops/type-punning-int2flt.c1
3 files changed, 11 insertions, 2 deletions
diff --git a/memops.c b/memops.c
index 5df2c033..f071e556 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 a76c6c1d..fadaf687 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 c05ce252..061b7423 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\\.