1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4; Narrow the select operands to eliminate the existing shuffles and replace a wide select with a narrow select. 5 6define <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]] 12; 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 17} 18 19; The 1st shuffle is not extending with undefs, but demanded elements corrects that. 20 21define <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]] 27; 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 32} 33 34; Verify that undef elements are acceptable for identity shuffle mask. Also check FP types. 35 36define <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]] 42; 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 47} 48 49declare void @use(<4 x i8>) 50declare void @use_cmp(<4 x i1>) 51 52; Negative test - extra use would require more instructions than we started with. 53 54define <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]] 61; 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 67} 68 69; Negative test - extra use would require more instructions than we started with. 70 71define <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]] 78; 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 84} 85 86; Negative test - mismatched types would require extra shuffling. 87 88define <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]] 94; 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 99} 100 101; Negative test - mismatched types would require extra shuffling. 102 103define <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]] 109; 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 114} 115 116; Narrowing constants does not require creating new narrowing shuffle instructions. 117 118define <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]] 122; 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 127} 128 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. 131 132define <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]] 136; 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 143} 144 145