diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2017-03-26 17:29:33 +0200 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2017-11-18 14:03:26 +0100 |
commit | 25dbd228c11410218242e585c598697005c707ea (patch) | |
tree | 4371572c4e7f05fb61720b950250cc7821b48b27 /cse.c | |
parent | 1c182507c3981aa20193c68d7cfd32d750b571cf (diff) | |
download | sparse-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.c | 14 |
1 files changed, 14 insertions, 0 deletions
@@ -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; |