1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -data-layout="n8:16:32" -S | FileCheck %s 3; RUN: opt < %s -instcombine -data-layout="n16" -S | FileCheck %s 4 5; PR35792 - https://bugs.llvm.org/show_bug.cgi?id=35792 6 7define i16 @zext_add(i8 %x) { 8; CHECK-LABEL: @zext_add( 9; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], 44 10; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]] 11; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16 12; CHECK-NEXT: ret i16 [[R]] 13; 14 %z = zext i8 %x to i16 15 %b = add i16 %z, 44 16 %r = and i16 %b, %z 17 ret i16 %r 18} 19 20define i16 @zext_sub(i8 %x) { 21; CHECK-LABEL: @zext_sub( 22; CHECK-NEXT: [[TMP1:%.*]] = sub i8 -5, [[X:%.*]] 23; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]] 24; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16 25; CHECK-NEXT: ret i16 [[R]] 26; 27 %z = zext i8 %x to i16 28 %b = sub i16 -5, %z 29 %r = and i16 %b, %z 30 ret i16 %r 31} 32 33define i16 @zext_mul(i8 %x) { 34; CHECK-LABEL: @zext_mul( 35; CHECK-NEXT: [[TMP1:%.*]] = mul i8 [[X:%.*]], 3 36; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]] 37; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16 38; CHECK-NEXT: ret i16 [[R]] 39; 40 %z = zext i8 %x to i16 41 %b = mul i16 %z, 3 42 %r = and i16 %b, %z 43 ret i16 %r 44} 45 46define i16 @zext_lshr(i8 %x) { 47; CHECK-LABEL: @zext_lshr( 48; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 [[X:%.*]], 4 49; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]] 50; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16 51; CHECK-NEXT: ret i16 [[R]] 52; 53 %z = zext i8 %x to i16 54 %b = lshr i16 %z, 4 55 %r = and i16 %b, %z 56 ret i16 %r 57} 58 59define i16 @zext_ashr(i8 %x) { 60; CHECK-LABEL: @zext_ashr( 61; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 [[X:%.*]], 2 62; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]] 63; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16 64; CHECK-NEXT: ret i16 [[R]] 65; 66 %z = zext i8 %x to i16 67 %b = ashr i16 %z, 2 68 %r = and i16 %b, %z 69 ret i16 %r 70} 71 72define i16 @zext_shl(i8 %x) { 73; CHECK-LABEL: @zext_shl( 74; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 3 75; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]] 76; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16 77; CHECK-NEXT: ret i16 [[R]] 78; 79 %z = zext i8 %x to i16 80 %b = shl i16 %z, 3 81 %r = and i16 %b, %z 82 ret i16 %r 83} 84 85define <2 x i16> @zext_add_vec(<2 x i8> %x) { 86; CHECK-LABEL: @zext_add_vec( 87; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], <i8 44, i8 42> 88; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]] 89; CHECK-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16> 90; CHECK-NEXT: ret <2 x i16> [[R]] 91; 92 %z = zext <2 x i8> %x to <2 x i16> 93 %b = add <2 x i16> %z, <i16 44, i16 42> 94 %r = and <2 x i16> %b, %z 95 ret <2 x i16> %r 96} 97 98define <2 x i16> @zext_sub_vec(<2 x i8> %x) { 99; CHECK-LABEL: @zext_sub_vec( 100; CHECK-NEXT: [[TMP1:%.*]] = sub <2 x i8> <i8 -5, i8 -4>, [[X:%.*]] 101; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]] 102; CHECK-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16> 103; CHECK-NEXT: ret <2 x i16> [[R]] 104; 105 %z = zext <2 x i8> %x to <2 x i16> 106 %b = sub <2 x i16> <i16 -5, i16 -4>, %z 107 %r = and <2 x i16> %b, %z 108 ret <2 x i16> %r 109} 110 111define <2 x i16> @zext_mul_vec(<2 x i8> %x) { 112; CHECK-LABEL: @zext_mul_vec( 113; CHECK-NEXT: [[TMP1:%.*]] = mul <2 x i8> [[X:%.*]], <i8 3, i8 -2> 114; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]] 115; CHECK-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16> 116; CHECK-NEXT: ret <2 x i16> [[R]] 117; 118 %z = zext <2 x i8> %x to <2 x i16> 119 %b = mul <2 x i16> %z, <i16 3, i16 -2> 120 %r = and <2 x i16> %b, %z 121 ret <2 x i16> %r 122} 123 124define <2 x i16> @zext_lshr_vec(<2 x i8> %x) { 125; CHECK-LABEL: @zext_lshr_vec( 126; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 4, i8 2> 127; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]] 128; CHECK-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16> 129; CHECK-NEXT: ret <2 x i16> [[R]] 130; 131 %z = zext <2 x i8> %x to <2 x i16> 132 %b = lshr <2 x i16> %z, <i16 4, i16 2> 133 %r = and <2 x i16> %b, %z 134 ret <2 x i16> %r 135} 136 137define <2 x i16> @zext_ashr_vec(<2 x i8> %x) { 138; CHECK-LABEL: @zext_ashr_vec( 139; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 2, i8 3> 140; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]] 141; CHECK-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16> 142; CHECK-NEXT: ret <2 x i16> [[R]] 143; 144 %z = zext <2 x i8> %x to <2 x i16> 145 %b = ashr <2 x i16> %z, <i16 2, i16 3> 146 %r = and <2 x i16> %b, %z 147 ret <2 x i16> %r 148} 149 150define <2 x i16> @zext_shl_vec(<2 x i8> %x) { 151; CHECK-LABEL: @zext_shl_vec( 152; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i8> [[X:%.*]], <i8 3, i8 2> 153; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]] 154; CHECK-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16> 155; CHECK-NEXT: ret <2 x i16> [[R]] 156; 157 %z = zext <2 x i8> %x to <2 x i16> 158 %b = shl <2 x i16> %z, <i16 3, i16 2> 159 %r = and <2 x i16> %b, %z 160 ret <2 x i16> %r 161} 162 163; Don't create poison by narrowing a shift below the shift amount. 164 165define <2 x i16> @zext_lshr_vec_overshift(<2 x i8> %x) { 166; CHECK-LABEL: @zext_lshr_vec_overshift( 167; CHECK-NEXT: [[Z:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i16> 168; CHECK-NEXT: [[B:%.*]] = lshr <2 x i16> [[Z]], <i16 4, i16 8> 169; CHECK-NEXT: [[R:%.*]] = and <2 x i16> [[B]], [[Z]] 170; CHECK-NEXT: ret <2 x i16> [[R]] 171; 172 %z = zext <2 x i8> %x to <2 x i16> 173 %b = lshr <2 x i16> %z, <i16 4, i16 8> 174 %r = and <2 x i16> %b, %z 175 ret <2 x i16> %r 176} 177 178define <2 x i16> @zext_lshr_vec_undef(<2 x i8> %x) { 179; CHECK-LABEL: @zext_lshr_vec_undef( 180; CHECK-NEXT: ret <2 x i16> zeroinitializer 181; 182 %z = zext <2 x i8> %x to <2 x i16> 183 %b = lshr <2 x i16> %z, undef 184 %r = and <2 x i16> %b, %z 185 ret <2 x i16> %r 186} 187 188; Don't create poison by narrowing a shift below the shift amount. 189 190define <2 x i16> @zext_shl_vec_overshift(<2 x i8> %x) { 191; CHECK-LABEL: @zext_shl_vec_overshift( 192; CHECK-NEXT: [[Z:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i16> 193; CHECK-NEXT: [[B:%.*]] = shl <2 x i16> [[Z]], <i16 8, i16 2> 194; CHECK-NEXT: [[R:%.*]] = and <2 x i16> [[B]], [[Z]] 195; CHECK-NEXT: ret <2 x i16> [[R]] 196; 197 %z = zext <2 x i8> %x to <2 x i16> 198 %b = shl <2 x i16> %z, <i16 8, i16 2> 199 %r = and <2 x i16> %b, %z 200 ret <2 x i16> %r 201} 202 203define <2 x i16> @zext_shl_vec_undef(<2 x i8> %x) { 204; CHECK-LABEL: @zext_shl_vec_undef( 205; CHECK-NEXT: ret <2 x i16> zeroinitializer 206; 207 %z = zext <2 x i8> %x to <2 x i16> 208 %b = shl <2 x i16> %z, undef 209 %r = and <2 x i16> %b, %z 210 ret <2 x i16> %r 211} 212 213