Update to use new semantics added in D148637 .
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
This change is visible in clang in particular in codegen for the vec_promote builtin.
It now produces poison instead of undef for the undefined elements.
I think this is OK according to IBM's documentation[https://www.ibm.com/docs/en/epfz/5.3?topic=book-semantics]:
When a result or behavior is undefined, it is something you “must not” do.
Use of an undefined feature is likely to produce different results on different > implementations or releases of a PL/I product.
The application program is considered to be in error.
Adding some PowerPC folks to review the change in codegen for vec_promote.
AFAICT its OK to have the undefined values be poison.
Why this changes IR output of following case?
// RUN: clang vecpromote.c -S -o - -O0 -target s390x-linux-gnu -fzvector -emit-llvm #include <vecintrin.h> vector int si; int g; int i; void foo() { si = vec_promote(g, i); } // store <4 x i32> undef, ptr %__vec.i, align 16, !noalias !6 ; this undef becomes poison after this patch // %2 = load i32, ptr %__scalar.addr.i, align 4, !noalias !6 // %3 = load i32, ptr %__index.addr.i, align 4, !noalias !6 // %4 = load <4 x i32>, ptr %__vec.i, align 16, !noalias !6 // %vecins.i = insertelement <4 x i32> %4, i32 %2, i32 %and.i
I see no PowerPC related case changes. Maybe adding SystemZ folks for comments @uweigand @jonpa
I think it's because vec_promote is implemented in clang using a shufflevector with an undefined mask (-1).
ConstantFold sees that we have a fully undefined mask and it folds the shufflevector to poison.(previously undef)
My concern : is it Ok to have the undefined values of the vector be poison or was the undef used to abide to some specific semantics?
Hope this makes sense.
I see no PowerPC related case changes. Maybe adding SystemZ folks for comments @uweigand @jonpa
My bad I pinged the wrong people, thanks for adding SystemZ folks.
So the semantics of the vec_promote(a, b) intrinsic is defined as:
Returns a vector with a in element position b. The result is a vector with a in element position b. [...] The other elements of the vector are undefined.
This is currently implemented by using insertvector to place a at position b into a source vector that is undef. The effect should be that when using element b of that vector, we are guaranteed to get a, while using any other element is undefined behavior (just like accessing an uninitialized variable).
To be honest, I'm not sure how exactly the LLVM IR semantics changes here when using a poison source vector instead of undef. I seem to recall that poison propagates over operations - is it true that the result of insertvector on a poison vector is itself poison? If so, then this change would break semantics. However, if the result is a vector with a in element b, and poison only in the other elements, then I guess this would still preserve the expected semantics.
If a vector is fully initialized with insertvector (i.e., one operation per index), then the value of the base vector is irrelevant. It can be poison.
Poison in vectors is element-wise. <poison, 42> doesn't propagate to <poison, poison>.