Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are ordered and unordered LLVM CmpInst compare instructions?

Tags:

llvm

The definition of CmpInst::Predicate type in "llvm/IR/InstrTypes.h" which describes the type of compare instruction in LLVM goes like this:

enum Predicate {
  // Opcode              U L G E    Intuitive operation
  FCMP_FALSE =  0,  ///< 0 0 0 0    Always false (always folded)
  FCMP_OEQ   =  1,  ///< 0 0 0 1    True if ordered and equal
  FCMP_OGT   =  2,  ///< 0 0 1 0    True if ordered and greater than
  FCMP_OGE   =  3,  ///< 0 0 1 1    True if ordered and greater than or equal
  FCMP_OLT   =  4,  ///< 0 1 0 0    True if ordered and less than
  FCMP_OLE   =  5,  ///< 0 1 0 1    True if ordered and less than or equal
  FCMP_ONE   =  6,  ///< 0 1 1 0    True if ordered and operands are unequal
  FCMP_ORD   =  7,  ///< 0 1 1 1    True if ordered (no nans)
  FCMP_UNO   =  8,  ///< 1 0 0 0    True if unordered: isnan(X) | isnan(Y)
  FCMP_UEQ   =  9,  ///< 1 0 0 1    True if unordered or equal
  FCMP_UGT   = 10,  ///< 1 0 1 0    True if unordered or greater than
  FCMP_UGE   = 11,  ///< 1 0 1 1    True if unordered, greater than, or equal
  FCMP_ULT   = 12,  ///< 1 1 0 0    True if unordered or less than
  FCMP_ULE   = 13,  ///< 1 1 0 1    True if unordered, less than, or equal
  FCMP_UNE   = 14,  ///< 1 1 1 0    True if unordered or not equal
  FCMP_TRUE  = 15,  ///< 1 1 1 1    Always true (always folded)
  FIRST_FCMP_PREDICATE = FCMP_FALSE,
  LAST_FCMP_PREDICATE = FCMP_TRUE,
  BAD_FCMP_PREDICATE = FCMP_TRUE + 1,
  ICMP_EQ    = 32,  ///< equal
  ICMP_NE    = 33,  ///< not equal
  ICMP_UGT   = 34,  ///< unsigned greater than
  ICMP_UGE   = 35,  ///< unsigned greater or equal
  ICMP_ULT   = 36,  ///< unsigned less than
  ICMP_ULE   = 37,  ///< unsigned less or equal
  ICMP_SGT   = 38,  ///< signed greater than
  ICMP_SGE   = 39,  ///< signed greater or equal
  ICMP_SLT   = 40,  ///< signed less than
  ICMP_SLE   = 41,  ///< signed less or equal
  FIRST_ICMP_PREDICATE = ICMP_EQ,
  LAST_ICMP_PREDICATE = ICMP_SLE,
  BAD_ICMP_PREDICATE = ICMP_SLE + 1
};

I am wondering what are "ordered" and "unordered" predicates (like "if ordered and equal" or "if unordered, greater than, or equal" compared to the normal ones that are just "unsigned greater or equal").

like image 812
Stanislav Pankevich Avatar asked Oct 30 '16 09:10

Stanislav Pankevich


1 Answers

If you don't know what NaN is, start from the last paragraph :)

Ordered and unordered floating point comparisons are different on what the result of comparison is if at least one of the operands are NaN. See fcmp instruction in the IR lang ref for more details. In particular this sentence is important: "Ordered means that neither operand is a QNAN while unordered means that either operand may be a QNAN". Note that LLVM (AFAIK) does not support SNaN, that is why lang ref exclusively talks about QNaN.

The reason for the naming is that NaN cannot be compared with floating point numbers. You cannot say NaN is smaller or larger than zero. So NaN is unordered. So unordered comparison return true if one of the operands is NaN. Ordered comparison expects both operands to be numbers.

This is the wikipedia page on NaN if you need background on that. Briefly speaking when the result of some floating point computation is not a number, a special result is generated that is called NaN (Not a Number). For example `std::sqrt' generates NaN if you ask for the square root of a negative number. There are two variants of NaN. SNaN and QNan. Wikipedia describes it. For the purpose of your question, you can ignore the difference as only QNaN matters. SNaN is not supported by LLVM AFAIK.

like image 105
esam Avatar answered Oct 22 '22 10:10

esam