diff options
| author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2017-03-25 03:01:17 +0100 |
|---|---|---|
| committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2017-11-18 13:54:54 +0100 |
| commit | 1c182507c3981aa20193c68d7cfd32d750b571cf (patch) | |
| tree | b0ec94c9cad3d457ffb7db679a070db729327450 /Documentation | |
| parent | 1fb139520881e9339589048c9c31dd1956a33ffb (diff) | |
| download | sparse-dev-1c182507c3981aa20193c68d7cfd32d750b571cf.tar.gz | |
fix support of floating-point compare
Comparision of floating-point values can't be done
like for integral values because of the possibility to have
NaNs which can't be ordered with normal values or even between
themselves.
The real difference appears once there is any "reasoning"
done with the result of the comparison. For example, once NaNs
are taken in account: "!(a < b)" and "(a >= b)" are not the same.
In fact the usual comparison operators must be reinterpreted
as implicitely first testing if any of the operand is a Nan
and return 'false' if it is the case. Thus "a < b" becomes
"!isnan(a) && !isnan(b) && (a < b)".
If we need to negate the comparison we get "!(a < b)" which
naturally becomes "isnan(a) || isnan(b) || (a >= b)".
We thus need two sets of operators for comparison of floats:
one for the "ordered" values (only true if neither operand
is a Nan) and one for the "values" (also true if either
operand is a NaN). A negation of the comparison switch from one
of the set to the other.
So, introduce another set of instructions for the comparison
of floats.
Note: the C standard requires that:
*) "x == x" is false if x is a NaN,
*) "x != x" is true if x is a NaN,
and this is coherent with "x != x" <-> "!(x == x)".
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Diffstat (limited to 'Documentation')
| -rw-r--r-- | Documentation/IR.md | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/Documentation/IR.md b/Documentation/IR.md index e6d14e19..8d49936f 100644 --- a/Documentation/IR.md +++ b/Documentation/IR.md @@ -95,7 +95,7 @@ They all follow the same signature: #### OP_AND_BOOL #### OP_OR_BOOL -### Comparisons +### Integer compares They all have the following signature: - .src1, .src2: operands (types must be compatible) - .target: result of the operation (0/1 valued integer) @@ -131,6 +131,60 @@ Compare less-than-or-equal (unsigned). #### OP_SET_AE Compare greater-than-or-equal (unsigned). +### Floating-point compares +They all have the same signature as the integer compares. +The usual 6 operations exist in two versions: 'ordered' and +'unordered'. Theses operations first check if any operand is a +NaN and if it is the case the ordered compares return false +and then unordered return true, otherwise the result of the +comparison, now garanted to be done on non-NaNs, is returned. + +#### OP_FCMP_OEQ +Floating-point compare ordered equal + +#### OP_FCMP_ONE +Floating-point compare ordered not-equal + +#### OP_FCMP_OLE +Floating-point compare ordered less-than-or-equal + +#### OP_FCMP_OGE +Floating-point compare ordered greater-or-equal + +#### OP_FCMP_OLT +Floating-point compare ordered less-than + +#### OP_FCMP_OGT +Floating-point compare ordered greater-than + + +#### OP_FCMP_UEQ +Floating-point compare unordered equal + +#### OP_FCMP_UNE +Floating-point compare unordered not-equal + +#### OP_FCMP_ULE +Floating-point compare unordered less-than-or-equal + +#### OP_FCMP_UGE +Floating-point compare unordered greater-or-equal + +#### OP_FCMP_ULT +Floating-point compare unordered less-than + +#### OP_FCMP_UGT +Floating-point compare unordered greater-than + + +#### OP_FCMP_ORD +Floating-point compare ordered: return true if both operands are ordered +(none of the operands are a NaN) and false otherwise. + +#### OP_FCMP_UNO +Floating-point compare unordered: return false if no operands is ordered +and true otherwise. + ### Unary ops #### OP_NOT Logical not. |
