This is an archive of the discontinued LLVM Phabricator instance.

[PowerPC] Implement vector bool/pixel initialization under -faltivec-src-compat=xl
ClosedPublic

Authored by amyk on Jul 15 2021, 7:15 PM.

Details

Summary

This patch implements the initialization of vectors under the -faltivec-src-compat=xl option
introduced in https://reviews.llvm.org/D103615.

Under this option, the initialization of scalar vectors, vector bool, and vector pixel are
treated the same, where the initialization value is splatted across the whole vector.

This patch does not change the behaviour of the -faltivec-src-compat=mixed option,
which is the current default for Clang.

Diff Detail

Event Timeline

amyk created this revision.Jul 15 2021, 7:15 PM
amyk requested review of this revision.Jul 15 2021, 7:15 PM
nemanjai requested changes to this revision.Jul 16 2021, 4:07 AM

Why are vector-scalar-altivec-init.c and vector-scalar-altivec-init2.c added? There is no initialization of vector bool or vector pixel in them so I don't really see the need to add them. If it is just to test that the existing behaviour doesn't change for those, you can simply add two run lines for xl and mixed to existing test cases.

Also, please unify vector-bool-pixel-altivec-init.c and vector-bool-pixel-altivec-init2.c into a single test case. It is not immediately obvious to the reader that the difference is parenthesized vs. unparenthesized initialization.

clang/include/clang/Sema/Sema.h
6097

Why take a Sema & parameter? It is called Self so presumably it is expected to point to *this. Is there a use case where it points to a different instance of Sema?

clang/lib/Sema/SemaCast.cpp
2627

No need to repeat the comment on the implementation.

clang/test/CodeGen/vector-bool-pixel-altivec-init.c
57

It is generally not safe to hard-code names of virtual registers (llvm::Value*'s) in test cases. The naming is different in Release vs. Debug builds and it could also change for any other reason as no guarantee is ever made about the names.

You should test for what's important:

  • The insertelement of the right type (save the name with [[INS:%.*]])
  • The use of that value for a shufflevector where you check the shuffle mask (presumably zeroinitializer)
This revision now requires changes to proceed.Jul 16 2021, 4:07 AM
amyk updated this revision to Diff 359358.Jul 16 2021, 9:32 AM

Update patch and touched base with Nemanja.

  • Removed the scalar vector test files that we already test for.
  • Update CHECKs in LIT tests accordingly.
  • Remove unnecessary Sema parameter in added function.
  • Keep two test files for initialization of vector bool and vector pixel with and without parentheses. The test without parentheses are separated in its own file rather than unified in a single file so we can successfully compile the parenthesized version of the test when we have faltivec-src-compat=mixed.
nemanjai accepted this revision.Jul 16 2021, 11:59 AM

LGTM other than a minor nit about a comment.

clang/include/clang/Sema/Sema.h
6093–6096
// Checks that the vector type should be initialized from a scalar
// by splatting the value rather than populating a single element.
// This is the case for AltiVecVector types as well as with
// AltiVecPixel and AltiVecBool when -faltivec-src-compat=xl
// is specified.
This revision is now accepted and ready to land.Jul 16 2021, 11:59 AM
This revision was landed with ongoing or failed builds.Jul 19 2021, 7:12 AM
This revision was automatically updated to reflect the committed changes.
q66 added a subscriber: q66.Dec 15 2021, 2:47 PM

Hi,

this warning also affects GCC-style vectors:

e.g.

typedef int myivec __attribute__((vector_size(16));
typedef float myfvec __attribute__((vector_size(16));
const myvec ret = (myfvec1 == myfvec2); // will issue a warning

Should it? This means different semantics between targets without explicitly using AltiVec vectors.

q66 added a comment.Dec 15 2021, 2:58 PM

and indeed, it affects semantics too:

/tmp$ clang++ test.cc -o test -faltivec-src-compat=xl                                                                                                                                                                          
/tmp$ ./test
b
b
b
/tmp$ clang++ test.cc -o test -faltivec-src-compat=gcc                                                                                                                                                                         
/tmp$ ./test                                                                                                                                                                                                                   
Dv4_i
Dv4_i
Dv8_s
/tmp$ clang++ test.cc -o test -faltivec-src-compat=mixed                                                                                                                                                                       
test.cc:10:20: warning: Current handling of vector bool and vector pixel types in this context are deprecated. The default behaviour will soon change to that implied by the '-altivec-compat=xl' option [-Wdeprecated-altivec-src-compat]
    auto cmp = (v1 == v2);
                   ^
test.cc:12:22: warning: Current handling of vector bool and vector pixel types in this context are deprecated. The default behaviour will soon change to that implied by the '-altivec-compat=xl' option [-Wdeprecated-altivec-src-compat]
    auto pcmp = (pv1 == pv2);
                     ^
2 warnings generated.
/tmp$ ./test                                                                                                                                                                                                                   
Dv4_i
b
Dv8_s
/tmp$ cat test.cc
#include <typeinfo>
#include <cstdio>

typedef float simd4f __attribute__((vector_size(16)));

int main() {
    simd4f v1, v2;
    vector float fv1, fv2;
    vector pixel pv1, pv2;
    auto cmp = (v1 == v2);
    auto acmp = (fv1 == fv2);
    auto pcmp = (pv1 == pv2);
    printf("%s\n", typeid(cmp).name());
    printf("%s\n", typeid(acmp).name());
    printf("%s\n", typeid(pcmp).name());
}
q66 added a comment.Dec 15 2021, 3:02 PM

On x86_64, the program predictably prints Dv4_i.

On x86_64, the program predictably prints Dv4_i.

The semantics here are not new, but the warning is emitted for generic vector types as a result of https://reviews.llvm.org/D103615. This is perhaps an oversight that should change (i.e. only emit the warning from CheckVectorCompareOperands() if the operands are vector bool/vector pixel).
@stefanp What do you think?

q66 added a comment.Dec 16 2021, 3:46 AM

Well, I'm more concerned about the actual semantics - as I see it, when using generic vectors, they should be unaffected by the comparison behavior of AltiVec vectors, which is not the case when you set the mode to xl. If the semantics are affected, it means creating a massive pain for libraries that use generic vectors without caring what platform they are in (since they will get a vector as a result of comparison on x86_64, but a bool on PowerPC). And since the behavior can be switched with a compiler flag, they don't even have a reasonable way to make this conditional in the code.

Well, I'm more concerned about the actual semantics - as I see it, when using generic vectors, they should be unaffected by the comparison behavior of AltiVec vectors, which is not the case when you set the mode to xl. If the semantics are affected, it means creating a massive pain for libraries that use generic vectors without caring what platform they are in (since they will get a vector as a result of comparison on x86_64, but a bool on PowerPC). And since the behavior can be switched with a compiler flag, they don't even have a reasonable way to make this conditional in the code.

Only users that are looking to match the XL behaviour will ever use the xl mode. I realize that the warning incorrectly states that the default behaviour will be switched to XL in the future but this is wrong (and we will correct it). Unfortunately with the XL compiler, the behaviour is to produce a bool/int when comparing two vectors regardless of whether they are Altivec vectors or generic ones.

q66 added a comment.Dec 20 2021, 11:41 AM

I see. Is there a way to compile-time-detect whether one is getting the XL behavior? This is still a potential concern for things that expose vector ops in public headers. There should be a macro of some kind to detect this at compile time and follow the XL semantics when needed.