This is an archive of the discontinued LLVM Phabricator instance.

{Sema] Gcc compatibility of vector shift.
ClosedPublic

Authored by vbyakovlcl on Sep 16 2016, 8:09 AM.

Details

Summary

Gcc prints error if elements of left and right parts of a shift have different sizes. This patch is provided the GCC compatibility.

Diff Detail

Repository
rL LLVM

Event Timeline

vbyakovlcl updated this revision to Diff 71646.Sep 16 2016, 8:09 AM
vbyakovlcl retitled this revision from to {Sema] Gcc compatibility of vector shift..
vbyakovlcl updated this object.
vbyakovlcl added reviewers: aaron.ballman, ahatanak.
vbyakovlcl set the repository for this revision to rL LLVM.
vbyakovlcl added a subscriber: cfe-commits.
aaron.ballman edited edge metadata.Sep 21 2016, 6:47 AM

In clang 3.8, your test code already produces a diagnostic for me: http://coliru.stacked-crooked.com/a/752a4ea34123bdae

Clang 3.8 balances vector shift operand erroneous using CheckVectorOperands which converts one of operand to the type of another. In D21678 it was fixed by using checkVectorShift instead. As result clang does not emit error if shift operands have different element sizes (bat gcc does).

Clang 3.8 balances vector shift operand erroneous using CheckVectorOperands which converts one of operand to the type of another. In D21678 it was fixed by using checkVectorShift instead. As result clang does not emit error if shift operands have different element sizes (bat gcc does).

Ah, thank you for the explanation!

llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td
522 ↗(On Diff #71646)

Is this the same warning flag GCC uses?

llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
2306 ↗(On Diff #71646)

Why is this off by default?

vbyakovlcl added inline comments.Sep 26 2016, 10:07 AM
llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td
522 ↗(On Diff #71646)

Gcc prints error messages

t.c:21:13: error: invalid operands to binary << (have vector_int8 and vector_short8)

vi8 = vi8 << vs8;

I could not find a flag controlling this error.

llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
2306 ↗(On Diff #71646)

The question is: would we like to have the feature as a clang extension?

aaron.ballman added inline comments.Oct 3 2016, 1:06 PM
llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td
522 ↗(On Diff #71646)

I would not add this as a diagnostic group, but instead use an ad-hoc group on the diagnostic itself. I don't think this is going to see very many diagnostics covered by the same group, but if that turns out to be the case, we can switch then.

llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
2306 ↗(On Diff #71646)

I'm not the best one to answer that question, but we typically avoid adding new off-by-default diagnostics. Since GCC prints this as an error message and this patch is for GCC compatibility, it seems weird to me to add this as an off-by-default warning.

vbyakovlcl updated this revision to Diff 73468.Oct 4 2016, 6:32 AM
vbyakovlcl edited edge metadata.
vbyakovlcl removed rL LLVM as the repository for this revision.
vbyakovlcl added inline comments.
llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td
522 ↗(On Diff #71646)

Ok, done

llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
2306 ↗(On Diff #71646)

I did similar to GCC - error by default.

ahatanak added inline comments.Oct 4 2016, 8:32 AM
llvm/tools/clang/lib/Sema/SemaExpr.cpp
8787 ↗(On Diff #73468)

Is it possible to use ASTContext::getTypeSize here?

vbyakovlcl updated this revision to Diff 73642.Oct 5 2016, 7:13 AM
vbyakovlcl added inline comments.
llvm/tools/clang/lib/Sema/SemaExpr.cpp
8787 ↗(On Diff #73468)

You are right.

bruno added a reviewer: bruno.Oct 7 2016, 11:15 AM
bruno added a subscriber: bruno.
bruno added inline comments.
llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
2306 ↗(On Diff #73642)

Although the motivation is to support the same warning present in GCC, I think this is helpful enough anyway so that we might skip calling it "gnu-vec-elem-size" and have a more generic name instead? How about plain "vec-elem-size"?

llvm/tools/clang/lib/Sema/SemaExpr.cpp
8787 ↗(On Diff #73642)

Besides __ext_vector_type__, would this also trigger for vector_size? Right now this is an error for vector_size primarily because the number of elements is different, can you confirm this won't change?

vbyakovlcl updated this revision to Diff 74123.Oct 10 2016, 6:33 AM
vbyakovlcl added inline comments.
llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
2306 ↗(On Diff #73642)

I'm agree.

llvm/tools/clang/lib/Sema/SemaExpr.cpp
8787 ↗(On Diff #73642)

I compare vector element sizes, so there must not be any differencies caused by different triggers. I added additional type definitions to the tests. All compiles fain.

bruno added inline comments.Oct 10 2016, 2:47 PM
llvm/tools/clang/lib/Sema/SemaExpr.cpp
8787 ↗(On Diff #73642)

I don't think this is right. When I try to compile similar code for vector_size without your patch, I get the errors:

/tmp/x.c:80:15: error: vector operands do not have the same number of elements ('vector_int8n' (vector of 2 'int' values) and 'vector_uchar8n' (vector of 8 'unsigned char' values))

vi8n = vi8n << vuc8n; // expected-warning {{vector operands do not have the same elements sizes}}
       ~~~~ ^  ~~~~~

/tmp/x.c:81:17: error: vector operands do not have the same number of elements ('vector_uchar8n' (vector of 8 'unsigned char' values) and 'vector_int8n' (vector of 2 'int' values))

vuc8n = vuc8n << vi8n; // expected-warning {{vector operands do not have the same elements sizes}}
        ~~~~~ ^  ~~~~

/tmp/x.c:82:17: error: vector operands do not have the same number of elements ('vector_ushort8n' (vector of 4 'unsigned short' values) and 'vector_uint8n' (vector of 2 'unsigned int' values))

vus8n = vus8n << vui8n; // expected-warning {{vector operands do not have the same elements sizes}}
        ~~~~~ ^  ~~~~~

/tmp/x.c:83:17: error: vector operands do not have the same number of elements ('vector_uint8n' (vector of 2 'unsigned int' values) and 'vector_short8n' (vector of 4 'short' values))

vui8n = vui8n << vs8n; // expected-warning {{vector operands do not have the same elements sizes}}
        ~~~~~ ^  ~~~~

Given your test changes, it seems that now, instead of "vector operands do not have the same number of elements" we would get "vector operands do not have the same elements sizes". I rather we stay with the first. Additionally, even if we had "vector operands do not have the same elements sizes" for vector_size, this should never be demoted to a warning.

majnemer added inline comments.
llvm/tools/clang/lib/Sema/SemaExpr.cpp
8795–8798 ↗(On Diff #74123)

Why return QualType() here? Would returning LHSType provide confusing or incorrect diagnostics?

vbyakovlcl updated this revision to Diff 74269.Oct 11 2016, 9:43 AM
vbyakovlcl added inline comments.
llvm/tools/clang/lib/Sema/SemaExpr.cpp
8795–8798 ↗(On Diff #74123)

This is really excessive. Thanks.

8787 ↗(On Diff #73642)

Argument of a GNU vector size attribute specifies vector size measured in bytes(see https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html). So you got right diagnostics. Both compilers with and without my changes print the same diagnostics for yours case. Here is a small testcase used both GNU and clang extensions

$ cat bruno.c
typedef attribute((ext_vector_type(8))) int vector_int8;
typedef attribute((ext_vector_type(8))) unsigned char vector_uchar8;

typedef attribute((vector_size(8))) int vector_int8n;
typedef attribute((vector_size(8))) unsigned char vector_uchar8n;

vector_int8 vi8;
vector_uchar8 vuc8;
vector_int8n vi8n;
vector_uchar8n vuc8n;

int foo() {

vi8 = vi8 << vuc8;
vi8n = vi8n << vuc8n;

$ clang -c bruno.c -Wno-error-vec-elem-size
bruno.c:13:13: warning: vector operands do not have the same elements sizes ('vector_int8' (vector of 8 'int' values) and 'vector_uchar8' (vector of 8 'unsigned char' values)) [-Wvec-elem-size]

vi8 = vi8 << vuc8;
      ~~~ ^  ~~~~

bruno.c:14:15: error: vector operands do not have the same number of elements ('vector_int8n' (vector of 2 'int' values) and 'vector_uchar8n' (vector of 8 'unsigned char' values))

vi8n = vi8n << vuc8n;

The compiler without the changes prints the second error only (bruno.c:14:15).

bruno added inline comments.Oct 11 2016, 10:35 AM
llvm/tools/clang/lib/Sema/SemaExpr.cpp
8787 ↗(On Diff #73642)

What actually concerns me here is the following: if you invoke clang -c bruno.c -Wvec-elem-size, will that override the error: vector operands do not have the same number of elements message for vector_size typed vectors? If so, I don't think this is right.

vbyakovlcl added inline comments.Oct 11 2016, 1:41 PM
llvm/tools/clang/lib/Sema/SemaExpr.cpp
8787 ↗(On Diff #73642)

No, this will not override the error because these diagnostics use independent conditions. The option vec-elem-size is used only for controlling kind of message 'vector_element_sizes_not_equal' - warning or error. Using this flag cannot influence on the massage you worry.

$ clang bruno.c -c -Wvec-elem-size
bruno.c:13:13: error: vector operands do not have the same elements sizes ('vector_int8' (vector of 8 'int' values) and 'vector_uchar8' (vector of 8 'unsigned char' values)) [-Wvec-elem-size]

vi8 = vi8 << vuc8;
      ~~~ ^  ~~~~

bruno.c:14:15: error: vector operands do not have the same number of elements ('vector_int8n' (vector of 2 'int' values) and 'vector_uchar8n' (vector of 8 'unsigned char' values))

vi8n = vi8n << vuc8n;
       ~~~~ ^  ~~~~~

2 errors generated.

$ clang bruno.c -c -Wno-vec-elem-size
bruno.c:14:15: error: vector operands do not have the same number of elements ('vector_int8n' (vector of 2 'int' values) and 'vector_uchar8n' (vector of 8 'unsigned char' values))

vi8n = vi8n << vuc8n;
       ~~~~ ^  ~~~~~

1 error generated.
$ clang bruno.c -c -Wno-error-vec-elem-size
bruno.c:13:13: warning: vector operands do not have the same elements sizes ('vector_int8' (vector of 8 'int' values) and 'vector_uchar8' (vector of 8 'unsigned char' values)) [-Wvec-elem-size]

vi8 = vi8 << vuc8;
      ~~~ ^  ~~~~

bruno.c:14:15: error: vector operands do not have the same number of elements ('vector_int8n' (vector of 2 'int' values) and 'vector_uchar8n' (vector of 8 'unsigned char' values))

vi8n = vi8n << vuc8n;
       ~~~~ ^  ~~~~~

1 warning and 1 error generated.

bruno accepted this revision.Oct 17 2016, 10:56 AM
bruno edited edge metadata.

Ok, great!

LGTM

This revision is now accepted and ready to land.Oct 17 2016, 10:56 AM
This revision was automatically updated to reflect the committed changes.