is opencl-style select function supported?

hi!

does clang support the opencl-style select function on vectors?
this would mean that it generates the vectorized llvm select instruction.

-Jochen

Are you referring to the OpenCL "vec.xyzw" syntax? If so, it's implemented in Clang and is represented by ExtVectorElementExpr.

  - Doug

Are you referring to the OpenCL "vec.xyzw" syntax? If so, it's implemented in Clang and is represented by ExtVectorElementExpr.
   
no, i mean something like
float4 a,b,c,d;
float4 e = select(a, b, c < d);

clang does not seem to support
float4 e = c < d ? a : b;
for vectors, or is there a flag to switch this on?

-Jochen

I hope someone else will chime in; I'm not well-versed in the handling of vectors within Clang.

  - Doug

This is a bug in clang missing support for this OpenCL syntax.

http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20100920/034760.html

thanks for solving this problem fast, but i wonder why you do something like
result = c & a | ~c & a
instead of using the llvm select instruction, i.e.
Builder.CreateSelect(TestMSB, LHS, RHS, "select");

I also would suggest that this depends on the Altivec option instead of OpenCL.
I'd like to use vectors with C++ and therefore enable Altivec. Then I would expect
the vectorized ? : operator to work.

-Jochen

http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20100920/034760.html

thanks for solving this problem fast, but i wonder why you do something like
result = c & a | ~c & a
instead of using the llvm select instruction, i.e.
Builder.CreateSelect(TestMSB, LHS, RHS, "select");

I don't think the LLVM IR select instruction has the appropriate semantics for vectors, but I could be wrong. Doing a bitselect/blend (whatever your preferred terminology) allows the target code generators to avoid having to see <4 x i1>.

I also would suggest that this depends on the Altivec option instead of
OpenCL.
I'd like to use vectors with C++ and therefore enable Altivec. Then I
would expect
the vectorized ? : operator to work.

I'm not the right person to comment on if that's appropriate or not. I don't see a problem per se with enabling this for altivec+ext_vector_type but I'll let some other language person decide :slight_smile:

nate

http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20100920/034760.html

thanks for solving this problem fast, but i wonder why you do something like
result = c& a | ~c& a
instead of using the llvm select instruction, i.e.
Builder.CreateSelect(TestMSB, LHS, RHS, "select");
     

I don't think the LLVM IR select instruction has the appropriate semantics for vectors, but I could be wrong. Doing a bitselect/blend (whatever your preferred terminology) allows the target code generators to avoid having to see<4 x i1>.
   

the llvm documentation says that select works on vectors:
http://www.llvm.org/docs/LangRef.html#i_select

for me select is better than bitselect/blend since I analyze the llvm ir and therefore it is more convenient if the
instructions are highlevel.

I also would suggest that this depends on the Altivec option instead of
OpenCL.
I'd like to use vectors with C++ and therefore enable Altivec. Then I
would expect
the vectorized ? : operator to work.
     

I'm not the right person to comment on if that's appropriate or not. I don't see a problem per se with enabling this for altivec+ext_vector_type but I'll let some other language person decide :slight_smile:
   

Have you already asked this person or can you tell me who it is ? :wink:

-Jochen

http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20100920/034760.html

thanks for solving this problem fast, but i wonder why you do something like
result = c& a | ~c& a
instead of using the llvm select instruction, i.e.
Builder.CreateSelect(TestMSB, LHS, RHS, "select");
    

I don't think the LLVM IR select instruction has the appropriate semantics for vectors, but I could be wrong. Doing a bitselect/blend (whatever your preferred terminology) allows the target code generators to avoid having to see<4 x i1>.
  

the llvm documentation says that select works on vectors:
http://www.llvm.org/docs/LangRef.html#i_select

for me select is better than bitselect/blend since I analyze the llvm ir and therefore it is more convenient if the
instructions are highlevel.

I don't think it would be too hard to find bit-select in the IR, but this is the behavior specified by OpenCL, since that's what actually works well on most SIMD architectures. The vector compare + vector sext pattern is the current magic required to get SelectionDAGISel to generate something type legal and appropriate for SSE and AltiVec comparison operations.

I also would suggest that this depends on the Altivec option instead of
OpenCL.
I'd like to use vectors with C++ and therefore enable Altivec. Then I
would expect
the vectorized ? : operator to work.
    

I'm not the right person to comment on if that's appropriate or not. I don't see a problem per se with enabling this for altivec+ext_vector_type but I'll let some other language person decide :slight_smile:
  

Have you already asked this person or can you tell me who it is ? :wink:

I dunno who maintains C-ish stuff like this, but I think Doug Gregor or John McCall could probably weigh in.

Nate

Hi!

I have a new idea: the vector operator ? : should depend on no option at all,
because options like Altivec or OpenCL enable language extensions.
But vectors are created using e.g.
typedef float __attribute__((ext_vector_type(4))) float4;
Therefore if you have some vectors the operators +, -, *, / work and also
the operator ? : should work.

-Jochen

I think it's perfectly reasonable for ? : to work on vectors, even if neither Altivec nor OpenCL are enabled.

  - Doug

Hi!

I have a new idea: the vector operator ? : should depend on no option at
all,
because options like Altivec or OpenCL enable language extensions.
But vectors are created using e.g.
typedef float __attribute__((ext_vector_type(4))) float4;
Therefore if you have some vectors the operators +, -, *, / work and also
the operator ? : should work.

I think it's perfectly reasonable for ? : to work on vectors, even if neither Altivec nor OpenCL are enabled.

I'm not sure I agree. What are the semantics?

In my opinion, the right semantics for ?: for vectors, relative to the
C language, is that (cond ? LHS : RHS <=> (cond == 0) ? LHS : RHS. But
that isn't a very useful operation on vectors, and may be surprising
to some users. I can see an argument for implementing it just for
orthogonality.

Having ?: mean a vector select seems wrong to me.

- Daniel

It seems weird to me too, but I think the question here is not whether to have it - IIUC OpenCL demands it - but whether it makes sense to make it work conditionally only for some language flags. And IMO, if you have ?: mean vector select in one dialect, you might as well make it work in all of them.

Sebastian

I think it's perfectly reasonable for ? : to work on vectors, even if neither Altivec nor OpenCL are enabled.

I'm not sure I agree. What are the semantics?

In my opinion, the right semantics for ?: for vectors, relative to the
C language, is that (cond ? LHS : RHS <=> (cond == 0) ? LHS : RHS. But
that isn't a very useful operation on vectors, and may be surprising
to some users. I can see an argument for implementing it just for
orthogonality.

Having ?: mean a vector select seems wrong to me.

It seems weird to me too, but I think the question here is not whether to have it - IIUC OpenCL demands it - but whether it makes sense to make it work conditionally only for some language flags. And IMO, if you have ?: mean vector select in one dialect, you might as well make it work in all of them.

Why? OpenCL is a different language in many ways.

- Daniel

AltiVec vector support isn't.

Sebastian

For AltiVec support, we have precedent to follow: what does GCC do? We need to do the same.

Now, Clang's ext_vector_type is a specific vector type that Clang added for OpenCL. It seems reasonable that it would have OpenCL's semantics, regardless of dialect. For example, we permit the OpenCL "vec.xyzw" syntax for ext_vector_type vectors in all dialects.

  - Doug

It seems weird to me too, but I think the question here is not whether to have it - IIUC OpenCL demands it - but whether it makes sense to make it work conditionally only for some language flags. And IMO, if you have ?: mean vector select in one dialect, you might as well make it work in all of them.

Why? OpenCL is a different language in many ways.

AltiVec vector support isn't.

For AltiVec support, we have precedent to follow: what does GCC do? We need to do the same.

Now, Clang's ext_vector_type is a specific vector type that Clang added for OpenCL. It seems reasonable that it would have OpenCL's semantics, regardless of dialect. For example, we permit the OpenCL "vec.xyzw" syntax for ext_vector_type vectors in all dialects.

Yes, but that syntax has no (sensical) precedent in C, so programmers
aren't likely to confuse it with "what C would normally do", at least
in code that compiles.

- Daniel

I think that’s a wonderful argument against OpenCL’s abuse of the ? : notation to mean vector selection. But, OpenCL made that decision, so our only decision is whether this syntax applies to Clang’s extended vectors (the purpose of which is to support OpenCL) or to Clang when in OpenCL mode. We have precedent for the format.

Note that there’s no conversion from a vector type to bool, so

vec? vec1 : vec2

is currently ill-formed. So, while having that expression turn into a select might confuse a C programmer, at least we’re not changing the semantics of existing, well-formed code.

  • Doug

I don't know much of anything about OpenCL, Clang, or the history of this issue, but here's my $0.02: I can see a few possible versions of ?: with vectors.

1) bool ? vec1 : vec2
That is pretty unambiguous to me.

2) vector of bools ? vec1 : vec2
This too seems unambiguous. It must be a vector select (if it's legal).

3) vector comparison ? vec1 : vec2
e.g. "vec1 < vec2 ? vec1 : vec2" would be a vector minimum
How does Clang handle comparisons of its extended vector types?

As Doug pointed out, interpretations (1) and (2) are not going to be confused unless you have conversions from vector types to bool. All the other vector operations in LLVM (maybe not in Clang?) are defined to be the element-wise equivalents of the standard operations, so that would argue for allowing (2).

It seems to me that case (3) might help clarify this. If Clang allows element-wise comparisons of its extended vector types, you ought to be able to replace the vector minimum example above with: "tmp = vec1 < vec2; min = tmp ? vec1 : vec2". That would mean that case (2) should be allowed. If Clang does not support element-wise vector comparisons, is there any particular reason why not? If you want to do vector comparisons and selects with Clang's extended vectors, what is the alternative? Builtins?