llvm / llvm/llvm-project

[clang] VectorSplat cast for the vector shift operand always has the ExtVectorType regardless of the other operand

Open
#223,135 1 comment 0 reactions 0 assignees View on GitHub
clang:frontend
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.