aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
-rw-r--r--cse.c30
-rw-r--r--validation/optim/cse-cmp-next.c15
2 files changed, 33 insertions, 12 deletions
diff --git a/cse.c b/cse.c
index 848ac512..511ac88a 100644
--- a/cse.c
+++ b/cse.c
@@ -94,14 +94,12 @@ void cse_collect(struct instruction *insn)
case OP_TRUNC:
case OP_PTRCAST:
case OP_UTPTR: case OP_PTRTU:
- /*
- * This is crap! Many "orig_types" are the
- * same as far as casts go, we should generate
- * some kind of "type hash" that is identical
- * for identical casts
- */
- hash += hashval(insn->orig_type);
+ if (!insn->orig_type || insn->orig_type->bit_size < 0)
+ return;
hash += hashval(insn->src);
+
+ // Note: see corresponding line in insn_compare()
+ hash += hashval(insn->orig_type->bit_size);
break;
/* Other */
@@ -164,6 +162,7 @@ static int insn_compare(const void *_i1, const void *_i2)
{
const struct instruction *i1 = _i1;
const struct instruction *i2 = _i2;
+ int size1, size2;
int diff;
if (i1->opcode != i2->opcode)
@@ -241,13 +240,18 @@ static int insn_compare(const void *_i1, const void *_i2)
case OP_TRUNC:
case OP_PTRCAST:
case OP_UTPTR: case OP_PTRTU:
- /*
- * This is crap! See the comments on hashing.
- */
- if (i1->orig_type != i2->orig_type)
- return i1->orig_type < i2->orig_type ? -1 : 1;
if (i1->src != i2->src)
return i1->src < i2->src ? -1 : 1;
+
+ // Note: if it can be guaranted that identical ->src
+ // implies identical orig_type->bit_size, then this
+ // test and the hashing of the original size in
+ // cse_collect() are not needed.
+ // It must be generaly true but it isn't guaranted (yet).
+ size1 = i1->orig_type->bit_size;
+ size2 = i2->orig_type->bit_size;
+ if (size1 != size2)
+ return size1 < size2 ? -1 : 1;
break;
default:
@@ -359,6 +363,8 @@ static struct instruction * try_to_cse(struct entrypoint *ep, struct instruction
i1 = cse_one_instruction(i2, i1);
remove_instruction(&b1->insns, i1, 1);
add_instruction_to_end(i1, common);
+ } else {
+ i1 = i2;
}
return i1;
diff --git a/validation/optim/cse-cmp-next.c b/validation/optim/cse-cmp-next.c
new file mode 100644
index 00000000..50fdbac0
--- /dev/null
+++ b/validation/optim/cse-cmp-next.c
@@ -0,0 +1,15 @@
+void foo(int p, int i, int f, int *ref, int *dst, int *src)
+{
+ if (p)
+ f = ref[i];
+ if (f)
+ dst[i] = src[i];
+}
+
+/*
+ * check-name: cse-cmp-next
+ * check-command: test-linearize -Wno-decl $file
+ *
+ * check-output-ignore
+ * check-output-pattern(1,2): mul\\.
+ */