The relational select() function is very handy for vectorization and mimics the ternary ()?: op. But, the supported types in scalar and vector modes for doubles (and halfs) is inconsistent with the relational comparison functions such as isgreater().
Code :int isgreater (double a, double b); double select (double a, double b, long cmp);
Code :longn isgreater (doublen a, doublen b); doublen select (doublen a, doublen b, longn cmp);
The scalar isgreater() (and similar) functions match the c99 math.h prototypes and return int for all datatypes. But, select() only accepts long for double (and short for half). This requires an explicit cast in most (all?) implementations and makes for some headaches when building type-independent code. That is, we can't cleanly write
Code :T select (T a, T b, isgreater(a,b));
and expect it to work with double and doublen. This same issues occurs with halfs. I have to wrap an #ifdef statement to distinguish scalar and vector types.
Code :#if (__VectorSize == 1) // ()?: version // double result = (isgreater(a,b)) ? b : a; double result = select (a, b, (long) isgreater(a,b)); #else double2 result = select (a, b, isgreater(a,b)); #endif
I propose that select() accept the datatype output of the relational functions in both scalar and vector modes. That is, accept (int) for all datatypes in scalar modes and accept the equivalent bit-masks in vector mode.