Skip to content

Commit

Permalink
[InstCombine] fix wrong undef handling when converting select to shuffle
Browse files Browse the repository at this point in the history
As discussed in:
https://bugs.llvm.org/show_bug.cgi?id=32486
...the canonicalization of vector select to shufflevector does not hold up
when undef elements are present in the condition vector. 

Try to make the undef handling clear in the code and the LangRef.

Differential Revision: https://reviews.llvm.org/D31980



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300092 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
rotateright committed Apr 12, 2017
1 parent c5de42f commit 2c5adb1
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 8 deletions.
7 changes: 4 additions & 3 deletions docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7071,9 +7071,10 @@ Semantics:
The elements of the two input vectors are numbered from left to right
across both of the vectors. The shuffle mask operand specifies, for each
element of the result vector, which element of the two input vectors the
result element gets. The element selector may be undef (meaning "don't
care") and the second operand may be undef if performing a shuffle from
only one vector.
result element gets. If the shuffle mask is undef, the result vector is
undef. If any element of the mask operand is undef, that element of the
result is undef. If the shuffle mask selects an undef element from one
of the input vectors, the resulting element is undef.

Example:
""""""""
Expand Down
6 changes: 4 additions & 2 deletions lib/Transforms/InstCombine/InstCombineSelect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1053,8 +1053,10 @@ static Instruction *canonicalizeSelectToShuffle(SelectInst &SI) {
// If the select condition element is false, choose from the 2nd vector.
Mask.push_back(ConstantInt::get(Int32Ty, i + NumElts));
} else if (isa<UndefValue>(Elt)) {
// If the select condition element is undef, the shuffle mask is undef.
Mask.push_back(UndefValue::get(Int32Ty));
// Undef in a select condition (choose one of the operands) does not mean
// the same thing as undef in a shuffle mask (any value is acceptable), so
// give up.
return nullptr;
} else {
// Bail out on a constant expression.
return nullptr;
Expand Down
17 changes: 14 additions & 3 deletions test/Transforms/InstCombine/select.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1298,11 +1298,22 @@ define <2 x i32> @select_icmp_slt0_xor_vec(<2 x i32> %x) {
ret <2 x i32> %x.xor
}

; Make sure that undef elements of the select condition are translated into undef elements of the shuffle mask.

define <4 x i32> @canonicalize_to_shuffle(<4 x i32> %a, <4 x i32> %b) {
; CHECK-LABEL: @canonicalize_to_shuffle(
; CHECK-NEXT: [[SEL:%.*]] = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 undef, i32 6, i32 undef>
; CHECK-NEXT: [[SEL:%.*]] = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 5, i32 6, i32 3>
; CHECK-NEXT: ret <4 x i32> [[SEL]]
;
%sel = select <4 x i1> <i1 true, i1 false, i1 false, i1 true>, <4 x i32> %a, <4 x i32> %b
ret <4 x i32> %sel
}

; Undef elements of the select condition may not be translated into undef elements of a shuffle mask
; because undef in a shuffle mask means we can return anything, not just one of the selected values.
; https://bugs.llvm.org/show_bug.cgi?id=32486

define <4 x i32> @undef_elts_in_condition(<4 x i32> %a, <4 x i32> %b) {
; CHECK-LABEL: @undef_elts_in_condition(
; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> <i1 true, i1 undef, i1 false, i1 undef>, <4 x i32> %a, <4 x i32> %b
; CHECK-NEXT: ret <4 x i32> [[SEL]]
;
%sel = select <4 x i1> <i1 true, i1 undef, i1 false, i1 undef>, <4 x i32> %a, <4 x i32> %b
Expand Down

0 comments on commit 2c5adb1

Please sign in to comment.