1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4define i8 @shl_and_and(i8 %x, i8 %y) { 5; CHECK-LABEL: @shl_and_and( 6; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y:%.*]], [[X:%.*]] 7; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], 4 8; CHECK-NEXT: [[BW1:%.*]] = and i8 [[TMP2]], 80 9; CHECK-NEXT: ret i8 [[BW1]] 10; 11 %shift1 = shl i8 %x, 4 12 %shift2 = shl i8 %y, 4 13 %bw2 = and i8 %shift2, 88 14 %bw1 = and i8 %shift1, %bw2 15 ret i8 %bw1 16} 17 18define i8 @shl_and_and_fail(i8 %x, i8 %y) { 19; CHECK-LABEL: @shl_and_and_fail( 20; CHECK-NEXT: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], 4 21; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 [[Y:%.*]], 5 22; CHECK-NEXT: [[BW2:%.*]] = and i8 [[SHIFT2]], 64 23; CHECK-NEXT: [[BW1:%.*]] = and i8 [[SHIFT1]], [[BW2]] 24; CHECK-NEXT: ret i8 [[BW1]] 25; 26 %shift1 = shl i8 %x, 4 27 %shift2 = shl i8 %y, 5 28 %bw2 = and i8 %shift2, 88 29 %bw1 = and i8 %shift1, %bw2 30 ret i8 %bw1 31} 32 33define i8 @shl_add_add(i8 %x, i8 %y) { 34; CHECK-LABEL: @shl_add_add( 35; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], [[X:%.*]] 36; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], 2 37; CHECK-NEXT: [[BW1:%.*]] = add i8 [[TMP2]], 48 38; CHECK-NEXT: ret i8 [[BW1]] 39; 40 %shift1 = shl i8 %x, 2 41 %shift2 = shl i8 %y, 2 42 %bw2 = add i8 %shift2, 48 43 %bw1 = add i8 %shift1, %bw2 44 ret i8 %bw1 45} 46 47define i8 @shl_add_add_fail(i8 %x, i8 %y) { 48; CHECK-LABEL: @shl_add_add_fail( 49; CHECK-NEXT: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], 2 50; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 2 51; CHECK-NEXT: [[BW2:%.*]] = add nuw nsw i8 [[SHIFT2]], 48 52; CHECK-NEXT: [[BW1:%.*]] = add nuw i8 [[SHIFT1]], [[BW2]] 53; CHECK-NEXT: ret i8 [[BW1]] 54; 55 %shift1 = lshr i8 %x, 2 56 %shift2 = lshr i8 %y, 2 57 %bw2 = add i8 %shift2, 48 58 %bw1 = add i8 %shift1, %bw2 59 ret i8 %bw1 60} 61 62define i8 @shl_and_and_fail2(i8 %x, i8 %y) { 63; CHECK-LABEL: @shl_and_and_fail2( 64; CHECK-NEXT: [[SHIFT1:%.*]] = shl i8 4, [[X:%.*]] 65; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 4, [[Y:%.*]] 66; CHECK-NEXT: [[BW2:%.*]] = and i8 [[SHIFT2]], 88 67; CHECK-NEXT: [[BW1:%.*]] = and i8 [[SHIFT1]], [[BW2]] 68; CHECK-NEXT: ret i8 [[BW1]] 69; 70 %shift1 = shl i8 4, %x 71 %shift2 = shl i8 4, %y 72 %bw2 = and i8 %shift2, 88 73 %bw1 = and i8 %shift1, %bw2 74 ret i8 %bw1 75} 76 77define <2 x i8> @lshr_and_or(<2 x i8> %x, <2 x i8> %y) { 78; CHECK-LABEL: @lshr_and_or( 79; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 -64, i8 96> 80; CHECK-NEXT: [[TMP2:%.*]] = or <2 x i8> [[Y:%.*]], [[TMP1]] 81; CHECK-NEXT: [[BW1:%.*]] = lshr <2 x i8> [[TMP2]], <i8 4, i8 5> 82; CHECK-NEXT: ret <2 x i8> [[BW1]] 83; 84 %shift1 = lshr <2 x i8> %x, <i8 4, i8 5> 85 %shift2 = lshr <2 x i8> %y, <i8 4, i8 5> 86 %bw2 = and <2 x i8> %shift1, <i8 44, i8 99> 87 %bw1 = or <2 x i8> %shift2, %bw2 88 ret <2 x i8> %bw1 89} 90 91define <2 x i8> @lshr_and_or_fail(<2 x i8> %x, <2 x i8> %y) { 92; CHECK-LABEL: @lshr_and_or_fail( 93; CHECK-NEXT: [[SHIFT1:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 4, i8 5> 94; CHECK-NEXT: [[SHIFT2:%.*]] = lshr <2 x i8> [[Y:%.*]], <i8 5, i8 4> 95; CHECK-NEXT: [[BW2:%.*]] = and <2 x i8> [[SHIFT2]], <i8 44, i8 99> 96; CHECK-NEXT: [[BW1:%.*]] = or <2 x i8> [[SHIFT1]], [[BW2]] 97; CHECK-NEXT: ret <2 x i8> [[BW1]] 98; 99 %shift1 = lshr <2 x i8> %x, <i8 4, i8 5> 100 %shift2 = lshr <2 x i8> %y, <i8 5, i8 4> 101 %bw2 = and <2 x i8> %shift2, <i8 44, i8 99> 102 %bw1 = or <2 x i8> %shift1, %bw2 103 ret <2 x i8> %bw1 104} 105 106define i8 @shl_and_xor(i8 %x, i8 %y) { 107; CHECK-LABEL: @shl_and_xor( 108; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 10 109; CHECK-NEXT: [[TMP2:%.*]] = xor i8 [[Y:%.*]], [[TMP1]] 110; CHECK-NEXT: [[BW1:%.*]] = shl i8 [[TMP2]], 1 111; CHECK-NEXT: ret i8 [[BW1]] 112; 113 %shift1 = shl i8 %x, 1 114 %shift2 = shl i8 %y, 1 115 %bw2 = and i8 %shift1, 20 116 %bw1 = xor i8 %shift2, %bw2 117 ret i8 %bw1 118} 119 120define i8 @shl_and_add(i8 %x, i8 %y) { 121; CHECK-LABEL: @shl_and_add( 122; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y:%.*]], 59 123; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[X:%.*]], [[TMP1]] 124; CHECK-NEXT: [[BW1:%.*]] = shl i8 [[TMP2]], 1 125; CHECK-NEXT: ret i8 [[BW1]] 126; 127 %shift1 = shl i8 %x, 1 128 %shift2 = shl i8 %y, 1 129 %bw2 = and i8 %shift2, 119 130 %bw1 = add i8 %shift1, %bw2 131 ret i8 %bw1 132} 133 134define i8 @shl_xor_add_fail(i8 %x, i8 %y) { 135; CHECK-LABEL: @shl_xor_add_fail( 136; CHECK-NEXT: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], 1 137; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 [[Y:%.*]], 1 138; CHECK-NEXT: [[BW2:%.*]] = xor i8 [[SHIFT2]], 119 139; CHECK-NEXT: [[BW1:%.*]] = add i8 [[SHIFT1]], [[BW2]] 140; CHECK-NEXT: ret i8 [[BW1]] 141; 142 %shift1 = shl i8 %x, 1 143 %shift2 = shl i8 %y, 1 144 %bw2 = xor i8 %shift2, 119 145 %bw1 = add i8 %shift1, %bw2 146 ret i8 %bw1 147} 148 149define i8 @lshr_or_and(i8 %x, i8 %y) { 150; CHECK-LABEL: @lshr_or_and( 151; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X:%.*]], -64 152; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[Y:%.*]], [[TMP1]] 153; CHECK-NEXT: [[BW1:%.*]] = lshr i8 [[TMP2]], 5 154; CHECK-NEXT: ret i8 [[BW1]] 155; 156 %shift1 = lshr i8 %x, 5 157 %shift2 = lshr i8 %y, 5 158 %bw2 = or i8 %shift1, 198 159 %bw1 = and i8 %bw2, %shift2 160 ret i8 %bw1 161} 162 163define i8 @lshr_or_or_fail(i8 %x, i8 %y) { 164; CHECK-LABEL: @lshr_or_or_fail( 165; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Y:%.*]], [[X:%.*]] 166; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], 5 167; CHECK-NEXT: [[BW1:%.*]] = or i8 [[TMP2]], -58 168; CHECK-NEXT: ret i8 [[BW1]] 169; 170 %shift1 = lshr i8 %x, 5 171 %shift2 = lshr i8 %y, 5 172 %bw2 = or i8 %shift2, 198 173 %bw1 = or i8 %shift1, %bw2 174 ret i8 %bw1 175} 176 177define <2 x i8> @shl_xor_and(<2 x i8> %x, <2 x i8> %y) { 178; CHECK-LABEL: @shl_xor_and( 179; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i8> [[Y:%.*]], <i8 11, i8 poison> 180; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i8> [[X:%.*]], [[TMP1]] 181; CHECK-NEXT: [[BW1:%.*]] = shl <2 x i8> [[TMP2]], <i8 2, i8 poison> 182; CHECK-NEXT: ret <2 x i8> [[BW1]] 183; 184 %shift1 = shl <2 x i8> %x, <i8 2, i8 poison> 185 %shift2 = shl <2 x i8> %y, <i8 2, i8 poison> 186 %bw2 = xor <2 x i8> %shift2, <i8 44, i8 poison> 187 %bw1 = and <2 x i8> %bw2, %shift1 188 ret <2 x i8> %bw1 189} 190 191define <2 x i8> @shl_xor_and_fail(<2 x i8> %x, <2 x i8> %y) { 192; CHECK-LABEL: @shl_xor_and_fail( 193; CHECK-NEXT: [[SHIFT1:%.*]] = shl <2 x i8> [[X:%.*]], <i8 2, i8 poison> 194; CHECK-NEXT: [[SHIFT2:%.*]] = shl <2 x i8> [[Y:%.*]], <i8 poison, i8 2> 195; CHECK-NEXT: [[BW2:%.*]] = xor <2 x i8> [[SHIFT2]], <i8 44, i8 poison> 196; CHECK-NEXT: [[BW1:%.*]] = and <2 x i8> [[SHIFT1]], [[BW2]] 197; CHECK-NEXT: ret <2 x i8> [[BW1]] 198; 199 %shift1 = shl <2 x i8> %x, <i8 2, i8 poison> 200 %shift2 = shl <2 x i8> %y, <i8 poison, i8 2> 201 %bw2 = xor <2 x i8> %shift2, <i8 44, i8 poison> 202 %bw1 = and <2 x i8> %shift1, %bw2 203 ret <2 x i8> %bw1 204} 205 206define i8 @lshr_or_or_no_const(i8 %x, i8 %y, i8 %sh, i8 %mask) { 207; CHECK-LABEL: @lshr_or_or_no_const( 208; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Y:%.*]], [[X:%.*]] 209; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SH:%.*]] 210; CHECK-NEXT: [[BW1:%.*]] = or i8 [[TMP2]], [[MASK:%.*]] 211; CHECK-NEXT: ret i8 [[BW1]] 212; 213 %shift1 = lshr i8 %x, %sh 214 %shift2 = lshr i8 %y, %sh 215 %bw2 = or i8 %shift2, %mask 216 %bw1 = or i8 %shift1, %bw2 217 ret i8 %bw1 218} 219 220define i8 @lshr_or_or_no_const_fail(i8 %x, i8 %y, i8 %sh, i8 %mask) { 221; CHECK-LABEL: @lshr_or_or_no_const_fail( 222; CHECK-NEXT: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], [[SH:%.*]] 223; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], [[SH]] 224; CHECK-NEXT: [[BW2:%.*]] = or i8 [[SHIFT2]], [[MASK:%.*]] 225; CHECK-NEXT: [[BW1:%.*]] = or i8 [[SHIFT1]], [[BW2]] 226; CHECK-NEXT: ret i8 [[BW1]] 227; 228 %shift1 = shl i8 %x, %sh 229 %shift2 = lshr i8 %y, %sh 230 %bw2 = or i8 %shift2, %mask 231 %bw1 = or i8 %shift1, %bw2 232 ret i8 %bw1 233} 234 235define i8 @shl_xor_xor_no_const(i8 %x, i8 %y, i8 %sh, i8 %mask) { 236; CHECK-LABEL: @shl_xor_xor_no_const( 237; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]] 238; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], [[SH:%.*]] 239; CHECK-NEXT: [[BW1:%.*]] = xor i8 [[TMP2]], [[MASK:%.*]] 240; CHECK-NEXT: ret i8 [[BW1]] 241; 242 %shift1 = shl i8 %x, %sh 243 %shift2 = shl i8 %y, %sh 244 %bw2 = xor i8 %shift2, %mask 245 %bw1 = xor i8 %shift1, %bw2 246 ret i8 %bw1 247} 248 249define i8 @shl_xor_and_no_const_fail(i8 %x, i8 %y, i8 %sh, i8 %mask) { 250; CHECK-LABEL: @shl_xor_and_no_const_fail( 251; CHECK-NEXT: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], [[SH:%.*]] 252; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 [[Y:%.*]], [[SH]] 253; CHECK-NEXT: [[BW2:%.*]] = xor i8 [[SHIFT2]], [[MASK:%.*]] 254; CHECK-NEXT: [[BW1:%.*]] = and i8 [[SHIFT1]], [[BW2]] 255; CHECK-NEXT: ret i8 [[BW1]] 256; 257 %shift1 = shl i8 %x, %sh 258 %shift2 = shl i8 %y, %sh 259 %bw2 = xor i8 %shift2, %mask 260 %bw1 = and i8 %shift1, %bw2 261 ret i8 %bw1 262} 263 264define <2 x i8> @shl_and_and_no_const(<2 x i8> %x, <2 x i8> %y, <2 x i8> %sh, <2 x i8> %mask) { 265; CHECK-LABEL: @shl_and_and_no_const( 266; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[Y:%.*]], [[X:%.*]] 267; CHECK-NEXT: [[TMP2:%.*]] = shl <2 x i8> [[TMP1]], [[SH:%.*]] 268; CHECK-NEXT: [[BW1:%.*]] = and <2 x i8> [[TMP2]], [[MASK:%.*]] 269; CHECK-NEXT: ret <2 x i8> [[BW1]] 270; 271 %shift1 = shl <2 x i8> %x, %sh 272 %shift2 = shl <2 x i8> %y, %sh 273 %bw2 = and <2 x i8> %shift2, %mask 274 %bw1 = and <2 x i8> %shift1, %bw2 275 ret <2 x i8> %bw1 276} 277 278define i8 @shl_add_add_no_const(i8 %x, i8 %y, i8 %sh, i8 %mask) { 279; CHECK-LABEL: @shl_add_add_no_const( 280; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], [[X:%.*]] 281; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], [[SH:%.*]] 282; CHECK-NEXT: [[BW1:%.*]] = add i8 [[TMP2]], [[MASK:%.*]] 283; CHECK-NEXT: ret i8 [[BW1]] 284; 285 %shift1 = shl i8 %x, %sh 286 %shift2 = shl i8 %y, %sh 287 %bw2 = add i8 %shift2, %mask 288 %bw1 = add i8 %shift1, %bw2 289 ret i8 %bw1 290} 291 292define i8 @lshr_add_add_no_const_fail(i8 %x, i8 %y, i8 %sh, i8 %mask) { 293; CHECK-LABEL: @lshr_add_add_no_const_fail( 294; CHECK-NEXT: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], [[SH:%.*]] 295; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], [[SH]] 296; CHECK-NEXT: [[BW2:%.*]] = add i8 [[SHIFT2]], [[MASK:%.*]] 297; CHECK-NEXT: [[BW1:%.*]] = add i8 [[SHIFT1]], [[BW2]] 298; CHECK-NEXT: ret i8 [[BW1]] 299; 300 %shift1 = lshr i8 %x, %sh 301 %shift2 = lshr i8 %y, %sh 302 %bw2 = add i8 %shift2, %mask 303 %bw1 = add i8 %shift1, %bw2 304 ret i8 %bw1 305} 306 307define <2 x i8> @lshr_add_and(<2 x i8> %x, <2 x i8> %y) { 308; CHECK-LABEL: @lshr_add_and( 309; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[Y:%.*]], <i8 -8, i8 16> 310; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i8> [[X:%.*]], [[TMP1]] 311; CHECK-NEXT: [[BW1:%.*]] = lshr <2 x i8> [[TMP2]], <i8 3, i8 4> 312; CHECK-NEXT: ret <2 x i8> [[BW1]] 313; 314 %shift1 = lshr <2 x i8> %x, <i8 3, i8 4> 315 %shift2 = lshr <2 x i8> %y, <i8 3, i8 4> 316 %bw2 = add <2 x i8> %shift2, <i8 255, i8 1> 317 %bw1 = and <2 x i8> %shift1, %bw2 318 ret <2 x i8> %bw1 319} 320 321define <2 x i8> @lshr_add_or_fail_dif_masks(<2 x i8> %x, <2 x i8> %y) { 322; CHECK-LABEL: @lshr_add_or_fail_dif_masks( 323; CHECK-NEXT: [[SHIFT1:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 3, i8 4> 324; CHECK-NEXT: [[SHIFT2:%.*]] = lshr <2 x i8> [[Y:%.*]], <i8 poison, i8 3> 325; CHECK-NEXT: [[BW2:%.*]] = add nsw <2 x i8> [[SHIFT2]], <i8 -1, i8 1> 326; CHECK-NEXT: [[BW1:%.*]] = and <2 x i8> [[SHIFT1]], [[BW2]] 327; CHECK-NEXT: ret <2 x i8> [[BW1]] 328; 329 %shift1 = lshr <2 x i8> %x, <i8 3, i8 4> 330 %shift2 = lshr <2 x i8> %y, <i8 poison, i8 3> 331 %bw2 = add <2 x i8> %shift2, <i8 255, i8 1> 332 %bw1 = and <2 x i8> %shift1, %bw2 333 ret <2 x i8> %bw1 334} 335 336define <2 x i8> @shl_or_or_good_mask(<2 x i8> %x, <2 x i8> %y) { 337; CHECK-LABEL: @shl_or_or_good_mask( 338; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i8> [[Y:%.*]], [[X:%.*]] 339; CHECK-NEXT: [[TMP2:%.*]] = shl <2 x i8> [[TMP1]], splat (i8 1) 340; CHECK-NEXT: [[BW1:%.*]] = or <2 x i8> [[TMP2]], <i8 18, i8 24> 341; CHECK-NEXT: ret <2 x i8> [[BW1]] 342; 343 %shift1 = shl <2 x i8> %x, <i8 1, i8 1> 344 %shift2 = shl <2 x i8> %y, <i8 1, i8 1> 345 %bw2 = or <2 x i8> %shift2, <i8 18, i8 24> 346 %bw1 = or <2 x i8> %shift1, %bw2 347 ret <2 x i8> %bw1 348} 349 350define <2 x i8> @shl_or_or_fail_bad_mask(<2 x i8> %x, <2 x i8> %y) { 351; CHECK-LABEL: @shl_or_or_fail_bad_mask( 352; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i8> [[Y:%.*]], [[X:%.*]] 353; CHECK-NEXT: [[TMP2:%.*]] = shl <2 x i8> [[TMP1]], splat (i8 1) 354; CHECK-NEXT: [[BW1:%.*]] = or <2 x i8> [[TMP2]], <i8 19, i8 24> 355; CHECK-NEXT: ret <2 x i8> [[BW1]] 356; 357 %shift1 = shl <2 x i8> %x, <i8 1, i8 1> 358 %shift2 = shl <2 x i8> %y, <i8 1, i8 1> 359 %bw2 = or <2 x i8> %shift2, <i8 19, i8 24> 360 %bw1 = or <2 x i8> %shift1, %bw2 361 ret <2 x i8> %bw1 362} 363 364define i8 @lshr_xor_or_good_mask(i8 %x, i8 %y) { 365; CHECK-LABEL: @lshr_xor_or_good_mask( 366; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Y:%.*]], [[X:%.*]] 367; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], 4 368; CHECK-NEXT: [[BW1:%.*]] = or disjoint i8 [[TMP2]], 48 369; CHECK-NEXT: ret i8 [[BW1]] 370; 371 %shift1 = lshr i8 %x, 4 372 %shift2 = lshr i8 %y, 4 373 %bw2 = xor i8 %shift2, 48 374 %bw1 = or i8 %shift1, %bw2 375 ret i8 %bw1 376} 377 378define i8 @lshr_xor_or_fail_bad_mask(i8 %x, i8 %y) { 379; CHECK-LABEL: @lshr_xor_or_fail_bad_mask( 380; CHECK-NEXT: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], 6 381; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 6 382; CHECK-NEXT: [[BW2:%.*]] = xor i8 [[SHIFT2]], -127 383; CHECK-NEXT: [[BW1:%.*]] = or i8 [[SHIFT1]], [[BW2]] 384; CHECK-NEXT: ret i8 [[BW1]] 385; 386 %shift1 = lshr i8 %x, 6 387 %shift2 = lshr i8 %y, 6 388 %bw2 = xor i8 %shift2, 129 389 %bw1 = or i8 %shift1, %bw2 390 ret i8 %bw1 391} 392 393define <2 x i8> @lshr_or_xor_good_mask(<2 x i8> %x, <2 x i8> %y) { 394; CHECK-LABEL: @lshr_or_xor_good_mask( 395; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i8> [[Y:%.*]], <i8 -64, i8 64> 396; CHECK-NEXT: [[TMP2:%.*]] = xor <2 x i8> [[X:%.*]], [[TMP1]] 397; CHECK-NEXT: [[BW1:%.*]] = lshr <2 x i8> [[TMP2]], splat (i8 6) 398; CHECK-NEXT: ret <2 x i8> [[BW1]] 399; 400 %shift1 = lshr <2 x i8> %x, <i8 6, i8 6> 401 %shift2 = lshr <2 x i8> %y, <i8 6, i8 6> 402 %bw2 = or <2 x i8> %shift2, <i8 3, i8 1> 403 %bw1 = xor <2 x i8> %shift1, %bw2 404 ret <2 x i8> %bw1 405} 406 407define <2 x i8> @lshr_or_xor_fail_bad_mask(<2 x i8> %x, <2 x i8> %y) { 408; CHECK-LABEL: @lshr_or_xor_fail_bad_mask( 409; CHECK-NEXT: [[SHIFT1:%.*]] = lshr <2 x i8> [[X:%.*]], splat (i8 6) 410; CHECK-NEXT: [[SHIFT2:%.*]] = lshr <2 x i8> [[Y:%.*]], splat (i8 6) 411; CHECK-NEXT: [[BW2:%.*]] = or <2 x i8> [[SHIFT2]], <i8 7, i8 1> 412; CHECK-NEXT: [[BW1:%.*]] = xor <2 x i8> [[SHIFT1]], [[BW2]] 413; CHECK-NEXT: ret <2 x i8> [[BW1]] 414; 415 %shift1 = lshr <2 x i8> %x, <i8 6, i8 6> 416 %shift2 = lshr <2 x i8> %y, <i8 6, i8 6> 417 %bw2 = or <2 x i8> %shift2, <i8 7, i8 1> 418 %bw1 = xor <2 x i8> %shift1, %bw2 419 ret <2 x i8> %bw1 420} 421 422define i8 @shl_xor_xor_good_mask(i8 %x, i8 %y) { 423; CHECK-LABEL: @shl_xor_xor_good_mask( 424; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]] 425; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], 1 426; CHECK-NEXT: [[BW1:%.*]] = xor i8 [[TMP2]], 88 427; CHECK-NEXT: ret i8 [[BW1]] 428; 429 %shift1 = shl i8 %x, 1 430 %shift2 = shl i8 %y, 1 431 %bw2 = xor i8 %shift2, 88 432 %bw1 = xor i8 %shift1, %bw2 433 ret i8 %bw1 434} 435 436define i8 @shl_xor_xor_bad_mask_distribute(i8 %x, i8 %y) { 437; CHECK-LABEL: @shl_xor_xor_bad_mask_distribute( 438; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]] 439; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], 1 440; CHECK-NEXT: [[BW1:%.*]] = xor i8 [[TMP2]], -68 441; CHECK-NEXT: ret i8 [[BW1]] 442; 443 %shift1 = shl i8 %x, 1 444 %shift2 = shl i8 %y, 1 445 %bw2 = xor i8 %shift2, 188 446 %bw1 = xor i8 %shift1, %bw2 447 ret i8 %bw1 448} 449 450define i8 @shl_add_and(i8 %x, i8 %y) { 451; CHECK-LABEL: @shl_add_and( 452; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], 61 453; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]] 454; CHECK-NEXT: [[BW1:%.*]] = shl i8 [[TMP2]], 1 455; CHECK-NEXT: ret i8 [[BW1]] 456; 457 %shift1 = shl i8 %x, 1 458 %shift2 = shl i8 %y, 1 459 %bw2 = add i8 %shift2, 123 460 %bw1 = and i8 %shift1, %bw2 461 ret i8 %bw1 462} 463 464define i8 @lshr_and_add_fail(i8 %x, i8 %y) { 465; CHECK-LABEL: @lshr_and_add_fail( 466; CHECK-NEXT: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], 1 467; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 1 468; CHECK-NEXT: [[BW2:%.*]] = and i8 [[SHIFT2]], 123 469; CHECK-NEXT: [[BW1:%.*]] = add nuw i8 [[SHIFT1]], [[BW2]] 470; CHECK-NEXT: ret i8 [[BW1]] 471; 472 %shift1 = lshr i8 %x, 1 473 %shift2 = lshr i8 %y, 1 474 %bw2 = and i8 %shift2, 123 475 %bw1 = add i8 %shift1, %bw2 476 ret i8 %bw1 477} 478 479define i8 @lshr_add_or_fail(i8 %x, i8 %y) { 480; CHECK-LABEL: @lshr_add_or_fail( 481; CHECK-NEXT: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], 1 482; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 1 483; CHECK-NEXT: [[BW2:%.*]] = add nuw i8 [[SHIFT2]], 123 484; CHECK-NEXT: [[BW1:%.*]] = or i8 [[SHIFT1]], [[BW2]] 485; CHECK-NEXT: ret i8 [[BW1]] 486; 487 %shift1 = lshr i8 %x, 1 488 %shift2 = lshr i8 %y, 1 489 %bw2 = add i8 %shift2, 123 490 %bw1 = or i8 %shift1, %bw2 491 ret i8 %bw1 492} 493 494define i8 @lshr_add_xor_fail(i8 %x, i8 %y) { 495; CHECK-LABEL: @lshr_add_xor_fail( 496; CHECK-NEXT: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], 1 497; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 1 498; CHECK-NEXT: [[BW2:%.*]] = add nuw i8 [[SHIFT2]], 123 499; CHECK-NEXT: [[BW1:%.*]] = xor i8 [[SHIFT1]], [[BW2]] 500; CHECK-NEXT: ret i8 [[BW1]] 501; 502 %shift1 = lshr i8 %x, 1 503 %shift2 = lshr i8 %y, 1 504 %bw2 = add i8 %shift2, 123 505 %bw1 = xor i8 %shift1, %bw2 506 ret i8 %bw1 507} 508 509define <2 x i8> @lshr_and_add(<2 x i8> %x, <2 x i8> %y) { 510; CHECK-LABEL: @lshr_and_add( 511; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 11, i8 3> 512; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i8> [[Y:%.*]], [[TMP1]] 513; CHECK-NEXT: [[BW1:%.*]] = shl <2 x i8> [[TMP2]], <i8 4, i8 5> 514; CHECK-NEXT: ret <2 x i8> [[BW1]] 515; 516 %shift1 = shl <2 x i8> %x, <i8 4, i8 5> 517 %shift2 = shl <2 x i8> %y, <i8 4, i8 5> 518 %bw2 = and <2 x i8> %shift1, <i8 189, i8 123> 519 %bw1 = add <2 x i8> %shift2, %bw2 520 ret <2 x i8> %bw1 521} 522 523define <2 x i8> @lshr_or_add_fail(<2 x i8> %x, <2 x i8> %y) { 524; CHECK-LABEL: @lshr_or_add_fail( 525; CHECK-NEXT: [[SHIFT1:%.*]] = shl <2 x i8> [[X:%.*]], <i8 4, i8 5> 526; CHECK-NEXT: [[SHIFT2:%.*]] = shl <2 x i8> [[Y:%.*]], <i8 4, i8 5> 527; CHECK-NEXT: [[BW2:%.*]] = or <2 x i8> [[SHIFT1]], <i8 -67, i8 123> 528; CHECK-NEXT: [[BW1:%.*]] = add <2 x i8> [[SHIFT2]], [[BW2]] 529; CHECK-NEXT: ret <2 x i8> [[BW1]] 530; 531 %shift1 = shl <2 x i8> %x, <i8 4, i8 5> 532 %shift2 = shl <2 x i8> %y, <i8 4, i8 5> 533 %bw2 = or <2 x i8> %shift1, <i8 189, i8 123> 534 %bw1 = add <2 x i8> %shift2, %bw2 535 ret <2 x i8> %bw1 536} 537 538define i8 @shl_add_and_fail_mismatch_shift(i8 %x, i8 %y) { 539; CHECK-LABEL: @shl_add_and_fail_mismatch_shift( 540; CHECK-NEXT: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], 1 541; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 1 542; CHECK-NEXT: [[BW2:%.*]] = add nuw i8 [[SHIFT2]], 123 543; CHECK-NEXT: [[BW1:%.*]] = and i8 [[SHIFT1]], [[BW2]] 544; CHECK-NEXT: ret i8 [[BW1]] 545; 546 %shift1 = shl i8 %x, 1 547 %shift2 = lshr i8 %y, 1 548 %bw2 = add i8 %shift2, 123 549 %bw1 = and i8 %shift1, %bw2 550 ret i8 %bw1 551} 552 553; Fold (-x >> y) & ((x >> y) ^ -1) -> (-x & ~x) >> y 554 555define i8 @and_ashr_not(i8 %x, i8 %y, i8 %shamt) { 556; CHECK-LABEL: @and_ashr_not( 557; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -1 558; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]] 559; CHECK-NEXT: [[AND:%.*]] = ashr i8 [[TMP2]], [[SHAMT:%.*]] 560; CHECK-NEXT: ret i8 [[AND]] 561; 562 %x.shift = ashr i8 %x, %shamt 563 %y.shift = ashr i8 %y, %shamt 564 %y.shift.not = xor i8 %y.shift, -1 565 %and = and i8 %x.shift, %y.shift.not 566 ret i8 %and 567} 568 569define i8 @and_ashr_not_commuted(i8 %x, i8 %y, i8 %shamt) { 570; CHECK-LABEL: @and_ashr_not_commuted( 571; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -1 572; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]] 573; CHECK-NEXT: [[AND:%.*]] = ashr i8 [[TMP2]], [[SHAMT:%.*]] 574; CHECK-NEXT: ret i8 [[AND]] 575; 576 %x.shift = ashr i8 %x, %shamt 577 %y.shift = ashr i8 %y, %shamt 578 %y.shift.not = xor i8 %y.shift, -1 579 %and = and i8 %y.shift.not, %x.shift 580 ret i8 %and 581} 582 583; Negative test: lshr instead of ashr 584 585define i8 @and_ashr_not_fail_lshr_ashr(i8 %x, i8 %y, i8 %shamt) { 586; CHECK-LABEL: @and_ashr_not_fail_lshr_ashr( 587; CHECK-NEXT: [[X_SHIFT:%.*]] = lshr i8 [[X:%.*]], [[SHAMT:%.*]] 588; CHECK-NEXT: [[Y_SHIFT:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]] 589; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -1 590; CHECK-NEXT: [[AND:%.*]] = and i8 [[X_SHIFT]], [[Y_SHIFT_NOT]] 591; CHECK-NEXT: ret i8 [[AND]] 592; 593 %x.shift = lshr i8 %x, %shamt 594 %y.shift = ashr i8 %y, %shamt 595 %y.shift.not = xor i8 %y.shift, -1 596 %and = and i8 %x.shift, %y.shift.not 597 ret i8 %and 598} 599 600; Negative test: lshr instead of ashr 601 602define i8 @and_ashr_not_fail_ashr_lshr(i8 %x, i8 %y, i8 %shamt) { 603; CHECK-LABEL: @and_ashr_not_fail_ashr_lshr( 604; CHECK-NEXT: [[X_SHIFT:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]] 605; CHECK-NEXT: [[Y_SHIFT:%.*]] = lshr i8 [[Y:%.*]], [[SHAMT]] 606; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -1 607; CHECK-NEXT: [[AND:%.*]] = and i8 [[X_SHIFT]], [[Y_SHIFT_NOT]] 608; CHECK-NEXT: ret i8 [[AND]] 609; 610 %x.shift = ashr i8 %x, %shamt 611 %y.shift = lshr i8 %y, %shamt 612 %y.shift.not = xor i8 %y.shift, -1 613 %and = and i8 %x.shift, %y.shift.not 614 ret i8 %and 615} 616 617; Negative test: invalid xor constant 618 619define i8 @and_ashr_not_fail_invalid_xor_constant(i8 %x, i8 %y, i8 %shamt) { 620; CHECK-LABEL: @and_ashr_not_fail_invalid_xor_constant( 621; CHECK-NEXT: [[X_SHIFT:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]] 622; CHECK-NEXT: [[Y_SHIFT:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]] 623; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -2 624; CHECK-NEXT: [[AND:%.*]] = and i8 [[X_SHIFT]], [[Y_SHIFT_NOT]] 625; CHECK-NEXT: ret i8 [[AND]] 626; 627 %x.shift = ashr i8 %x, %shamt 628 %y.shift = ashr i8 %y, %shamt 629 %y.shift.not = xor i8 %y.shift, -2 630 %and = and i8 %x.shift, %y.shift.not 631 ret i8 %and 632} 633 634define <4 x i8> @and_ashr_not_vec(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { 635; CHECK-LABEL: @and_ashr_not_vec( 636; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], splat (i8 -1) 637; CHECK-NEXT: [[TMP2:%.*]] = and <4 x i8> [[X:%.*]], [[TMP1]] 638; CHECK-NEXT: [[AND:%.*]] = ashr <4 x i8> [[TMP2]], [[SHAMT:%.*]] 639; CHECK-NEXT: ret <4 x i8> [[AND]] 640; 641 %x.shift = ashr <4 x i8> %x, %shamt 642 %y.shift = ashr <4 x i8> %y, %shamt 643 %y.shift.not = xor <4 x i8> %y.shift, <i8 -1, i8 -1, i8 -1, i8 -1> 644 %and = and <4 x i8> %x.shift, %y.shift.not 645 ret <4 x i8> %and 646} 647 648define <4 x i8> @and_ashr_not_vec_commuted(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { 649; CHECK-LABEL: @and_ashr_not_vec_commuted( 650; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], splat (i8 -1) 651; CHECK-NEXT: [[TMP2:%.*]] = and <4 x i8> [[X:%.*]], [[TMP1]] 652; CHECK-NEXT: [[AND:%.*]] = ashr <4 x i8> [[TMP2]], [[SHAMT:%.*]] 653; CHECK-NEXT: ret <4 x i8> [[AND]] 654; 655 %x.shift = ashr <4 x i8> %x, %shamt 656 %y.shift = ashr <4 x i8> %y, %shamt 657 %y.shift.not = xor <4 x i8> %y.shift, <i8 -1, i8 -1, i8 -1, i8 -1> 658 %and = and <4 x i8> %y.shift.not, %x.shift 659 ret <4 x i8> %and 660} 661 662define <4 x i8> @and_ashr_not_vec_poison_1(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { 663; CHECK-LABEL: @and_ashr_not_vec_poison_1( 664; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], splat (i8 -1) 665; CHECK-NEXT: [[TMP2:%.*]] = and <4 x i8> [[X:%.*]], [[TMP1]] 666; CHECK-NEXT: [[AND:%.*]] = ashr <4 x i8> [[TMP2]], [[SHAMT:%.*]] 667; CHECK-NEXT: ret <4 x i8> [[AND]] 668; 669 %x.shift = ashr <4 x i8> %x, %shamt 670 %y.shift = ashr <4 x i8> %y, %shamt 671 %y.shift.not = xor <4 x i8> %y.shift, <i8 -1, i8 poison, i8 poison, i8 poison> 672 %and = and <4 x i8> %x.shift, %y.shift.not 673 ret <4 x i8> %and 674} 675 676define <4 x i8> @and_ashr_not_vec_poison_2(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { 677; CHECK-LABEL: @and_ashr_not_vec_poison_2( 678; CHECK-NEXT: ret <4 x i8> poison 679; 680 %x.shift = ashr <4 x i8> %x, %shamt 681 %y.shift = ashr <4 x i8> %y, %shamt 682 %y.shift.not = xor <4 x i8> %y.shift, <i8 poison, i8 poison, i8 poison, i8 poison> 683 %and = and <4 x i8> %x.shift, %y.shift.not 684 ret <4 x i8> %and 685} 686 687; Fold (-x >> y) | ((x >> y) ^ -1) -> (-x | ~x) >> y 688 689define i8 @or_ashr_not(i8 %x, i8 %y, i8 %shamt) { 690; CHECK-LABEL: @or_ashr_not( 691; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -1 692; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[X:%.*]], [[TMP1]] 693; CHECK-NEXT: [[OR:%.*]] = ashr i8 [[TMP2]], [[SHAMT:%.*]] 694; CHECK-NEXT: ret i8 [[OR]] 695; 696 %x.shift = ashr i8 %x, %shamt 697 %y.shift = ashr i8 %y, %shamt 698 %y.shift.not = xor i8 %y.shift, -1 699 %or = or i8 %x.shift, %y.shift.not 700 ret i8 %or 701} 702 703define i8 @or_ashr_not_commuted(i8 %x, i8 %y, i8 %shamt) { 704; CHECK-LABEL: @or_ashr_not_commuted( 705; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -1 706; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[X:%.*]], [[TMP1]] 707; CHECK-NEXT: [[OR:%.*]] = ashr i8 [[TMP2]], [[SHAMT:%.*]] 708; CHECK-NEXT: ret i8 [[OR]] 709; 710 %x.shift = ashr i8 %x, %shamt 711 %y.shift = ashr i8 %y, %shamt 712 %y.shift.not = xor i8 %y.shift, -1 713 %or = or i8 %y.shift.not, %x.shift 714 ret i8 %or 715} 716 717; Negative test: lshr instead of ashr 718 719define i8 @or_ashr_not_fail_lshr_ashr(i8 %x, i8 %y, i8 %shamt) { 720; CHECK-LABEL: @or_ashr_not_fail_lshr_ashr( 721; CHECK-NEXT: [[X_SHIFT:%.*]] = lshr i8 [[X:%.*]], [[SHAMT:%.*]] 722; CHECK-NEXT: [[Y_SHIFT:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]] 723; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -1 724; CHECK-NEXT: [[OR:%.*]] = or i8 [[X_SHIFT]], [[Y_SHIFT_NOT]] 725; CHECK-NEXT: ret i8 [[OR]] 726; 727 %x.shift = lshr i8 %x, %shamt 728 %y.shift = ashr i8 %y, %shamt 729 %y.shift.not = xor i8 %y.shift, -1 730 %or = or i8 %x.shift, %y.shift.not 731 ret i8 %or 732} 733 734; Negative test: lshr instead of ashr 735 736define i8 @or_ashr_not_fail_ashr_lshr(i8 %x, i8 %y, i8 %shamt) { 737; CHECK-LABEL: @or_ashr_not_fail_ashr_lshr( 738; CHECK-NEXT: [[X_SHIFT:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]] 739; CHECK-NEXT: [[Y_SHIFT:%.*]] = lshr i8 [[Y:%.*]], [[SHAMT]] 740; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -1 741; CHECK-NEXT: [[OR:%.*]] = or i8 [[X_SHIFT]], [[Y_SHIFT_NOT]] 742; CHECK-NEXT: ret i8 [[OR]] 743; 744 %x.shift = ashr i8 %x, %shamt 745 %y.shift = lshr i8 %y, %shamt 746 %y.shift.not = xor i8 %y.shift, -1 747 %or = or i8 %x.shift, %y.shift.not 748 ret i8 %or 749} 750 751; Negative test: invalid xor constant 752 753define i8 @or_ashr_not_fail_invalid_xor_constant(i8 %x, i8 %y, i8 %shamt) { 754; CHECK-LABEL: @or_ashr_not_fail_invalid_xor_constant( 755; CHECK-NEXT: [[X_SHIFT:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]] 756; CHECK-NEXT: [[Y_SHIFT:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]] 757; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -2 758; CHECK-NEXT: [[OR:%.*]] = or i8 [[X_SHIFT]], [[Y_SHIFT_NOT]] 759; CHECK-NEXT: ret i8 [[OR]] 760; 761 %x.shift = ashr i8 %x, %shamt 762 %y.shift = ashr i8 %y, %shamt 763 %y.shift.not = xor i8 %y.shift, -2 764 %or = or i8 %x.shift, %y.shift.not 765 ret i8 %or 766} 767 768define <4 x i8> @or_ashr_not_vec(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { 769; CHECK-LABEL: @or_ashr_not_vec( 770; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], splat (i8 -1) 771; CHECK-NEXT: [[TMP2:%.*]] = or <4 x i8> [[X:%.*]], [[TMP1]] 772; CHECK-NEXT: [[OR:%.*]] = ashr <4 x i8> [[TMP2]], [[SHAMT:%.*]] 773; CHECK-NEXT: ret <4 x i8> [[OR]] 774; 775 %x.shift = ashr <4 x i8> %x, %shamt 776 %y.shift = ashr <4 x i8> %y, %shamt 777 %y.shift.not = xor <4 x i8> %y.shift, <i8 -1, i8 -1, i8 -1, i8 -1> 778 %or = or <4 x i8> %x.shift, %y.shift.not 779 ret <4 x i8> %or 780} 781 782define <4 x i8> @or_ashr_not_vec_commuted(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { 783; CHECK-LABEL: @or_ashr_not_vec_commuted( 784; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], splat (i8 -1) 785; CHECK-NEXT: [[TMP2:%.*]] = or <4 x i8> [[X:%.*]], [[TMP1]] 786; CHECK-NEXT: [[OR:%.*]] = ashr <4 x i8> [[TMP2]], [[SHAMT:%.*]] 787; CHECK-NEXT: ret <4 x i8> [[OR]] 788; 789 %x.shift = ashr <4 x i8> %x, %shamt 790 %y.shift = ashr <4 x i8> %y, %shamt 791 %y.shift.not = xor <4 x i8> %y.shift, <i8 -1, i8 -1, i8 -1, i8 -1> 792 %or = or <4 x i8> %y.shift.not, %x.shift 793 ret <4 x i8> %or 794} 795 796define <4 x i8> @or_ashr_not_vec_poison_1(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { 797; CHECK-LABEL: @or_ashr_not_vec_poison_1( 798; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], splat (i8 -1) 799; CHECK-NEXT: [[TMP2:%.*]] = or <4 x i8> [[X:%.*]], [[TMP1]] 800; CHECK-NEXT: [[OR:%.*]] = ashr <4 x i8> [[TMP2]], [[SHAMT:%.*]] 801; CHECK-NEXT: ret <4 x i8> [[OR]] 802; 803 %x.shift = ashr <4 x i8> %x, %shamt 804 %y.shift = ashr <4 x i8> %y, %shamt 805 %y.shift.not = xor <4 x i8> %y.shift, <i8 -1, i8 poison, i8 poison, i8 poison> 806 %or = or <4 x i8> %x.shift, %y.shift.not 807 ret <4 x i8> %or 808} 809 810define <4 x i8> @or_ashr_not_vec_poison_2(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { 811; CHECK-LABEL: @or_ashr_not_vec_poison_2( 812; CHECK-NEXT: ret <4 x i8> poison 813; 814 %x.shift = ashr <4 x i8> %x, %shamt 815 %y.shift = ashr <4 x i8> %y, %shamt 816 %y.shift.not = xor <4 x i8> %y.shift, <i8 poison, i8 poison, i8 poison, i8 poison> 817 %or = or <4 x i8> %x.shift, %y.shift.not 818 ret <4 x i8> %or 819} 820 821; Fold (-x >> y) ^ ((x >> y) ^ -1) -> (-x ^ ~x) >> y 822 823define i8 @xor_ashr_not(i8 %x, i8 %y, i8 %shamt) { 824; CHECK-LABEL: @xor_ashr_not( 825; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]] 826; CHECK-NEXT: [[DOTNOT:%.*]] = ashr i8 [[TMP1]], [[SHAMT:%.*]] 827; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[DOTNOT]], -1 828; CHECK-NEXT: ret i8 [[XOR]] 829; 830 %x.shift = ashr i8 %x, %shamt 831 %y.shift = ashr i8 %y, %shamt 832 %y.shift.not = xor i8 %y.shift, -1 833 %xor = xor i8 %x.shift, %y.shift.not 834 ret i8 %xor 835} 836 837define i8 @xor_ashr_not_commuted(i8 %x, i8 %y, i8 %shamt) { 838; CHECK-LABEL: @xor_ashr_not_commuted( 839; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]] 840; CHECK-NEXT: [[DOTNOT:%.*]] = ashr i8 [[TMP1]], [[SHAMT:%.*]] 841; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[DOTNOT]], -1 842; CHECK-NEXT: ret i8 [[XOR]] 843; 844 %x.shift = ashr i8 %x, %shamt 845 %y.shift = ashr i8 %y, %shamt 846 %y.shift.not = xor i8 %y.shift, -1 847 %xor = xor i8 %y.shift.not, %x.shift 848 ret i8 %xor 849} 850 851; Negative test: lshr instead of ashr 852 853define i8 @xor_ashr_not_fail_lshr_ashr(i8 %x, i8 %y, i8 %shamt) { 854; CHECK-LABEL: @xor_ashr_not_fail_lshr_ashr( 855; CHECK-NEXT: [[X_SHIFT:%.*]] = lshr i8 [[X:%.*]], [[SHAMT:%.*]] 856; CHECK-NEXT: [[Y_SHIFT:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]] 857; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y_SHIFT]], [[X_SHIFT]] 858; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[TMP1]], -1 859; CHECK-NEXT: ret i8 [[XOR]] 860; 861 %x.shift = lshr i8 %x, %shamt 862 %y.shift = ashr i8 %y, %shamt 863 %y.shift.not = xor i8 %y.shift, -1 864 %xor = xor i8 %x.shift, %y.shift.not 865 ret i8 %xor 866} 867 868; Negative test: lshr instead of ashr 869 870define i8 @xor_ashr_not_fail_ashr_lshr(i8 %x, i8 %y, i8 %shamt) { 871; CHECK-LABEL: @xor_ashr_not_fail_ashr_lshr( 872; CHECK-NEXT: [[X_SHIFT:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]] 873; CHECK-NEXT: [[Y_SHIFT:%.*]] = lshr i8 [[Y:%.*]], [[SHAMT]] 874; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y_SHIFT]], [[X_SHIFT]] 875; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[TMP1]], -1 876; CHECK-NEXT: ret i8 [[XOR]] 877; 878 %x.shift = ashr i8 %x, %shamt 879 %y.shift = lshr i8 %y, %shamt 880 %y.shift.not = xor i8 %y.shift, -1 881 %xor = xor i8 %x.shift, %y.shift.not 882 ret i8 %xor 883} 884 885; Negative test: invalid xor constant 886 887define i8 @xor_ashr_not_fail_invalid_xor_constant(i8 %x, i8 %y, i8 %shamt) { 888; CHECK-LABEL: @xor_ashr_not_fail_invalid_xor_constant( 889; CHECK-NEXT: [[Y_SHIFT1:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]] 890; CHECK-NEXT: [[TMP1:%.*]] = ashr i8 [[Y_SHIFT1]], [[SHAMT:%.*]] 891; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[TMP1]], -2 892; CHECK-NEXT: ret i8 [[XOR]] 893; 894 %x.shift = ashr i8 %x, %shamt 895 %y.shift = ashr i8 %y, %shamt 896 %y.shift.not = xor i8 %y.shift, -2 897 %xor = xor i8 %x.shift, %y.shift.not 898 ret i8 %xor 899} 900 901define <4 x i8> @xor_ashr_not_vec(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { 902; CHECK-LABEL: @xor_ashr_not_vec( 903; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], [[X:%.*]] 904; CHECK-NEXT: [[DOTNOT:%.*]] = ashr <4 x i8> [[TMP1]], [[SHAMT:%.*]] 905; CHECK-NEXT: [[XOR:%.*]] = xor <4 x i8> [[DOTNOT]], splat (i8 -1) 906; CHECK-NEXT: ret <4 x i8> [[XOR]] 907; 908 %x.shift = ashr <4 x i8> %x, %shamt 909 %y.shift = ashr <4 x i8> %y, %shamt 910 %y.shift.not = xor <4 x i8> %y.shift, <i8 -1, i8 -1, i8 -1, i8 -1> 911 %xor = xor <4 x i8> %x.shift, %y.shift.not 912 ret <4 x i8> %xor 913} 914 915define <4 x i8> @xor_ashr_not_vec_commuted(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { 916; CHECK-LABEL: @xor_ashr_not_vec_commuted( 917; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], [[X:%.*]] 918; CHECK-NEXT: [[DOTNOT:%.*]] = ashr <4 x i8> [[TMP1]], [[SHAMT:%.*]] 919; CHECK-NEXT: [[XOR:%.*]] = xor <4 x i8> [[DOTNOT]], splat (i8 -1) 920; CHECK-NEXT: ret <4 x i8> [[XOR]] 921; 922 %x.shift = ashr <4 x i8> %x, %shamt 923 %y.shift = ashr <4 x i8> %y, %shamt 924 %y.shift.not = xor <4 x i8> %y.shift, <i8 -1, i8 -1, i8 -1, i8 -1> 925 %xor = xor <4 x i8> %y.shift.not, %x.shift 926 ret <4 x i8> %xor 927} 928 929define <4 x i8> @xor_ashr_not_vec_poison_1(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { 930; CHECK-LABEL: @xor_ashr_not_vec_poison_1( 931; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], [[X:%.*]] 932; CHECK-NEXT: [[DOTNOT:%.*]] = ashr <4 x i8> [[TMP1]], [[SHAMT:%.*]] 933; CHECK-NEXT: [[XOR:%.*]] = xor <4 x i8> [[DOTNOT]], splat (i8 -1) 934; CHECK-NEXT: ret <4 x i8> [[XOR]] 935; 936 %x.shift = ashr <4 x i8> %x, %shamt 937 %y.shift = ashr <4 x i8> %y, %shamt 938 %y.shift.not = xor <4 x i8> %y.shift, <i8 -1, i8 poison, i8 poison, i8 poison> 939 %xor = xor <4 x i8> %x.shift, %y.shift.not 940 ret <4 x i8> %xor 941} 942 943define <4 x i8> @xor_ashr_not_vec_poison_2(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { 944; CHECK-LABEL: @xor_ashr_not_vec_poison_2( 945; CHECK-NEXT: ret <4 x i8> poison 946; 947 %x.shift = ashr <4 x i8> %x, %shamt 948 %y.shift = ashr <4 x i8> %y, %shamt 949 %y.shift.not = xor <4 x i8> %y.shift, <i8 poison, i8 poison, i8 poison, i8 poison> 950 %xor = xor <4 x i8> %x.shift, %y.shift.not 951 ret <4 x i8> %xor 952} 953 954; Negative test: invalid binop 955 956define i8 @binop_ashr_not_fail_invalid_binop(i8 %x, i8 %y, i8 %shamt) { 957; CHECK-LABEL: @binop_ashr_not_fail_invalid_binop( 958; CHECK-NEXT: [[X_SHIFT:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]] 959; CHECK-NEXT: [[Y_SHIFT:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]] 960; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -1 961; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X_SHIFT]], [[Y_SHIFT_NOT]] 962; CHECK-NEXT: ret i8 [[ADD]] 963; 964 %x.shift = ashr i8 %x, %shamt 965 %y.shift = ashr i8 %y, %shamt 966 %y.shift.not = xor i8 %y.shift, -1 967 %add = add i8 %x.shift, %y.shift.not 968 ret i8 %add 969} 970