[clang] VectorSplat cast for the vector shift operand always has the ExtVectorType regardless of the other operand
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
Let's consider an example with a shift operation where one operand has VectorType and other has scalar integer:
```c
typedef int v4si __attribute__((vector_size(16)));
void foo(void)
{
v4si vec = {1,2,3,4};
long long ll = 10;
vec = vec << ll;
}
```
and look at its AST for shift operation.
```
`-BinaryOperator 'v4si':'__attribute__((__vector_size__(4 * sizeof(int)))) int' '<<'
|-ImplicitCastExpr 'v4si':'__attribute__((__vector_size__(4 * sizeof(int)))) int'
| `-DeclRefExpr 'v4si':'__attribute__((__vector_size__(4 * sizeof(int)))) int' lvalue Var 0x4486cef0 'vec' 'v4si':'__attribute__((__vector_size__(4 * sizeof(int)))) int'
`-ImplicitCastExpr 'long long __attribute__((ext_vector_type(4)))' // <- problem here
`-ImplicitCastExpr 'long long'
`-DeclRefExpr 'long long' lvalue Var 0x4486d0d8 'll' 'long long'
```
For RHS VectorSplat to ExtVectorType is built instead of usual VectorType with corresponding VectorKind.
As I can see in SemaExpr.cpp in the function checkVectorShift(), there is a mandatory cast to ExtVectorType without checking the other operand:
```c++
QualType VecTy =
S.Context.getExtVectorType(LHSEleType, RHSVecTy->getNumElements());
```
For instance, in the convertVector() function, the result type of cast is determined with the condition:
```c++
QualType NewVecTy =
VecTy->isExtVectorType()
? S.Context.getExtVectorType(ElementType, VecTy->getNumElements())
: S.Context.getVectorType(ElementType, VecTy->getNumElements(),
VecTy->getVectorKind());
```
There is one more question, but I am not sure if it's a bug or not. In the example above, the LHS operand has a size of 16 bytes, but the RHS operand has a 32-byte size because they have different element types. In user code this operation gives an error.
```
error: vector operands do not have the same elements sizes ('v4si' (vector of 4 'int' values) and 'v4di' (vector of 4 'long long' values)) [-Wvec-elem-size]
```
Should there be IntegerCast for the RHS scalar operand to element type of the LHS vector operand first, before VectorSplat?
If LHS is a scalar and RHS is a vector, there is IntegerCast before VectorSplat.
Compiler Explorer with example:
https://godbolt.org/z/49z7d8fYx
Contributor guide
Research direction
Start in SemaExpr.cpp at checkVectorShift() and compare its VectorSplat type construction with convertVector(). Reproduce the AST and diagnostic using the C example or the linked Compiler Explorer case; done means the expected vector kind and scalar-to-vector operand behavior are established and covered by an appropriate regression test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100