[PATCH] D148637: [LangRef] Update shufflevector's semantics to return poison if the mask is undef

Manuel Brito via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 18 08:12:55 PDT 2023


ManuelJBrito created this revision.
ManuelJBrito added reviewers: nlopes, aqjune, spatel, RKSimon.
Herald added subscribers: StephenFan, jdoerfert.
Herald added a project: All.
ManuelJBrito requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

This patch changes the shufflevector's semantics to yield poison if the mask is undefined. This allows the extraction of shufflevectors while also opening the door for more optimization opportunities due to the fact that poison is more undefined than undef.

This is a continuation of the work done by @aqjune in D93818 <https://reviews.llvm.org/D93818>.

As described at https://github.com/llvm/llvm-project/issues/43530, here is a quick overview:

Undef in the shufflevector mask yielding undef even when the shuffled value is poison makes the following transformation invalid:

  define <4 x float> @insert_not_undef_shuffle_translate_commute(float %x, <4 x float> %y, <4 x float> %q) {
    %xv = insertelement <4 x float> %q, float %x, i32 2
    %r = shufflevector <4 x float> %y, <4 x float> %xv, <4 x i32> { 0, 6, 2, undef }
    ret <4 x float> %r
  }
  =>
  define <4 x float> @insert_not_undef_shuffle_translate_commute(float %x, <4 x float> %y, <4 x float> %q) {
    %r = insertelement <4 x float> %y, float %x, i32 1
    ret <4 x float> %r
  }
  
  float %x = poison
  <4 x float> %y = < poison, poison, poison, poison >
  <4 x float> %q = < poison, poison, poison, poison >
  
  Source:
  <4 x float> %xv = < poison, poison, poison, poison >
  <4 x float> %r = < poison, poison, poison, undef >
  
  Target:
  <4 x float> %r = < poison, poison, poison, poison >
  
  Source value: < poison, poison, poison, undef >
  Target value: < poison, poison, poison, poison >

The motivation for the current semantics was to be able to introduce shufflevectors when building a vector with a sequence of insertelements starting from an undef vector:

  %t = insertelement <4 x float> undef, float %arg, i32 1
  %t4 = insertelement <4 x float> %t, float %arg, i32 1
  %t5 = insertelement <4 x float> %t4, float %arg, i32 2
  %t6 = insertelement <4 x float> %t5, float %arg, i32 3
  ret <4 x float> %t6
  =>
  %t = insertelement <4 x float> undef, float %arg, i32 0
  %t2 = shufflevector <4 x float> %t, <4 x float> undef, <4 x i32> <i32 undef, i32 0, i32 0, i32 0>
  ret <4 x float> %t2

With the soft deprecation of undef these cases should become more rare. So these new semantics in combination with disabling these transformations when an undef placeholder is used should prevent miscompilations without meaningful regressions.

Theses cases are identified at https://web.ist.utl.pt/nuno.lopes/alive2/index.php?hash=a9bc405e427c007f with 'LLVM PR44185'.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D148637

Files:
  llvm/docs/LangRef.rst


Index: llvm/docs/LangRef.rst
===================================================================
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -10021,6 +10021,10 @@
 is an index indicating the position at which to insert the value. The
 index may be a variable of any integer type, and will be treated as an
 unsigned integer.
+``poison`` vector is used for ``val`` if the input is a don't-care vector.
+using ``undef`` for ``val`` is not recommended because it prohibits
+optimizations to '``shufflevector``' with ``poison`` masks.
+
 
 Semantics:
 """"""""""
@@ -10038,6 +10042,7 @@
 .. code-block:: text
 
       <result> = insertelement <4 x i32> %vec, i32 1, i32 0    ; yields <4 x i32>
+      <result> = insertelement <4 x i32> poison, i32 1, i32 0  ; creates <4 x i32> from a don't-care vector with the first element set to 1 and returns it
 
 .. _i_shufflevector:
 
@@ -10065,7 +10070,7 @@
 The first two operands of a '``shufflevector``' instruction are vectors
 with the same type. The third argument is a shuffle mask vector constant
 whose element type is ``i32``. The mask vector elements must be constant
-integers or ``undef`` values. The result of the instruction is a vector
+integers or ``poison`` values. The result of the instruction is a vector
 whose length is the same as the shuffle mask and whose element type is the
 same as the element type of the first two operands.
 
@@ -10078,16 +10083,22 @@
 to the result. Non-negative elements in the mask represent an index
 into the concatenated pair of input vectors.
 
-If the shuffle mask is undefined, the result vector is undefined. If
-the shuffle mask selects an undefined element from one of the input
-vectors, the resulting element is undefined. An undefined element
-in the mask vector specifies that the resulting element is undefined.
-An undefined element in the mask vector prevents a poisoned vector
-element from propagating.
+If the shuffle mask is ``poison``, the result vector is ``poison``. If
+the shuffle mask selects a ``poison`` element from one of the input vectors,
+the resulting element is ``poison``. Similarly, if an ``undef`` element
+is selected, the result is ``undef`` as well. A ``poison`` element
+in the mask vector specifies that the resulting element is ``poison``.
+
+If the shuffle mask is ``undef``, the result vector is ``poison``. An ``undef``
+element in the mask vector specifies that the resulting element is ``poison``.
+Therefore, the result of ``shufflevector`` does not change even if the
+``poison`` mask is used instead of ``undef``, and vice versa.
+LLVM's assembly printer will print ``poison`` if ``undef`` was given to the
+shuffle mask because LLVM does not distinguish between them internally.
 
 For scalable vectors, the only valid mask values at present are
-``zeroinitializer`` and ``undef``, since we cannot write all indices as
-literals for a vector with a length unknown at compile time.
+``zeroinitializer``, ``undef`` and ``poison``, since we cannot write all
+indices as literals for a vector with a length unknown at compile time.
 
 Example:
 """"""""
@@ -10096,9 +10107,9 @@
 
       <result> = shufflevector <4 x i32> %v1, <4 x i32> %v2,
                               <4 x i32> <i32 0, i32 4, i32 1, i32 5>  ; yields <4 x i32>
-      <result> = shufflevector <4 x i32> %v1, <4 x i32> undef,
+      <result> = shufflevector <4 x i32> %v1, <4 x i32> poison,
                               <4 x i32> <i32 0, i32 1, i32 2, i32 3>  ; yields <4 x i32> - Identity shuffle.
-      <result> = shufflevector <8 x i32> %v1, <8 x i32> undef,
+      <result> = shufflevector <8 x i32> %v1, <8 x i32> poison,
                               <4 x i32> <i32 0, i32 1, i32 2, i32 3>  ; yields <4 x i32>
       <result> = shufflevector <4 x i32> %v1, <4 x i32> %v2,
                               <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7 >  ; yields <8 x i32>


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D148637.514640.patch
Type: text/x-patch
Size: 3920 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230418/8f64c84d/attachment.bin>


More information about the llvm-commits mailing list