[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / InstCombine / shuffle-select-narrow.ll
blobbf9609623d89c092e7e9f4a28b5e480e644eaa82
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 ; Narrow the select operands to eliminate the existing shuffles and replace a wide select with a narrow select.
6 define <2 x i8> @narrow_shuffle_of_select(<2 x i1> %cmp, <4 x i8> %x, <4 x i8> %y) {
7 ; CHECK-LABEL: @narrow_shuffle_of_select(
8 ; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> undef, <2 x i32> <i32 0, i32 1>
9 ; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i8> [[Y:%.*]], <4 x i8> undef, <2 x i32> <i32 0, i32 1>
10 ; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i8> [[TMP1]], <2 x i8> [[TMP2]]
11 ; CHECK-NEXT:    ret <2 x i8> [[R]]
13   %widecmp = shufflevector <2 x i1> %cmp, <2 x i1> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
14   %widesel = select <4 x i1> %widecmp, <4 x i8> %x, <4 x i8> %y
15   %r = shufflevector <4 x i8> %widesel, <4 x i8> undef, <2 x i32> <i32 0, i32 1>
16   ret <2 x i8> %r
19 ; The 1st shuffle is not extending with undefs, but demanded elements corrects that.
21 define <2 x i8> @narrow_shuffle_of_select_overspecified_extend(<2 x i1> %cmp, <4 x i8> %x, <4 x i8> %y) {
22 ; CHECK-LABEL: @narrow_shuffle_of_select_overspecified_extend(
23 ; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> undef, <2 x i32> <i32 0, i32 1>
24 ; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i8> [[Y:%.*]], <4 x i8> undef, <2 x i32> <i32 0, i32 1>
25 ; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i8> [[TMP1]], <2 x i8> [[TMP2]]
26 ; CHECK-NEXT:    ret <2 x i8> [[R]]
28   %widecmp = shufflevector <2 x i1> %cmp, <2 x i1> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
29   %widesel = select <4 x i1> %widecmp, <4 x i8> %x, <4 x i8> %y
30   %r = shufflevector <4 x i8> %widesel, <4 x i8> undef, <2 x i32> <i32 0, i32 1>
31   ret <2 x i8> %r
34 ; Verify that undef elements are acceptable for identity shuffle mask. Also check FP types.
36 define <3 x float> @narrow_shuffle_of_select_undefs(<3 x i1> %cmp, <4 x float> %x, <4 x float> %y) {
37 ; CHECK-LABEL: @narrow_shuffle_of_select_undefs(
38 ; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[X:%.*]], <4 x float> undef, <3 x i32> <i32 0, i32 1, i32 undef>
39 ; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x float> [[Y:%.*]], <4 x float> undef, <3 x i32> <i32 0, i32 1, i32 undef>
40 ; CHECK-NEXT:    [[R:%.*]] = select <3 x i1> [[CMP:%.*]], <3 x float> [[TMP1]], <3 x float> [[TMP2]]
41 ; CHECK-NEXT:    ret <3 x float> [[R]]
43   %widecmp = shufflevector <3 x i1> %cmp, <3 x i1> undef, <4 x i32> <i32 undef, i32 1, i32 2, i32 undef>
44   %widesel = select <4 x i1> %widecmp, <4 x float> %x, <4 x float> %y
45   %r = shufflevector <4 x float> %widesel, <4 x float> undef, <3 x i32> <i32 0, i32 1, i32 undef>
46   ret <3 x float> %r
49 declare void @use(<4 x i8>)
50 declare void @use_cmp(<4 x i1>)
52 ; Negative test - extra use would require more instructions than we started with.
54 define <2 x i8> @narrow_shuffle_of_select_use1(<2 x i1> %cmp, <4 x i8> %x, <4 x i8> %y) {
55 ; CHECK-LABEL: @narrow_shuffle_of_select_use1(
56 ; CHECK-NEXT:    [[WIDECMP:%.*]] = shufflevector <2 x i1> [[CMP:%.*]], <2 x i1> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
57 ; CHECK-NEXT:    [[WIDESEL:%.*]] = select <4 x i1> [[WIDECMP]], <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]]
58 ; CHECK-NEXT:    call void @use(<4 x i8> [[WIDESEL]])
59 ; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i8> [[WIDESEL]], <4 x i8> undef, <2 x i32> <i32 0, i32 1>
60 ; CHECK-NEXT:    ret <2 x i8> [[R]]
62   %widecmp = shufflevector <2 x i1> %cmp, <2 x i1> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
63   %widesel = select <4 x i1> %widecmp, <4 x i8> %x, <4 x i8> %y
64   call void @use(<4 x i8> %widesel)
65   %r = shufflevector <4 x i8> %widesel, <4 x i8> undef, <2 x i32> <i32 0, i32 1>
66   ret <2 x i8> %r
69 ; Negative test - extra use would require more instructions than we started with.
71 define <2 x i8> @narrow_shuffle_of_select_use2(<2 x i1> %cmp, <4 x i8> %x, <4 x i8> %y) {
72 ; CHECK-LABEL: @narrow_shuffle_of_select_use2(
73 ; CHECK-NEXT:    [[WIDECMP:%.*]] = shufflevector <2 x i1> [[CMP:%.*]], <2 x i1> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
74 ; CHECK-NEXT:    call void @use_cmp(<4 x i1> [[WIDECMP]])
75 ; CHECK-NEXT:    [[WIDESEL:%.*]] = select <4 x i1> [[WIDECMP]], <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]]
76 ; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i8> [[WIDESEL]], <4 x i8> undef, <2 x i32> <i32 0, i32 1>
77 ; CHECK-NEXT:    ret <2 x i8> [[R]]
79   %widecmp = shufflevector <2 x i1> %cmp, <2 x i1> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
80   call void @use_cmp(<4 x i1> %widecmp)
81   %widesel = select <4 x i1> %widecmp, <4 x i8> %x, <4 x i8> %y
82   %r = shufflevector <4 x i8> %widesel, <4 x i8> undef, <2 x i32> <i32 0, i32 1>
83   ret <2 x i8> %r
86 ; Negative test - mismatched types would require extra shuffling.
88 define <3 x i8> @narrow_shuffle_of_select_mismatch_types1(<2 x i1> %cmp, <4 x i8> %x, <4 x i8> %y) {
89 ; CHECK-LABEL: @narrow_shuffle_of_select_mismatch_types1(
90 ; CHECK-NEXT:    [[WIDECMP:%.*]] = shufflevector <2 x i1> [[CMP:%.*]], <2 x i1> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
91 ; CHECK-NEXT:    [[WIDESEL:%.*]] = select <4 x i1> [[WIDECMP]], <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]]
92 ; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i8> [[WIDESEL]], <4 x i8> undef, <3 x i32> <i32 0, i32 1, i32 2>
93 ; CHECK-NEXT:    ret <3 x i8> [[R]]
95   %widecmp = shufflevector <2 x i1> %cmp, <2 x i1> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
96   %widesel = select <4 x i1> %widecmp, <4 x i8> %x, <4 x i8> %y
97   %r = shufflevector <4 x i8> %widesel, <4 x i8> undef, <3 x i32> <i32 0, i32 1, i32 2>
98   ret <3 x i8> %r
101 ; Negative test - mismatched types would require extra shuffling.
103 define <3 x i8> @narrow_shuffle_of_select_mismatch_types2(<4 x i1> %cmp, <6 x i8> %x, <6 x i8> %y) {
104 ; CHECK-LABEL: @narrow_shuffle_of_select_mismatch_types2(
105 ; CHECK-NEXT:    [[WIDECMP:%.*]] = shufflevector <4 x i1> [[CMP:%.*]], <4 x i1> undef, <6 x i32> <i32 0, i32 1, i32 2, i32 undef, i32 undef, i32 undef>
106 ; CHECK-NEXT:    [[WIDESEL:%.*]] = select <6 x i1> [[WIDECMP]], <6 x i8> [[X:%.*]], <6 x i8> [[Y:%.*]]
107 ; CHECK-NEXT:    [[R:%.*]] = shufflevector <6 x i8> [[WIDESEL]], <6 x i8> undef, <3 x i32> <i32 0, i32 1, i32 2>
108 ; CHECK-NEXT:    ret <3 x i8> [[R]]
110   %widecmp = shufflevector <4 x i1> %cmp, <4 x i1> undef, <6 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef>
111   %widesel = select <6 x i1> %widecmp, <6 x i8> %x, <6 x i8> %y
112   %r = shufflevector <6 x i8> %widesel, <6 x i8> undef, <3 x i32> <i32 0, i32 1, i32 2>
113   ret <3 x i8> %r
116 ; Narrowing constants does not require creating new narrowing shuffle instructions.
118 define <2 x i8> @narrow_shuffle_of_select_consts(<2 x i1> %cmp) {
119 ; CHECK-LABEL: @narrow_shuffle_of_select_consts(
120 ; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i8> <i8 -1, i8 -2>, <2 x i8> <i8 1, i8 2>
121 ; CHECK-NEXT:    ret <2 x i8> [[R]]
123   %widecmp = shufflevector <2 x i1> %cmp, <2 x i1> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
124   %widesel = select <4 x i1> %widecmp, <4 x i8> <i8 -1, i8 -2, i8 -3, i8 -4>, <4 x i8> <i8 1, i8 2, i8 3, i8 4>
125   %r = shufflevector <4 x i8> %widesel, <4 x i8> undef, <2 x i32> <i32 0, i32 1>
126   ret <2 x i8> %r
129 ; PR38691 - https://bugs.llvm.org/show_bug.cgi?id=38691
130 ; If the operands are widened only to be narrowed back, then all of the shuffles are unnecessary.
132 define <2 x i8> @narrow_shuffle_of_select_with_widened_ops(<2 x i1> %cmp, <2 x i8> %x, <2 x i8> %y) {
133 ; CHECK-LABEL: @narrow_shuffle_of_select_with_widened_ops(
134 ; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]
135 ; CHECK-NEXT:    ret <2 x i8> [[R]]
137   %widex = shufflevector <2 x i8> %x, <2 x i8> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
138   %widey = shufflevector <2 x i8> %y, <2 x i8> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
139   %widecmp = shufflevector <2 x i1> %cmp, <2 x i1> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
140   %widesel = select <4 x i1> %widecmp, <4 x i8> %widex, <4 x i8> %widey
141   %r = shufflevector <4 x i8> %widesel, <4 x i8> undef, <2 x i32> <i32 0, i32 1>
142   ret <2 x i8> %r