aboutsummaryrefslogtreecommitdiffstats
path: root/cse.c
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-03-26 17:29:33 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-11-18 14:03:26 +0100
commit25dbd228c11410218242e585c598697005c707ea (patch)
tree4371572c4e7f05fb61720b950250cc7821b48b27 /cse.c
parent1c182507c3981aa20193c68d7cfd32d750b571cf (diff)
downloadsparse-25dbd228c11410218242e585c598697005c707ea.tar.gz
add support of floating-point specific arithmetic ops
Floating-point arithmetic is quite different from the arithmetic on integers or the one of real numbers. In particular, most transformations, simplifications that can be done on integers are invalid when done on floats. For example: - associativity doesn't hold - distributivity doesn't hold - comparison is tricky & complex This is because (among others things): - limited precision, rounding everywhere - presence of signed zeroes - presence of infinities - presence of NaNs (signaling or quiet) - presence of numbers without inverse - several kind of exceptions. Since they don't follow the same rules as their integer counterpart, better to give them a specific opcode instead of having to test the type of the operands at each manipulation. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Diffstat (limited to 'cse.c')
-rw-r--r--cse.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/cse.c b/cse.c
index 17b3da01..d5da26fb 100644
--- a/cse.c
+++ b/cse.c
@@ -70,11 +70,18 @@ static void clean_up_one_instruction(struct basic_block *bb, struct instruction
case OP_SET_LT: case OP_SET_GT:
case OP_SET_B: case OP_SET_A:
case OP_SET_BE: case OP_SET_AE:
+
+ /* floating-point arithmetic */
+ case OP_FADD:
+ case OP_FSUB:
+ case OP_FMUL:
+ case OP_FDIV:
hash += hashval(insn->src2);
/* Fall through */
/* Unary */
case OP_NOT: case OP_NEG:
+ case OP_FNEG:
hash += hashval(insn->src1);
break;
@@ -205,6 +212,12 @@ static int insn_compare(const void *_i1, const void *_i2)
case OP_SET_LT: case OP_SET_GT:
case OP_SET_B: case OP_SET_A:
case OP_SET_BE: case OP_SET_AE:
+
+ /* floating-point arithmetic */
+ case OP_FADD:
+ case OP_FSUB:
+ case OP_FMUL:
+ case OP_FDIV:
case_binops:
if (i1->src2 != i2->src2)
return i1->src2 < i2->src2 ? -1 : 1;
@@ -212,6 +225,7 @@ static int insn_compare(const void *_i1, const void *_i2)
/* Unary */
case OP_NOT: case OP_NEG:
+ case OP_FNEG:
if (i1->src1 != i2->src1)
return i1->src1 < i2->src1 ? -1 : 1;
break;