1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4define i32 @select_0_or_1_from_bool(i1 %x) { 5; CHECK-LABEL: @select_0_or_1_from_bool( 6; CHECK-NEXT: [[NOT_X:%.*]] = xor i1 [[X:%.*]], true 7; CHECK-NEXT: [[ADD:%.*]] = zext i1 [[NOT_X]] to i32 8; CHECK-NEXT: ret i32 [[ADD]] 9; 10 %ext = sext i1 %x to i32 11 %add = add i32 %ext, 1 12 ret i32 %add 13} 14 15define <2 x i32> @select_0_or_1_from_bool_vec(<2 x i1> %x) { 16; CHECK-LABEL: @select_0_or_1_from_bool_vec( 17; CHECK-NEXT: [[NOT_X:%.*]] = xor <2 x i1> [[X:%.*]], <i1 true, i1 true> 18; CHECK-NEXT: [[ADD:%.*]] = zext <2 x i1> [[NOT_X]] to <2 x i32> 19; CHECK-NEXT: ret <2 x i32> [[ADD]] 20; 21 %ext = sext <2 x i1> %x to <2 x i32> 22 %add = add <2 x i32> %ext, <i32 1, i32 1> 23 ret <2 x i32> %add 24} 25 26define i32 @select_C_minus_1_or_C_from_bool(i1 %x) { 27; CHECK-LABEL: @select_C_minus_1_or_C_from_bool( 28; CHECK-NEXT: [[ADD:%.*]] = select i1 [[X:%.*]], i32 41, i32 42 29; CHECK-NEXT: ret i32 [[ADD]] 30; 31 %ext = sext i1 %x to i32 32 %add = add i32 %ext, 42 33 ret i32 %add 34} 35 36define <2 x i32> @select_C_minus_1_or_C_from_bool_vec(<2 x i1> %x) { 37; CHECK-LABEL: @select_C_minus_1_or_C_from_bool_vec( 38; CHECK-NEXT: [[ADD:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> <i32 41, i32 42>, <2 x i32> <i32 42, i32 43> 39; CHECK-NEXT: ret <2 x i32> [[ADD]] 40; 41 %ext = sext <2 x i1> %x to <2 x i32> 42 %add = add <2 x i32> %ext, <i32 42, i32 43> 43 ret <2 x i32> %add 44} 45 46; This is an 'andn' of the low bit. 47 48define i32 @flip_and_mask(i32 %x) { 49; CHECK-LABEL: @flip_and_mask( 50; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 1 51; CHECK-NEXT: [[INC:%.*]] = xor i32 [[TMP1]], 1 52; CHECK-NEXT: ret i32 [[INC]] 53; 54 %shl = shl i32 %x, 31 55 %shr = ashr i32 %shl, 31 56 %inc = add i32 %shr, 1 57 ret i32 %inc 58} 59 60define <2 x i8> @flip_and_mask_splat(<2 x i8> %x) { 61; CHECK-LABEL: @flip_and_mask_splat( 62; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 1, i8 1> 63; CHECK-NEXT: [[INC:%.*]] = xor <2 x i8> [[TMP1]], <i8 1, i8 1> 64; CHECK-NEXT: ret <2 x i8> [[INC]] 65; 66 %shl = shl <2 x i8> %x, <i8 7, i8 7> 67 %shr = ashr <2 x i8> %shl, <i8 7, i8 7> 68 %inc = add <2 x i8> %shr, <i8 1, i8 1> 69 ret <2 x i8> %inc 70} 71 72define i32 @test1(i32 %A) { 73; CHECK-LABEL: @test1( 74; CHECK-NEXT: ret i32 [[A:%.*]] 75; 76 %B = add i32 %A, 0 77 ret i32 %B 78} 79 80define i32 @test2(i32 %A) { 81; CHECK-LABEL: @test2( 82; CHECK-NEXT: ret i32 [[A:%.*]] 83; 84 %B = add i32 %A, 5 85 %C = add i32 %B, -5 86 ret i32 %C 87} 88 89define i32 @test3(i32 %A) { 90; CHECK-LABEL: @test3( 91; CHECK-NEXT: ret i32 [[A:%.*]] 92; 93 %B = add i32 %A, 5 94 %C = sub i32 %B, 5 95 ret i32 %C 96} 97 98; D = B + -A = B - A 99define i32 @test4(i32 %A, i32 %B) { 100; CHECK-LABEL: @test4( 101; CHECK-NEXT: [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]] 102; CHECK-NEXT: ret i32 [[D]] 103; 104 %C = sub i32 0, %A 105 %D = add i32 %B, %C 106 ret i32 %D 107} 108 109; D = -A + B = B - A 110define i32 @test5(i32 %A, i32 %B) { 111; CHECK-LABEL: @test5( 112; CHECK-NEXT: [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]] 113; CHECK-NEXT: ret i32 [[D]] 114; 115 %C = sub i32 0, %A 116 %D = add i32 %C, %B 117 ret i32 %D 118} 119 120define <2 x i8> @neg_op0_vec_undef_elt(<2 x i8> %a, <2 x i8> %b) { 121; CHECK-LABEL: @neg_op0_vec_undef_elt( 122; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> [[B:%.*]], [[A:%.*]] 123; CHECK-NEXT: ret <2 x i8> [[R]] 124; 125 %nega = sub <2 x i8> <i8 0, i8 undef>, %a 126 %r = add <2 x i8> %nega, %b 127 ret <2 x i8> %r 128} 129 130define <2 x i8> @neg_neg_vec_undef_elt(<2 x i8> %a, <2 x i8> %b) { 131; CHECK-LABEL: @neg_neg_vec_undef_elt( 132; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[A:%.*]], [[B:%.*]] 133; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]] 134; CHECK-NEXT: ret <2 x i8> [[R]] 135; 136 %nega = sub <2 x i8> <i8 undef, i8 0>, %a 137 %negb = sub <2 x i8> <i8 undef, i8 0>, %b 138 %r = add <2 x i8> %nega, %negb 139 ret <2 x i8> %r 140} 141 142; C = 7*A+A == 8*A == A << 3 143define i32 @test6(i32 %A) { 144; CHECK-LABEL: @test6( 145; CHECK-NEXT: [[C:%.*]] = shl i32 [[A:%.*]], 3 146; CHECK-NEXT: ret i32 [[C]] 147; 148 %B = mul i32 7, %A 149 %C = add i32 %B, %A 150 ret i32 %C 151} 152 153; C = A+7*A == 8*A == A << 3 154define i32 @test7(i32 %A) { 155; CHECK-LABEL: @test7( 156; CHECK-NEXT: [[C:%.*]] = shl i32 [[A:%.*]], 3 157; CHECK-NEXT: ret i32 [[C]] 158; 159 %B = mul i32 7, %A 160 %C = add i32 %A, %B 161 ret i32 %C 162} 163 164; (A & C1)+(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0 165define i32 @test8(i32 %A, i32 %B) { 166; CHECK-LABEL: @test8( 167; CHECK-NEXT: [[A1:%.*]] = and i32 [[A:%.*]], 7 168; CHECK-NEXT: [[B1:%.*]] = and i32 [[B:%.*]], 128 169; CHECK-NEXT: [[C:%.*]] = or i32 [[A1]], [[B1]] 170; CHECK-NEXT: ret i32 [[C]] 171; 172 %A1 = and i32 %A, 7 173 %B1 = and i32 %B, 128 174 %C = add i32 %A1, %B1 175 ret i32 %C 176} 177 178define i32 @test9(i32 %A) { 179; CHECK-LABEL: @test9( 180; CHECK-NEXT: [[C:%.*]] = shl i32 [[A:%.*]], 5 181; CHECK-NEXT: ret i32 [[C]] 182; 183 %B = shl i32 %A, 4 184 %C = add i32 %B, %B 185 ret i32 %C 186} 187 188; a != -b 189define i1 @test10(i8 %a, i8 %b) { 190; CHECK-LABEL: @test10( 191; CHECK-NEXT: [[ADD:%.*]] = sub i8 0, [[B:%.*]] 192; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[ADD]], [[A:%.*]] 193; CHECK-NEXT: ret i1 [[C]] 194; 195 %add = add i8 %a, %b 196 %c = icmp ne i8 %add, 0 197 ret i1 %c 198} 199 200define <2 x i1> @test10vec(<2 x i8> %a, <2 x i8> %b) { 201; CHECK-LABEL: @test10vec( 202; CHECK-NEXT: [[C:%.*]] = sub <2 x i8> zeroinitializer, [[B:%.*]] 203; CHECK-NEXT: [[D:%.*]] = icmp ne <2 x i8> [[C]], [[A:%.*]] 204; CHECK-NEXT: ret <2 x i1> [[D]] 205; 206 %c = add <2 x i8> %a, %b 207 %d = icmp ne <2 x i8> %c, zeroinitializer 208 ret <2 x i1> %d 209} 210 211define i1 @test11(i8 %A) { 212; CHECK-LABEL: @test11( 213; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A:%.*]], 1 214; CHECK-NEXT: ret i1 [[C]] 215; 216 %B = add i8 %A, -1 217 %c = icmp ne i8 %B, 0 218 ret i1 %c 219} 220 221define <2 x i1> @test11vec(<2 x i8> %a) { 222; CHECK-LABEL: @test11vec( 223; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[A:%.*]], <i8 1, i8 1> 224; CHECK-NEXT: ret <2 x i1> [[C]] 225; 226 %b = add <2 x i8> %a, <i8 -1, i8 -1> 227 %c = icmp ne <2 x i8> %b, zeroinitializer 228 ret <2 x i1> %c 229} 230 231define i8 @reassoc_shl1(i8 %x, i8 %y) { 232; CHECK-LABEL: @reassoc_shl1( 233; CHECK-NEXT: [[REASS_ADD:%.*]] = shl i8 [[X:%.*]], 1 234; CHECK-NEXT: [[R:%.*]] = add i8 [[REASS_ADD]], [[Y:%.*]] 235; CHECK-NEXT: ret i8 [[R]] 236; 237 %a = add i8 %y, %x 238 %r = add i8 %a, %x 239 ret i8 %r 240} 241 242define <2 x i8> @reassoc_shl1_commute1(<2 x i8> %x, <2 x i8> %y) { 243; CHECK-LABEL: @reassoc_shl1_commute1( 244; CHECK-NEXT: [[REASS_ADD:%.*]] = shl <2 x i8> [[X:%.*]], <i8 1, i8 1> 245; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[REASS_ADD]], [[Y:%.*]] 246; CHECK-NEXT: ret <2 x i8> [[R]] 247; 248 %a = add <2 x i8> %x, %y 249 %r = add <2 x i8> %a, %x 250 ret <2 x i8> %r 251} 252 253define i8 @reassoc_shl1_commute2(i8 %px, i8 %py) { 254; CHECK-LABEL: @reassoc_shl1_commute2( 255; CHECK-NEXT: [[X:%.*]] = sdiv i8 42, [[PX:%.*]] 256; CHECK-NEXT: [[Y:%.*]] = sdiv i8 43, [[PY:%.*]] 257; CHECK-NEXT: [[REASS_ADD:%.*]] = shl i8 [[X]], 1 258; CHECK-NEXT: [[R:%.*]] = add i8 [[Y]], [[REASS_ADD]] 259; CHECK-NEXT: ret i8 [[R]] 260; 261 %x = sdiv i8 42, %px ; thwart complexity-based canonicalization 262 %y = sdiv i8 43, %py ; thwart complexity-based canonicalization 263 %a = add i8 %y, %x 264 %r = add i8 %x, %a 265 ret i8 %r 266} 267 268define i8 @reassoc_shl1_commute3(i8 %px, i8 %py) { 269; CHECK-LABEL: @reassoc_shl1_commute3( 270; CHECK-NEXT: [[X:%.*]] = sdiv i8 42, [[PX:%.*]] 271; CHECK-NEXT: [[Y:%.*]] = sdiv i8 43, [[PY:%.*]] 272; CHECK-NEXT: [[REASS_ADD:%.*]] = shl i8 [[X]], 1 273; CHECK-NEXT: [[R:%.*]] = add i8 [[Y]], [[REASS_ADD]] 274; CHECK-NEXT: ret i8 [[R]] 275; 276 %x = sdiv i8 42, %px ; thwart complexity-based canonicalization 277 %y = sdiv i8 43, %py ; thwart complexity-based canonicalization 278 %a = add i8 %x, %y 279 %r = add i8 %x, %a 280 ret i8 %r 281} 282 283declare void @use(i8) 284 285define i8 @reassoc_shl1_extra_use(i8 %x, i8 %y) { 286; CHECK-LABEL: @reassoc_shl1_extra_use( 287; CHECK-NEXT: [[A:%.*]] = add i8 [[Y:%.*]], [[X:%.*]] 288; CHECK-NEXT: call void @use(i8 [[A]]) 289; CHECK-NEXT: [[R:%.*]] = add i8 [[A]], [[X]] 290; CHECK-NEXT: ret i8 [[R]] 291; 292 %a = add i8 %y, %x 293 call void @use(i8 %a) 294 %r = add i8 %a, %x 295 ret i8 %r 296} 297 298;; TODO: shl A, 1? 299define i32 @test13(i32 %A, i32 %B, i32 %C) { 300; CHECK-LABEL: @test13( 301; CHECK-NEXT: [[D_OK:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 302; CHECK-NEXT: [[E_OK:%.*]] = add i32 [[D_OK]], [[C:%.*]] 303; CHECK-NEXT: [[F:%.*]] = add i32 [[E_OK]], [[A]] 304; CHECK-NEXT: ret i32 [[F]] 305; 306 %D_OK = add i32 %A, %B 307 %E_OK = add i32 %D_OK, %C 308 %F = add i32 %E_OK, %A 309 ret i32 %F 310} 311 312define i32 @test14(i32 %offset, i32 %difference) { 313; CHECK-LABEL: @test14( 314; CHECK-NEXT: [[TMP_2:%.*]] = and i32 [[DIFFERENCE:%.*]], 3 315; CHECK-NEXT: [[TMP_3_OK:%.*]] = add i32 [[TMP_2]], [[OFFSET:%.*]] 316; CHECK-NEXT: [[TMP_5_MASK:%.*]] = and i32 [[DIFFERENCE]], -4 317; CHECK-NEXT: [[TMP_8:%.*]] = add i32 [[TMP_3_OK]], [[TMP_5_MASK]] 318; CHECK-NEXT: ret i32 [[TMP_8]] 319; 320 %tmp.2 = and i32 %difference, 3 321 %tmp.3_OK = add i32 %tmp.2, %offset 322 %tmp.5.mask = and i32 %difference, -4 323 ; == add %offset, %difference 324 %tmp.8 = add i32 %tmp.3_OK, %tmp.5.mask 325 ret i32 %tmp.8 326} 327 328; Only one bit set 329define i8 @test15(i8 %A) { 330; CHECK-LABEL: @test15( 331; CHECK-NEXT: [[C:%.*]] = and i8 [[A:%.*]], 16 332; CHECK-NEXT: ret i8 [[C]] 333; 334 %B = add i8 %A, -64 335 %C = and i8 %B, 16 336 ret i8 %C 337} 338 339define i32 @test17(i32 %A) { 340; CHECK-LABEL: @test17( 341; CHECK-NEXT: [[C:%.*]] = sub i32 0, [[A:%.*]] 342; CHECK-NEXT: ret i32 [[C]] 343; 344 %B = xor i32 %A, -1 345 %C = add i32 %B, 1 346 ret i32 %C 347} 348 349define i8 @test18(i8 %A) { 350; CHECK-LABEL: @test18( 351; CHECK-NEXT: [[C:%.*]] = sub i8 16, [[A:%.*]] 352; CHECK-NEXT: ret i8 [[C]] 353; 354 %B = xor i8 %A, -1 355 %C = add i8 %B, 17 356 ret i8 %C 357} 358 359define <2 x i64> @test18vec(<2 x i64> %A) { 360; CHECK-LABEL: @test18vec( 361; CHECK-NEXT: [[ADD:%.*]] = sub <2 x i64> <i64 1, i64 2>, [[A:%.*]] 362; CHECK-NEXT: ret <2 x i64> [[ADD]] 363; 364 %xor = xor <2 x i64> %A, <i64 -1, i64 -1> 365 %add = add <2 x i64> %xor, <i64 2, i64 3> 366 ret <2 x i64> %add 367} 368 369define i32 @test19(i1 %C) { 370; CHECK-LABEL: @test19( 371; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 1123, i32 133 372; CHECK-NEXT: ret i32 [[V]] 373; 374 %A = select i1 %C, i32 1000, i32 10 375 %V = add i32 %A, 123 376 ret i32 %V 377} 378 379define <2 x i32> @test19vec(i1 %C) { 380; CHECK-LABEL: @test19vec( 381; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 1123>, <2 x i32> <i32 133, i32 133> 382; CHECK-NEXT: ret <2 x i32> [[V]] 383; 384 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10> 385 %V = add <2 x i32> %A, <i32 123, i32 123> 386 ret <2 x i32> %V 387} 388 389; This is an InstSimplify fold, but test it here to make sure that 390; InstCombine does not prevent the fold. 391; With NSW, add of sign bit -> or of sign bit. 392 393define i32 @test20(i32 %x) { 394; CHECK-LABEL: @test20( 395; CHECK-NEXT: ret i32 [[X:%.*]] 396; 397 %y = xor i32 %x, -2147483648 398 %z = add nsw i32 %y, -2147483648 399 ret i32 %z 400} 401 402define i32 @xor_sign_bit(i32 %x) { 403; CHECK-LABEL: @xor_sign_bit( 404; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], -2147483606 405; CHECK-NEXT: ret i32 [[ADD]] 406; 407 %xor = xor i32 %x, 2147483648 408 %add = add i32 %xor, 42 409 ret i32 %add 410} 411 412define <2 x i32> @xor_sign_bit_vec_splat(<2 x i32> %x) { 413; CHECK-LABEL: @xor_sign_bit_vec_splat( 414; CHECK-NEXT: [[ADD:%.*]] = add <2 x i32> [[X:%.*]], <i32 -2147483606, i32 -2147483606> 415; CHECK-NEXT: ret <2 x i32> [[ADD]] 416; 417 %xor = xor <2 x i32> %x, <i32 2147483648, i32 2147483648> 418 %add = add <2 x i32> %xor, <i32 42, i32 42> 419 ret <2 x i32> %add 420} 421 422; No-wrap info allows converting the add to 'or'. 423 424define i8 @add_nsw_signbit(i8 %x) { 425; CHECK-LABEL: @add_nsw_signbit( 426; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], -128 427; CHECK-NEXT: ret i8 [[Y]] 428; 429 %y = add nsw i8 %x, -128 430 ret i8 %y 431} 432 433; No-wrap info allows converting the add to 'or'. 434 435define i8 @add_nuw_signbit(i8 %x) { 436; CHECK-LABEL: @add_nuw_signbit( 437; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], -128 438; CHECK-NEXT: ret i8 [[Y]] 439; 440 %y = add nuw i8 %x, 128 441 ret i8 %y 442} 443 444define i32 @add_nsw_sext_add(i8 %x) { 445; CHECK-LABEL: @add_nsw_sext_add( 446; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32 447; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[TMP1]], 398 448; CHECK-NEXT: ret i32 [[R]] 449; 450 %add = add nsw i8 %x, 42 451 %ext = sext i8 %add to i32 452 %r = add i32 %ext, 356 453 ret i32 %r 454} 455 456; Negative test - extra use of the sext means increase of instructions. 457 458define i32 @add_nsw_sext_add_extra_use_1(i8 %x, i32* %p) { 459; CHECK-LABEL: @add_nsw_sext_add_extra_use_1( 460; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[X:%.*]], 42 461; CHECK-NEXT: [[EXT:%.*]] = sext i8 [[ADD]] to i32 462; CHECK-NEXT: store i32 [[EXT]], i32* [[P:%.*]], align 4 463; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[EXT]], 356 464; CHECK-NEXT: ret i32 [[R]] 465; 466 %add = add nsw i8 %x, 42 467 %ext = sext i8 %add to i32 468 store i32 %ext, i32* %p 469 %r = add i32 %ext, 356 470 ret i32 %r 471} 472 473define <2 x i32> @add_nsw_sext_add_vec_extra_use_2(<2 x i8> %x, <2 x i8>* %p) { 474; CHECK-LABEL: @add_nsw_sext_add_vec_extra_use_2( 475; CHECK-NEXT: [[ADD:%.*]] = add nsw <2 x i8> [[X:%.*]], <i8 42, i8 -5> 476; CHECK-NEXT: store <2 x i8> [[ADD]], <2 x i8>* [[P:%.*]], align 2 477; CHECK-NEXT: [[TMP1:%.*]] = sext <2 x i8> [[X]] to <2 x i32> 478; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i32> [[TMP1]], <i32 398, i32 7> 479; CHECK-NEXT: ret <2 x i32> [[R]] 480; 481 %add = add nsw <2 x i8> %x, <i8 42, i8 -5> 482 store <2 x i8> %add, <2 x i8>* %p 483 %ext = sext <2 x i8> %add to <2 x i32> 484 %r = add <2 x i32> %ext, <i32 356, i32 12> 485 ret <2 x i32> %r 486} 487 488define <2 x i32> @add_nuw_zext_add_vec(<2 x i16> %x) { 489; CHECK-LABEL: @add_nuw_zext_add_vec( 490; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i16> [[X:%.*]] to <2 x i32> 491; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i32> [[TMP1]], <i32 65850, i32 -7> 492; CHECK-NEXT: ret <2 x i32> [[R]] 493; 494 %add = add nuw <2 x i16> %x, <i16 -42, i16 5> 495 %ext = zext <2 x i16> %add to <2 x i32> 496 %r = add <2 x i32> %ext, <i32 356, i32 -12> 497 ret <2 x i32> %r 498} 499 500; Negative test - extra use of the zext means increase of instructions. 501 502define i64 @add_nuw_zext_add_extra_use_1(i8 %x, i64* %p) { 503; CHECK-LABEL: @add_nuw_zext_add_extra_use_1( 504; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[X:%.*]], 42 505; CHECK-NEXT: [[EXT:%.*]] = zext i8 [[ADD]] to i64 506; CHECK-NEXT: store i64 [[EXT]], i64* [[P:%.*]], align 4 507; CHECK-NEXT: [[R:%.*]] = add nuw nsw i64 [[EXT]], 356 508; CHECK-NEXT: ret i64 [[R]] 509; 510 %add = add nuw i8 %x, 42 511 %ext = zext i8 %add to i64 512 store i64 %ext, i64* %p 513 %r = add i64 %ext, 356 514 ret i64 %r 515} 516 517define i64 @add_nuw_zext_add_extra_use_2(i8 %x, i8* %p) { 518; CHECK-LABEL: @add_nuw_zext_add_extra_use_2( 519; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[X:%.*]], 42 520; CHECK-NEXT: store i8 [[ADD]], i8* [[P:%.*]], align 1 521; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[X]] to i64 522; CHECK-NEXT: [[R:%.*]] = add nuw nsw i64 [[TMP1]], -314 523; CHECK-NEXT: ret i64 [[R]] 524; 525 %add = add nuw i8 %x, 42 526 store i8 %add, i8* %p 527 %ext = zext i8 %add to i64 528 %r = add i64 %ext, -356 529 ret i64 %r 530} 531 532define i1 @test21(i32 %x) { 533; CHECK-LABEL: @test21( 534; CHECK-NEXT: [[Y:%.*]] = icmp eq i32 [[X:%.*]], 119 535; CHECK-NEXT: ret i1 [[Y]] 536; 537 %t = add i32 %x, 4 538 %y = icmp eq i32 %t, 123 539 ret i1 %y 540} 541 542define <2 x i1> @test21vec(<2 x i32> %x) { 543; CHECK-LABEL: @test21vec( 544; CHECK-NEXT: [[Y:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 119, i32 119> 545; CHECK-NEXT: ret <2 x i1> [[Y]] 546; 547 %t = add <2 x i32> %x, <i32 4, i32 4> 548 %y = icmp eq <2 x i32> %t, <i32 123, i32 123> 549 ret <2 x i1> %y 550} 551 552define i32 @test22(i32 %V) { 553; CHECK-LABEL: @test22( 554; CHECK-NEXT: switch i32 [[V:%.*]], label [[DEFAULT:%.*]] [ 555; CHECK-NEXT: i32 10, label [[LAB1:%.*]] 556; CHECK-NEXT: i32 20, label [[LAB2:%.*]] 557; CHECK-NEXT: ] 558; CHECK: Default: 559; CHECK-NEXT: ret i32 123 560; CHECK: Lab1: 561; CHECK-NEXT: ret i32 12312 562; CHECK: Lab2: 563; CHECK-NEXT: ret i32 1231231 564; 565 %V2 = add i32 %V, 10 566 switch i32 %V2, label %Default [ 567 i32 20, label %Lab1 568 i32 30, label %Lab2 569 ] 570 571Default: ; preds = %0 572 ret i32 123 573 574Lab1: ; preds = %0 575 ret i32 12312 576 577Lab2: ; preds = %0 578 ret i32 1231231 579} 580 581define i32 @test23(i1 %C, i32 %a) { 582; CHECK-LABEL: @test23( 583; CHECK-NEXT: entry: 584; CHECK-NEXT: br i1 [[C:%.*]], label [[ENDIF:%.*]], label [[ELSE:%.*]] 585; CHECK: else: 586; CHECK-NEXT: br label [[ENDIF]] 587; CHECK: endif: 588; CHECK-NEXT: [[B_0:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 2, [[ELSE]] ] 589; CHECK-NEXT: ret i32 [[B_0]] 590; 591entry: 592 br i1 %C, label %endif, label %else 593 594else: ; preds = %entry 595 br label %endif 596 597endif: ; preds = %else, %entry 598 %b.0 = phi i32 [ 0, %entry ], [ 1, %else ] 599 %tmp.4 = add i32 %b.0, 1 600 ret i32 %tmp.4 601} 602 603define i32 @test24(i32 %A) { 604; CHECK-LABEL: @test24( 605; CHECK-NEXT: [[B:%.*]] = shl i32 [[A:%.*]], 1 606; CHECK-NEXT: ret i32 [[B]] 607; 608 %B = add i32 %A, 1 609 %C = shl i32 %B, 1 610 %D = sub i32 %C, 2 611 ret i32 %D 612} 613 614define i64 @test25(i64 %Y) { 615; CHECK-LABEL: @test25( 616; CHECK-NEXT: [[TMP_8:%.*]] = shl i64 [[Y:%.*]], 3 617; CHECK-NEXT: ret i64 [[TMP_8]] 618; 619 %tmp.4 = shl i64 %Y, 2 620 %tmp.12 = shl i64 %Y, 2 621 %tmp.8 = add i64 %tmp.4, %tmp.12 622 ret i64 %tmp.8 623} 624 625define i32 @test26(i32 %A, i32 %B) { 626; CHECK-LABEL: @test26( 627; CHECK-NEXT: ret i32 [[A:%.*]] 628; 629 %C = add i32 %A, %B 630 %D = sub i32 %C, %B 631 ret i32 %D 632} 633 634; Fold add through select. 635define i32 @test27(i1 %C, i32 %X, i32 %Y) { 636; CHECK-LABEL: @test27( 637; CHECK-NEXT: [[C_UPGRD_1_V:%.*]] = select i1 [[C:%.*]], i32 [[X:%.*]], i32 123 638; CHECK-NEXT: ret i32 [[C_UPGRD_1_V]] 639; 640 %A = add i32 %X, %Y 641 %B = add i32 %Y, 123 642 %C.upgrd.1 = select i1 %C, i32 %A, i32 %B 643 %D = sub i32 %C.upgrd.1, %Y 644 ret i32 %D 645} 646 647define i32 @test28(i32 %X) { 648; CHECK-LABEL: @test28( 649; CHECK-NEXT: [[Z:%.*]] = sub i32 -1192, [[X:%.*]] 650; CHECK-NEXT: ret i32 [[Z]] 651; 652 %Y = add i32 %X, 1234 653 %Z = sub i32 42, %Y 654 ret i32 %Z 655} 656 657define i32 @test29(i32 %x, i32 %y) { 658; CHECK-LABEL: @test29( 659; CHECK-NEXT: [[TMP_2:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]] 660; CHECK-NEXT: [[TMP_7:%.*]] = and i32 [[X]], 63 661; CHECK-NEXT: [[TMP_9:%.*]] = and i32 [[TMP_2]], -64 662; CHECK-NEXT: [[TMP_10:%.*]] = or i32 [[TMP_7]], [[TMP_9]] 663; CHECK-NEXT: ret i32 [[TMP_10]] 664; 665 %tmp.2 = sub i32 %x, %y 666 %tmp.2.mask = and i32 %tmp.2, 63 667 %tmp.6 = add i32 %tmp.2.mask, %y 668 %tmp.7 = and i32 %tmp.6, 63 669 %tmp.9 = and i32 %tmp.2, -64 670 %tmp.10 = or i32 %tmp.7, %tmp.9 671 ret i32 %tmp.10 672} 673 674; Add of sign bit -> xor of sign bit. 675define i64 @test30(i64 %x) { 676; CHECK-LABEL: @test30( 677; CHECK-NEXT: ret i64 [[X:%.*]] 678; 679 %tmp.2 = xor i64 %x, -9223372036854775808 680 %tmp.4 = add i64 %tmp.2, -9223372036854775808 681 ret i64 %tmp.4 682} 683 684define i32 @test31(i32 %A) { 685; CHECK-LABEL: @test31( 686; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[A:%.*]], 5 687; CHECK-NEXT: ret i32 [[TMP1]] 688; 689 %B = add i32 %A, 4 690 %C = mul i32 %B, 5 691 %D = sub i32 %C, 20 692 ret i32 %D 693} 694 695define i32 @test32(i32 %A) { 696; CHECK-LABEL: @test32( 697; CHECK-NEXT: [[B:%.*]] = shl i32 [[A:%.*]], 2 698; CHECK-NEXT: ret i32 [[B]] 699; 700 %B = add i32 %A, 4 701 %C = shl i32 %B, 2 702 %D = sub i32 %C, 16 703 ret i32 %D 704} 705 706define i8 @test33(i8 %A) { 707; CHECK-LABEL: @test33( 708; CHECK-NEXT: [[C:%.*]] = or i8 [[A:%.*]], 1 709; CHECK-NEXT: ret i8 [[C]] 710; 711 %B = and i8 %A, -2 712 %C = add i8 %B, 1 713 ret i8 %C 714} 715 716define i8 @test34(i8 %A) { 717; CHECK-LABEL: @test34( 718; CHECK-NEXT: [[C:%.*]] = and i8 [[A:%.*]], 12 719; CHECK-NEXT: ret i8 [[C]] 720; 721 %B = add i8 %A, 64 722 %C = and i8 %B, 12 723 ret i8 %C 724} 725 726; If all bits affected by the add are included 727; in the mask, do the add before the mask op. 728 729define i8 @masked_add(i8 %x) { 730; CHECK-LABEL: @masked_add( 731; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], 96 732; CHECK-NEXT: [[R:%.*]] = and i8 [[TMP1]], -16 733; CHECK-NEXT: ret i8 [[R]] 734; 735 %and = and i8 %x, 240 ; 0xf0 736 %r = add i8 %and, 96 ; 0x60 737 ret i8 %r 738} 739 740define <2 x i8> @masked_add_splat(<2 x i8> %x) { 741; CHECK-LABEL: @masked_add_splat( 742; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], <i8 64, i8 64> 743; CHECK-NEXT: [[R:%.*]] = and <2 x i8> [[TMP1]], <i8 -64, i8 -64> 744; CHECK-NEXT: ret <2 x i8> [[R]] 745; 746 %and = and <2 x i8> %x, <i8 192, i8 192> ; 0xc0 747 %r = add <2 x i8> %and, <i8 64, i8 64> ; 0x40 748 ret <2 x i8> %r 749} 750 751define i8 @not_masked_add(i8 %x) { 752; CHECK-LABEL: @not_masked_add( 753; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 112 754; CHECK-NEXT: [[R:%.*]] = add nuw i8 [[AND]], 96 755; CHECK-NEXT: ret i8 [[R]] 756; 757 %and = and i8 %x, 112 ; 0x70 758 %r = add i8 %and, 96 ; 0x60 759 ret i8 %r 760} 761 762define i8 @masked_add_multi_use(i8 %x) { 763; CHECK-LABEL: @masked_add_multi_use( 764; CHECK-NEXT: [[TMP:%.*]] = add i8 [[X:%.*]], 96 765; CHECK-NEXT: [[R:%.*]] = and i8 [[TMP:%.*]], -16 766; CHECK-NEXT: call void @use(i8 [[X]]) 767; CHECK-NEXT: ret i8 [[R]] 768; 769 %and = and i8 %x, -16 ; 0xf0 770 %r = add i8 %and, 96 ; 0x60 771 call void @use(i8 %x) ; extra use 772 ret i8 %r 773} 774 775define i32 @test35(i32 %a) { 776; CHECK-LABEL: @test35( 777; CHECK-NEXT: ret i32 -1 778; 779 %tmpnot = xor i32 %a, -1 780 %tmp2 = add i32 %tmpnot, %a 781 ret i32 %tmp2 782} 783 784define i32 @test36(i32 %a) { 785; CHECK-LABEL: @test36( 786; CHECK-NEXT: ret i32 0 787; 788 %x = and i32 %a, -2 789 %y = and i32 %a, -126 790 %z = add i32 %x, %y 791 %q = and i32 %z, 1 ; always zero 792 ret i32 %q 793} 794 795define i1 @test37(i32 %a, i32 %b) { 796; CHECK-LABEL: @test37( 797; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[B:%.*]], 0 798; CHECK-NEXT: ret i1 [[CMP]] 799; 800 %add = add i32 %a, %b 801 %cmp = icmp eq i32 %add, %a 802 ret i1 %cmp 803} 804 805define i1 @test38(i32 %a, i32 %b) { 806; CHECK-LABEL: @test38( 807; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0 808; CHECK-NEXT: ret i1 [[CMP]] 809; 810 %add = add i32 %a, %b 811 %cmp = icmp eq i32 %add, %b 812 ret i1 %cmp 813} 814 815define i1 @test39(i32 %a, i32 %b) { 816; CHECK-LABEL: @test39( 817; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[B:%.*]], 0 818; CHECK-NEXT: ret i1 [[CMP]] 819; 820 %add = add i32 %b, %a 821 %cmp = icmp eq i32 %add, %a 822 ret i1 %cmp 823} 824 825define i1 @test40(i32 %a, i32 %b) { 826; CHECK-LABEL: @test40( 827; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0 828; CHECK-NEXT: ret i1 [[CMP]] 829; 830 %add = add i32 %b, %a 831 %cmp = icmp eq i32 %add, %b 832 ret i1 %cmp 833} 834 835; (add (zext (add nuw X, C2)), C) --> (zext (add nuw X, C2 + C)) 836 837define i64 @test41(i32 %a) { 838; CHECK-LABEL: @test41( 839; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[A:%.*]], 15 840; CHECK-NEXT: [[SUB:%.*]] = zext i32 [[TMP1]] to i64 841; CHECK-NEXT: ret i64 [[SUB]] 842; 843 %add = add nuw i32 %a, 16 844 %zext = zext i32 %add to i64 845 %sub = add i64 %zext, -1 846 ret i64 %sub 847} 848 849; (add (zext (add nuw X, C2)), C) --> (zext (add nuw X, C2 + C)) 850 851define <2 x i64> @test41vec(<2 x i32> %a) { 852; CHECK-LABEL: @test41vec( 853; CHECK-NEXT: [[TMP1:%.*]] = add nuw <2 x i32> [[A:%.*]], <i32 15, i32 15> 854; CHECK-NEXT: [[SUB:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64> 855; CHECK-NEXT: ret <2 x i64> [[SUB]] 856; 857 %add = add nuw <2 x i32> %a, <i32 16, i32 16> 858 %zext = zext <2 x i32> %add to <2 x i64> 859 %sub = add <2 x i64> %zext, <i64 -1, i64 -1> 860 ret <2 x i64> %sub 861} 862 863define <2 x i64> @test41vec_and_multiuse(<2 x i32> %a) { 864; CHECK-LABEL: @test41vec_and_multiuse( 865; CHECK-NEXT: [[ADD:%.*]] = add nuw <2 x i32> [[A:%.*]], <i32 16, i32 16> 866; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i32> [[ADD]] to <2 x i64> 867; CHECK-NEXT: [[REASS_ADD:%.*]] = shl nuw nsw <2 x i64> [[ZEXT]], <i64 1, i64 1> 868; CHECK-NEXT: [[EXTRAUSE:%.*]] = add nsw <2 x i64> [[REASS_ADD]], <i64 -1, i64 -1> 869; CHECK-NEXT: ret <2 x i64> [[EXTRAUSE]] 870; 871 %add = add nuw <2 x i32> %a, <i32 16, i32 16> 872 %zext = zext <2 x i32> %add to <2 x i64> 873 %sub = add <2 x i64> %zext, <i64 -1, i64 -1> 874 %extrause = add <2 x i64> %zext, %sub 875 ret <2 x i64> %extrause 876} 877 878define i32 @test42(i1 %C) { 879; CHECK-LABEL: @test42( 880; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 1123, i32 133 881; CHECK-NEXT: ret i32 [[V]] 882; 883 %A = select i1 %C, i32 1000, i32 10 884 %V = add i32 123, %A 885 ret i32 %V 886} 887 888define <2 x i32> @test42vec(i1 %C) { 889; CHECK-LABEL: @test42vec( 890; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 1123>, <2 x i32> <i32 133, i32 133> 891; CHECK-NEXT: ret <2 x i32> [[V]] 892; 893 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10> 894 %V = add <2 x i32> <i32 123, i32 123>, %A 895 ret <2 x i32> %V 896} 897 898define <2 x i32> @test42vec2(i1 %C) { 899; CHECK-LABEL: @test42vec2( 900; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 2833>, <2 x i32> <i32 133, i32 363> 901; CHECK-NEXT: ret <2 x i32> [[V]] 902; 903 %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30> 904 %V = add <2 x i32> <i32 123, i32 333>, %A 905 ret <2 x i32> %V 906} 907 908define i32 @test55(i1 %which) { 909; CHECK-LABEL: @test55( 910; CHECK-NEXT: entry: 911; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 912; CHECK: delay: 913; CHECK-NEXT: br label [[FINAL]] 914; CHECK: final: 915; CHECK-NEXT: [[A:%.*]] = phi i32 [ 1123, [[ENTRY:%.*]] ], [ 133, [[DELAY]] ] 916; CHECK-NEXT: ret i32 [[A]] 917; 918entry: 919 br i1 %which, label %final, label %delay 920 921delay: 922 br label %final 923 924final: 925 %A = phi i32 [ 1000, %entry ], [ 10, %delay ] 926 %value = add i32 123, %A 927 ret i32 %value 928} 929 930define <2 x i32> @test43vec(i1 %which) { 931; CHECK-LABEL: @test43vec( 932; CHECK-NEXT: entry: 933; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 934; CHECK: delay: 935; CHECK-NEXT: br label [[FINAL]] 936; CHECK: final: 937; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1123, i32 1123>, [[ENTRY:%.*]] ], [ <i32 133, i32 133>, [[DELAY]] ] 938; CHECK-NEXT: ret <2 x i32> [[A]] 939; 940entry: 941 br i1 %which, label %final, label %delay 942 943delay: 944 br label %final 945 946final: 947 %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ] 948 %value = add <2 x i32> <i32 123, i32 123>, %A 949 ret <2 x i32> %value 950} 951 952define <2 x i32> @test43vec2(i1 %which) { 953; CHECK-LABEL: @test43vec2( 954; CHECK-NEXT: entry: 955; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 956; CHECK: delay: 957; CHECK-NEXT: br label [[FINAL]] 958; CHECK: final: 959; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1123, i32 2833>, [[ENTRY:%.*]] ], [ <i32 133, i32 363>, [[DELAY]] ] 960; CHECK-NEXT: ret <2 x i32> [[A]] 961; 962entry: 963 br i1 %which, label %final, label %delay 964 965delay: 966 br label %final 967 968final: 969 %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ] 970 %value = add <2 x i32> <i32 123, i32 333>, %A 971 ret <2 x i32> %value 972} 973 974; E = (A + 1) + ~B = A - B 975define i32 @add_not_increment(i32 %A, i32 %B) { 976; CHECK-LABEL: @add_not_increment( 977; CHECK-NEXT: [[E:%.*]] = sub i32 [[A:%.*]], [[B:%.*]] 978; CHECK-NEXT: ret i32 [[E]] 979; 980 %C = xor i32 %B, -1 981 %D = add i32 %A, 1 982 %E = add i32 %D, %C 983 ret i32 %E 984} 985 986; E = (A + 1) + ~B = A - B 987define <2 x i32> @add_not_increment_vec(<2 x i32> %A, <2 x i32> %B) { 988; CHECK-LABEL: @add_not_increment_vec( 989; CHECK-NEXT: [[E:%.*]] = sub <2 x i32> [[A:%.*]], [[B:%.*]] 990; CHECK-NEXT: ret <2 x i32> [[E]] 991; 992 %C = xor <2 x i32> %B, <i32 -1, i32 -1> 993 %D = add <2 x i32> %A, <i32 1, i32 1> 994 %E = add <2 x i32> %D, %C 995 ret <2 x i32> %E 996} 997 998; E = ~B + (1 + A) = A - B 999define i32 @add_not_increment_commuted(i32 %A, i32 %B) { 1000; CHECK-LABEL: @add_not_increment_commuted( 1001; CHECK-NEXT: [[E:%.*]] = sub i32 [[A:%.*]], [[B:%.*]] 1002; CHECK-NEXT: ret i32 [[E]] 1003; 1004 %C = xor i32 %B, -1 1005 %D = add i32 %A, 1 1006 %E = add i32 %C, %D 1007 ret i32 %E 1008} 1009 1010; E = (A + ~B) + 1 = A - B 1011define i32 @add_to_sub(i32 %M, i32 %B) { 1012; CHECK-LABEL: @add_to_sub( 1013; CHECK-NEXT: [[A:%.*]] = mul i32 [[M:%.*]], 42 1014; CHECK-NEXT: [[E:%.*]] = sub i32 [[A]], [[B:%.*]] 1015; CHECK-NEXT: ret i32 [[E]] 1016; 1017 %A = mul i32 %M, 42 ; thwart complexity-based ordering 1018 %C = xor i32 %B, -1 1019 %D = add i32 %A, %C 1020 %E = add i32 %D, 1 1021 ret i32 %E 1022} 1023 1024; E = (~B + A) + 1 = A - B 1025define i32 @add_to_sub2(i32 %A, i32 %M) { 1026; CHECK-LABEL: @add_to_sub2( 1027; CHECK-NEXT: [[B_NEG:%.*]] = mul i32 [[M:%.*]], -42 1028; CHECK-NEXT: [[E:%.*]] = add i32 [[B_NEG]], [[A:%.*]] 1029; CHECK-NEXT: ret i32 [[E]] 1030; 1031 %B = mul i32 %M, 42 ; thwart complexity-based ordering 1032 %C = xor i32 %B, -1 1033 %D = add i32 %C, %A 1034 %E = add i32 %D, 1 1035 ret i32 %E 1036} 1037 1038; (X | C1) + C2 --> (X | C1) ^ C1 iff (C1 == -C2) 1039define i32 @test44(i32 %A) { 1040; CHECK-LABEL: @test44( 1041; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], -124 1042; CHECK-NEXT: ret i32 [[TMP1]] 1043; 1044 %B = or i32 %A, 123 1045 %C = add i32 %B, -123 1046 ret i32 %C 1047} 1048 1049define i32 @test44_extra_use(i32 %A) { 1050; CHECK-LABEL: @test44_extra_use( 1051; CHECK-NEXT: [[B:%.*]] = or i32 [[A:%.*]], 123 1052; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A]], -124 1053; CHECK-NEXT: [[D:%.*]] = mul i32 [[B]], [[TMP1]] 1054; CHECK-NEXT: ret i32 [[D]] 1055; 1056 %B = or i32 %A, 123 1057 %C = add i32 %B, -123 1058 %D = mul i32 %B, %C 1059 ret i32 %D 1060} 1061 1062define i32 @test44_non_matching(i32 %A) { 1063; CHECK-LABEL: @test44_non_matching( 1064; CHECK-NEXT: [[B:%.*]] = or i32 [[A:%.*]], 123 1065; CHECK-NEXT: [[C:%.*]] = add i32 [[B]], -321 1066; CHECK-NEXT: ret i32 [[C]] 1067; 1068 %B = or i32 %A, 123 1069 %C = add i32 %B, -321 1070 ret i32 %C 1071} 1072 1073define <2 x i32> @test44_vec(<2 x i32> %A) { 1074; CHECK-LABEL: @test44_vec( 1075; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[A:%.*]], <i32 -124, i32 -124> 1076; CHECK-NEXT: ret <2 x i32> [[TMP1]] 1077; 1078 %B = or <2 x i32> %A, <i32 123, i32 123> 1079 %C = add <2 x i32> %B, <i32 -123, i32 -123> 1080 ret <2 x i32> %C 1081} 1082 1083define <2 x i32> @test44_vec_non_matching(<2 x i32> %A) { 1084; CHECK-LABEL: @test44_vec_non_matching( 1085; CHECK-NEXT: [[B:%.*]] = or <2 x i32> [[A:%.*]], <i32 123, i32 123> 1086; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[B]], <i32 -321, i32 -321> 1087; CHECK-NEXT: ret <2 x i32> [[C]] 1088; 1089 %B = or <2 x i32> %A, <i32 123, i32 123> 1090 %C = add <2 x i32> %B, <i32 -321, i32 -321> 1091 ret <2 x i32> %C 1092} 1093 1094define <2 x i32> @test44_vec_undef(<2 x i32> %A) { 1095; CHECK-LABEL: @test44_vec_undef( 1096; CHECK-NEXT: [[B:%.*]] = or <2 x i32> [[A:%.*]], <i32 123, i32 undef> 1097; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[B]], <i32 -123, i32 undef> 1098; CHECK-NEXT: ret <2 x i32> [[C]] 1099; 1100 %B = or <2 x i32> %A, <i32 123, i32 undef> 1101 %C = add <2 x i32> %B, <i32 -123, i32 undef> 1102 ret <2 x i32> %C 1103} 1104 1105define <2 x i32> @test44_vec_non_splat(<2 x i32> %A) { 1106; CHECK-LABEL: @test44_vec_non_splat( 1107; CHECK-NEXT: [[B:%.*]] = or <2 x i32> [[A:%.*]], <i32 123, i32 456> 1108; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[B]], <i32 -123, i32 -456> 1109; CHECK-NEXT: ret <2 x i32> [[C]] 1110; 1111 %B = or <2 x i32> %A, <i32 123, i32 456> 1112 %C = add <2 x i32> %B, <i32 -123, i32 -456> 1113 ret <2 x i32> %C 1114} 1115 1116define i32 @lshr_add(i1 %x, i1 %y) { 1117; CHECK-LABEL: @lshr_add( 1118; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X:%.*]], true 1119; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[Y:%.*]] 1120; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP2]] to i32 1121; CHECK-NEXT: ret i32 [[R]] 1122; 1123 %xz = zext i1 %x to i32 1124 %ys = sext i1 %y to i32 1125 %sub = add i32 %xz, %ys 1126 %r = lshr i32 %sub, 31 1127 ret i32 %r 1128} 1129 1130define i5 @and_add(i1 %x, i1 %y) { 1131; CHECK-LABEL: @and_add( 1132; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X:%.*]], true 1133; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[Y:%.*]] 1134; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i5 -2, i5 0 1135; CHECK-NEXT: ret i5 [[R]] 1136; 1137 %xz = zext i1 %x to i5 1138 %ys = sext i1 %y to i5 1139 %sub = add i5 %xz, %ys 1140 %r = and i5 %sub, 30 1141 ret i5 %r 1142} 1143 1144define <2 x i8> @ashr_add_commute(<2 x i1> %x, <2 x i1> %y) { 1145; CHECK-LABEL: @ashr_add_commute( 1146; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i1> [[X:%.*]], <i1 true, i1 true> 1147; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i1> [[TMP1]], [[Y:%.*]] 1148; CHECK-NEXT: [[TMP3:%.*]] = sext <2 x i1> [[TMP2]] to <2 x i8> 1149; CHECK-NEXT: ret <2 x i8> [[TMP3]] 1150; 1151 %xz = zext <2 x i1> %x to <2 x i8> 1152 %ys = sext <2 x i1> %y to <2 x i8> 1153 %sub = add nsw <2 x i8> %ys, %xz 1154 %r = ashr <2 x i8> %sub, <i8 1, i8 1> 1155 ret <2 x i8> %r 1156} 1157 1158define i32 @cmp_math(i32 %x, i32 %y) { 1159; CHECK-LABEL: @cmp_math( 1160; CHECK-NEXT: [[LT:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 1161; CHECK-NEXT: [[R:%.*]] = zext i1 [[LT]] to i32 1162; CHECK-NEXT: ret i32 [[R]] 1163; 1164 %gt = icmp ugt i32 %x, %y 1165 %lt = icmp ult i32 %x, %y 1166 %xz = zext i1 %gt to i32 1167 %yz = zext i1 %lt to i32 1168 %s = sub i32 %xz, %yz 1169 %r = lshr i32 %s, 31 1170 ret i32 %r 1171} 1172 1173; Negative test - wrong type 1174 1175define i32 @lshr_add_nonbool(i2 %x, i1 %y) { 1176; CHECK-LABEL: @lshr_add_nonbool( 1177; CHECK-NEXT: [[XZ:%.*]] = zext i2 [[X:%.*]] to i32 1178; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32 1179; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]] 1180; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31 1181; CHECK-NEXT: ret i32 [[R]] 1182; 1183 %xz = zext i2 %x to i32 1184 %ys = sext i1 %y to i32 1185 %sub = add i32 %xz, %ys 1186 %r = lshr i32 %sub, 31 1187 ret i32 %r 1188} 1189 1190; Negative test - wrong demand 1191 1192define i32 @and31_add(i1 %x, i1 %y) { 1193; CHECK-LABEL: @and31_add( 1194; CHECK-NEXT: [[XZ:%.*]] = zext i1 [[X:%.*]] to i32 1195; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32 1196; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]] 1197; CHECK-NEXT: [[R:%.*]] = and i32 [[SUB]], 31 1198; CHECK-NEXT: ret i32 [[R]] 1199; 1200 %xz = zext i1 %x to i32 1201 %ys = sext i1 %y to i32 1202 %sub = add i32 %xz, %ys 1203 %r = and i32 %sub, 31 1204 ret i32 %r 1205} 1206 1207; Negative test - extra use 1208 1209define i32 @lshr_add_use(i1 %x, i1 %y, i32* %p) { 1210; CHECK-LABEL: @lshr_add_use( 1211; CHECK-NEXT: [[XZ:%.*]] = zext i1 [[X:%.*]] to i32 1212; CHECK-NEXT: store i32 [[XZ]], i32* [[P:%.*]], align 4 1213; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32 1214; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]] 1215; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31 1216; CHECK-NEXT: ret i32 [[R]] 1217; 1218 %xz = zext i1 %x to i32 1219 store i32 %xz, i32* %p 1220 %ys = sext i1 %y to i32 1221 %sub = add i32 %xz, %ys 1222 %r = lshr i32 %sub, 31 1223 ret i32 %r 1224} 1225 1226; Negative test - extra use 1227 1228define i32 @lshr_add_use2(i1 %x, i1 %y, i32* %p) { 1229; CHECK-LABEL: @lshr_add_use2( 1230; CHECK-NEXT: [[XZ:%.*]] = zext i1 [[X:%.*]] to i32 1231; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32 1232; CHECK-NEXT: store i32 [[YS]], i32* [[P:%.*]], align 4 1233; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]] 1234; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31 1235; CHECK-NEXT: ret i32 [[R]] 1236; 1237 %xz = zext i1 %x to i32 1238 %ys = sext i1 %y to i32 1239 store i32 %ys, i32* %p 1240 %sub = add i32 %xz, %ys 1241 %r = lshr i32 %sub, 31 1242 ret i32 %r 1243} 1244 1245define i32 @lshr_add_sexts(i1 %x, i1 %y) { 1246; CHECK-LABEL: @lshr_add_sexts( 1247; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y:%.*]] 1248; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i32 1249; CHECK-NEXT: ret i32 [[R]] 1250; 1251 %xs = sext i1 %x to i32 1252 %ys = sext i1 %y to i32 1253 %sub = add i32 %xs, %ys 1254 %r = lshr i32 %sub, 31 1255 ret i32 %r 1256} 1257 1258define i5 @and_add_sexts(i1 %x, i1 %y) { 1259; CHECK-LABEL: @and_add_sexts( 1260; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y:%.*]] 1261; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i5 -2, i5 0 1262; CHECK-NEXT: ret i5 [[R]] 1263; 1264 %xs = sext i1 %x to i5 1265 %ys = sext i1 %y to i5 1266 %sub = add i5 %xs, %ys 1267 %r = and i5 %sub, 30 1268 ret i5 %r 1269} 1270 1271define <2 x i8> @ashr_add_sexts(<2 x i1> %x, <2 x i1> %y) { 1272; CHECK-LABEL: @ashr_add_sexts( 1273; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i1> [[Y:%.*]], [[X:%.*]] 1274; CHECK-NEXT: [[TMP2:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8> 1275; CHECK-NEXT: ret <2 x i8> [[TMP2]] 1276; 1277 %xs = sext <2 x i1> %x to <2 x i8> 1278 %ys = sext <2 x i1> %y to <2 x i8> 1279 %sub = add nsw <2 x i8> %ys, %xs 1280 %r = ashr <2 x i8> %sub, <i8 1, i8 1> 1281 ret <2 x i8> %r 1282} 1283 1284define i32 @cmp_math_sexts(i32 %x, i32 %y) { 1285; CHECK-LABEL: @cmp_math_sexts( 1286; CHECK-NEXT: [[DOTNOT:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]] 1287; CHECK-NEXT: [[R:%.*]] = zext i1 [[DOTNOT]] to i32 1288; CHECK-NEXT: ret i32 [[R]] 1289; 1290 %gt = icmp ugt i32 %x, %y 1291 %lt = icmp ult i32 %x, %y 1292 %xz = sext i1 %gt to i32 1293 %yz = zext i1 %lt to i32 1294 %s = sub i32 %xz, %yz 1295 %r = lshr i32 %s, 31 1296 ret i32 %r 1297} 1298 1299; Negative test - wrong type 1300 1301define i32 @lshr_add_nonbool_sexts(i2 %x, i1 %y) { 1302; CHECK-LABEL: @lshr_add_nonbool_sexts( 1303; CHECK-NEXT: [[XS:%.*]] = sext i2 [[X:%.*]] to i32 1304; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32 1305; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]] 1306; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31 1307; CHECK-NEXT: ret i32 [[R]] 1308; 1309 %xs = sext i2 %x to i32 1310 %ys = sext i1 %y to i32 1311 %sub = add i32 %xs, %ys 1312 %r = lshr i32 %sub, 31 1313 ret i32 %r 1314} 1315 1316; Negative test - wrong demand 1317 1318define i32 @and31_add_sexts(i1 %x, i1 %y) { 1319; CHECK-LABEL: @and31_add_sexts( 1320; CHECK-NEXT: [[XS:%.*]] = sext i1 [[X:%.*]] to i32 1321; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32 1322; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]] 1323; CHECK-NEXT: [[R:%.*]] = and i32 [[SUB]], 31 1324; CHECK-NEXT: ret i32 [[R]] 1325; 1326 %xs = sext i1 %x to i32 1327 %ys = sext i1 %y to i32 1328 %sub = add i32 %xs, %ys 1329 %r = and i32 %sub, 31 1330 ret i32 %r 1331} 1332 1333; Negative test - extra use 1334 1335define i32 @lshr_add_use_sexts(i1 %x, i1 %y, i32* %p) { 1336; CHECK-LABEL: @lshr_add_use_sexts( 1337; CHECK-NEXT: [[XS:%.*]] = sext i1 [[X:%.*]] to i32 1338; CHECK-NEXT: store i32 [[XS]], i32* [[P:%.*]], align 4 1339; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32 1340; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]] 1341; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31 1342; CHECK-NEXT: ret i32 [[R]] 1343; 1344 %xs = sext i1 %x to i32 1345 store i32 %xs, i32* %p 1346 %ys = sext i1 %y to i32 1347 %sub = add i32 %xs, %ys 1348 %r = lshr i32 %sub, 31 1349 ret i32 %r 1350} 1351 1352; Negative test - extra use 1353 1354define i32 @lshr_add_use2_sexts(i1 %x, i1 %y, i32* %p) { 1355; CHECK-LABEL: @lshr_add_use2_sexts( 1356; CHECK-NEXT: [[XS:%.*]] = sext i1 [[X:%.*]] to i32 1357; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32 1358; CHECK-NEXT: store i32 [[YS]], i32* [[P:%.*]], align 4 1359; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]] 1360; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31 1361; CHECK-NEXT: ret i32 [[R]] 1362; 1363 %xs = sext i1 %x to i32 1364 %ys = sext i1 %y to i32 1365 store i32 %ys, i32* %p 1366 %sub = add i32 %xs, %ys 1367 %r = lshr i32 %sub, 31 1368 ret i32 %r 1369} 1370 1371define i8 @add_like_or_t0(i8 %x) { 1372; CHECK-LABEL: @add_like_or_t0( 1373; CHECK-NEXT: [[I0:%.*]] = shl i8 [[X:%.*]], 4 1374; CHECK-NEXT: [[R:%.*]] = add i8 [[I0]], 57 1375; CHECK-NEXT: ret i8 [[R]] 1376; 1377 %i0 = shl i8 %x, 4 1378 %i1 = or i8 %i0, 15 ; no common bits 1379 %r = add i8 %i1, 42 1380 ret i8 %r 1381} 1382define i8 @add_like_or_n1(i8 %x) { 1383; CHECK-LABEL: @add_like_or_n1( 1384; CHECK-NEXT: [[I0:%.*]] = shl i8 [[X:%.*]], 4 1385; CHECK-NEXT: [[I1:%.*]] = or i8 [[I0]], 31 1386; CHECK-NEXT: [[R:%.*]] = add i8 [[I1]], 42 1387; CHECK-NEXT: ret i8 [[R]] 1388; 1389 %i0 = shl i8 %x, 4 1390 %i1 = or i8 %i0, 31 ; 4'th bit might be common-set 1391 %r = add i8 %i1, 42 1392 ret i8 %r 1393} 1394define i8 @add_like_or_t2_extrause(i8 %x) { 1395; CHECK-LABEL: @add_like_or_t2_extrause( 1396; CHECK-NEXT: [[I0:%.*]] = shl i8 [[X:%.*]], 4 1397; CHECK-NEXT: [[I1:%.*]] = or i8 [[I0]], 15 1398; CHECK-NEXT: call void @use(i8 [[I1]]) 1399; CHECK-NEXT: [[R:%.*]] = add i8 [[I0]], 57 1400; CHECK-NEXT: ret i8 [[R]] 1401; 1402 %i0 = shl i8 %x, 4 1403 %i1 = or i8 %i0, 15 ; no common bits 1404 call void @use(i8 %i1) ; extra use 1405 %r = add i8 %i1, 42 1406 ret i8 %r 1407} 1408 1409define i8 @add_and_xor(i8 %x, i8 %y) { 1410; CHECK-LABEL: @add_and_xor( 1411; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y:%.*]], [[X:%.*]] 1412; CHECK-NEXT: ret i8 [[ADD]] 1413; 1414 %xor = xor i8 %x, -1 1415 %and = and i8 %xor, %y 1416 %add = add i8 %and, %x 1417 ret i8 %add 1418} 1419 1420define i8 @add_and_xor_wrong_const(i8 %x, i8 %y) { 1421; CHECK-LABEL: @add_and_xor_wrong_const( 1422; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -2 1423; CHECK-NEXT: [[AND:%.*]] = and i8 [[XOR]], [[Y:%.*]] 1424; CHECK-NEXT: [[ADD:%.*]] = add i8 [[AND]], [[X]] 1425; CHECK-NEXT: ret i8 [[ADD]] 1426; 1427 %xor = xor i8 %x, -2 1428 %and = and i8 %xor, %y 1429 %add = add i8 %and, %x 1430 ret i8 %add 1431} 1432 1433define i8 @add_and_xor_wrong_op(i8 %x, i8 %y, i8 %z) { 1434; CHECK-LABEL: @add_and_xor_wrong_op( 1435; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[Z:%.*]], -1 1436; CHECK-NEXT: [[AND:%.*]] = and i8 [[XOR]], [[Y:%.*]] 1437; CHECK-NEXT: [[ADD:%.*]] = add i8 [[AND]], [[X:%.*]] 1438; CHECK-NEXT: ret i8 [[ADD]] 1439; 1440 %xor = xor i8 %z, -1 1441 %and = and i8 %xor, %y 1442 %add = add i8 %and, %x 1443 ret i8 %add 1444} 1445 1446define i8 @add_and_xor_commuted1(i8 %x, i8 %_y) { 1447; CHECK-LABEL: @add_and_xor_commuted1( 1448; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]] 1449; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X:%.*]] 1450; CHECK-NEXT: ret i8 [[ADD]] 1451; 1452 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization 1453 %xor = xor i8 %x, -1 1454 %and = and i8 %y, %xor 1455 %add = add i8 %and, %x 1456 ret i8 %add 1457} 1458 1459define i8 @add_and_xor_commuted2(i8 %_x, i8 %y) { 1460; CHECK-LABEL: @add_and_xor_commuted2( 1461; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]] 1462; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y:%.*]] 1463; CHECK-NEXT: ret i8 [[ADD]] 1464; 1465 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization 1466 %xor = xor i8 %x, -1 1467 %and = and i8 %xor, %y 1468 %add = add i8 %x, %and 1469 ret i8 %add 1470} 1471 1472define i8 @add_and_xor_commuted3(i8 %_x, i8 %_y) { 1473; CHECK-LABEL: @add_and_xor_commuted3( 1474; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]] 1475; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]] 1476; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y]] 1477; CHECK-NEXT: ret i8 [[ADD]] 1478; 1479 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization 1480 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization 1481 %xor = xor i8 %x, -1 1482 %and = and i8 %y, %xor 1483 %add = add i8 %x, %and 1484 ret i8 %add 1485} 1486 1487define i8 @add_and_xor_extra_use(i8 %x, i8 %y) { 1488; CHECK-LABEL: @add_and_xor_extra_use( 1489; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -1 1490; CHECK-NEXT: call void @use(i8 [[XOR]]) 1491; CHECK-NEXT: [[AND:%.*]] = and i8 [[XOR]], [[Y:%.*]] 1492; CHECK-NEXT: call void @use(i8 [[AND]]) 1493; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]] 1494; CHECK-NEXT: ret i8 [[ADD]] 1495; 1496 %xor = xor i8 %x, -1 1497 call void @use(i8 %xor) 1498 %and = and i8 %xor, %y 1499 call void @use(i8 %and) 1500 %add = add i8 %and, %x 1501 ret i8 %add 1502} 1503 1504define i8 @add_xor_and_const(i8 %x) { 1505; CHECK-LABEL: @add_xor_and_const( 1506; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X:%.*]], 42 1507; CHECK-NEXT: ret i8 [[ADD]] 1508; 1509 %and = and i8 %x, 42 1510 %xor = xor i8 %and, 42 1511 %add = add i8 %xor, %x 1512 ret i8 %add 1513} 1514 1515define i8 @add_xor_and_const_wrong_const(i8 %x) { 1516; CHECK-LABEL: @add_xor_and_const_wrong_const( 1517; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 42 1518; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[AND]], 88 1519; CHECK-NEXT: [[ADD:%.*]] = add i8 [[XOR]], [[X]] 1520; CHECK-NEXT: ret i8 [[ADD]] 1521; 1522 %and = and i8 %x, 42 1523 %xor = xor i8 %and, 88 1524 %add = add i8 %xor, %x 1525 ret i8 %add 1526} 1527 1528define i8 @add_xor_and_var(i8 %x, i8 %y) { 1529; CHECK-LABEL: @add_xor_and_var( 1530; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]] 1531; CHECK-NEXT: call void @use(i8 [[AND]]) 1532; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]] 1533; CHECK-NEXT: ret i8 [[ADD]] 1534; 1535 %and = and i8 %x, %y 1536 call void @use(i8 %and) 1537 %xor = xor i8 %and, %y 1538 %add = add i8 %xor, %x 1539 ret i8 %add 1540} 1541 1542define i8 @add_xor_and_var_wrong_op1(i8 %x, i8 %y, i8 %z) { 1543; CHECK-LABEL: @add_xor_and_var_wrong_op1( 1544; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]] 1545; CHECK-NEXT: call void @use(i8 [[AND]]) 1546; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[AND]], [[Z:%.*]] 1547; CHECK-NEXT: [[ADD:%.*]] = add i8 [[XOR]], [[X]] 1548; CHECK-NEXT: ret i8 [[ADD]] 1549; 1550 %and = and i8 %x, %y 1551 call void @use(i8 %and) 1552 %xor = xor i8 %and, %z 1553 %add = add i8 %xor, %x 1554 ret i8 %add 1555} 1556 1557define i8 @add_xor_and_var_wrong_op2(i8 %x, i8 %y, i8 %z) { 1558; CHECK-LABEL: @add_xor_and_var_wrong_op2( 1559; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]] 1560; CHECK-NEXT: call void @use(i8 [[AND]]) 1561; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[AND]], [[Y]] 1562; CHECK-NEXT: [[ADD:%.*]] = add i8 [[XOR]], [[Z:%.*]] 1563; CHECK-NEXT: ret i8 [[ADD]] 1564; 1565 %and = and i8 %x, %y 1566 call void @use(i8 %and) 1567 %xor = xor i8 %and, %y 1568 %add = add i8 %xor, %z 1569 ret i8 %add 1570} 1571 1572define i8 @add_xor_and_var_commuted1(i8 %x, i8 %y) { 1573; CHECK-LABEL: @add_xor_and_var_commuted1( 1574; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y:%.*]], [[X:%.*]] 1575; CHECK-NEXT: call void @use(i8 [[AND]]) 1576; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]] 1577; CHECK-NEXT: ret i8 [[ADD]] 1578; 1579 %and = and i8 %y, %x 1580 call void @use(i8 %and) 1581 %xor = xor i8 %and, %y 1582 %add = add i8 %xor, %x 1583 ret i8 %add 1584} 1585 1586define i8 @add_xor_and_var_commuted2(i8 %_x, i8 %_y) { 1587; CHECK-LABEL: @add_xor_and_var_commuted2( 1588; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]] 1589; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]] 1590; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[Y]] 1591; CHECK-NEXT: call void @use(i8 [[AND]]) 1592; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]] 1593; CHECK-NEXT: ret i8 [[ADD]] 1594; 1595 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization 1596 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization 1597 %and = and i8 %x, %y 1598 call void @use(i8 %and) 1599 %xor = xor i8 %y, %and 1600 %add = add i8 %xor, %x 1601 ret i8 %add 1602} 1603 1604define i8 @add_xor_and_var_commuted3(i8 %x, i8 %_y) { 1605; CHECK-LABEL: @add_xor_and_var_commuted3( 1606; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]] 1607; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y]], [[X:%.*]] 1608; CHECK-NEXT: call void @use(i8 [[AND]]) 1609; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]] 1610; CHECK-NEXT: ret i8 [[ADD]] 1611; 1612 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization 1613 %and = and i8 %y, %x 1614 call void @use(i8 %and) 1615 %xor = xor i8 %y, %and 1616 %add = add i8 %xor, %x 1617 ret i8 %add 1618} 1619 1620define i8 @add_xor_and_var_commuted4(i8 %_x, i8 %y) { 1621; CHECK-LABEL: @add_xor_and_var_commuted4( 1622; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]] 1623; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[Y:%.*]] 1624; CHECK-NEXT: call void @use(i8 [[AND]]) 1625; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y]] 1626; CHECK-NEXT: ret i8 [[ADD]] 1627; 1628 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization 1629 %and = and i8 %x, %y 1630 call void @use(i8 %and) 1631 %xor = xor i8 %and, %y 1632 %add = add i8 %x, %xor 1633 ret i8 %add 1634} 1635 1636define i8 @add_xor_and_var_commuted5(i8 %_x, i8 %_y) { 1637; CHECK-LABEL: @add_xor_and_var_commuted5( 1638; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]] 1639; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]] 1640; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y]], [[X]] 1641; CHECK-NEXT: call void @use(i8 [[AND]]) 1642; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y]] 1643; CHECK-NEXT: ret i8 [[ADD]] 1644; 1645 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization 1646 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization 1647 %and = and i8 %y, %x 1648 call void @use(i8 %and) 1649 %xor = xor i8 %and, %y 1650 %add = add i8 %x, %xor 1651 ret i8 %add 1652} 1653 1654define i8 @add_xor_and_var_commuted6(i8 %_x, i8 %_y) { 1655; CHECK-LABEL: @add_xor_and_var_commuted6( 1656; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]] 1657; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]] 1658; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[Y]] 1659; CHECK-NEXT: call void @use(i8 [[AND]]) 1660; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y]] 1661; CHECK-NEXT: ret i8 [[ADD]] 1662; 1663 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization 1664 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization 1665 %and = and i8 %x, %y 1666 call void @use(i8 %and) 1667 %xor = xor i8 %y, %and 1668 %add = add i8 %x, %xor 1669 ret i8 %add 1670} 1671 1672define i8 @add_xor_and_var_commuted7(i8 %_x, i8 %_y) { 1673; CHECK-LABEL: @add_xor_and_var_commuted7( 1674; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]] 1675; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]] 1676; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y]], [[X]] 1677; CHECK-NEXT: call void @use(i8 [[AND]]) 1678; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y]] 1679; CHECK-NEXT: ret i8 [[ADD]] 1680; 1681 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization 1682 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization 1683 %and = and i8 %y, %x 1684 call void @use(i8 %and) 1685 %xor = xor i8 %y, %and 1686 %add = add i8 %x, %xor 1687 ret i8 %add 1688} 1689 1690define i8 @add_xor_and_var_extra_use(i8 %x, i8 %y) { 1691; CHECK-LABEL: @add_xor_and_var_extra_use( 1692; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]] 1693; CHECK-NEXT: call void @use(i8 [[AND]]) 1694; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[AND]], [[Y]] 1695; CHECK-NEXT: call void @use(i8 [[XOR]]) 1696; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]] 1697; CHECK-NEXT: ret i8 [[ADD]] 1698; 1699 %and = and i8 %x, %y 1700 call void @use(i8 %and) 1701 %xor = xor i8 %and, %y 1702 call void @use(i8 %xor) 1703 %add = add i8 %xor, %x 1704 ret i8 %add 1705} 1706 1707define i32 @add_add_add(i32 %A, i32 %B, i32 %C, i32 %D) { 1708; CHECK-LABEL: @add_add_add( 1709; CHECK-NEXT: [[E:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 1710; CHECK-NEXT: [[F:%.*]] = add i32 [[E]], [[C:%.*]] 1711; CHECK-NEXT: [[G:%.*]] = add i32 [[F]], [[D:%.*]] 1712; CHECK-NEXT: ret i32 [[G]] 1713; 1714 %E = add i32 %A, %B 1715 %F = add i32 %E, %C 1716 %G = add i32 %F, %D 1717 ret i32 %G 1718} 1719 1720define i32 @add_add_add_commute1(i32 %A, i32 %B, i32 %C, i32 %D) { 1721; CHECK-LABEL: @add_add_add_commute1( 1722; CHECK-NEXT: [[E:%.*]] = add i32 [[B:%.*]], [[A:%.*]] 1723; CHECK-NEXT: [[F:%.*]] = add i32 [[E]], [[C:%.*]] 1724; CHECK-NEXT: [[G:%.*]] = add i32 [[F]], [[D:%.*]] 1725; CHECK-NEXT: ret i32 [[G]] 1726; 1727 %E = add i32 %B, %A 1728 %F = add i32 %E, %C 1729 %G = add i32 %F, %D 1730 ret i32 %G 1731} 1732 1733define i32 @add_add_add_commute2(i32 %A, i32 %B, i32 %C, i32 %D) { 1734; CHECK-LABEL: @add_add_add_commute2( 1735; CHECK-NEXT: [[E:%.*]] = add i32 [[B:%.*]], [[A:%.*]] 1736; CHECK-NEXT: [[F:%.*]] = add i32 [[E]], [[C:%.*]] 1737; CHECK-NEXT: [[G:%.*]] = add i32 [[F]], [[D:%.*]] 1738; CHECK-NEXT: ret i32 [[G]] 1739; 1740 %E = add i32 %B, %A 1741 %F = add i32 %C, %E 1742 %G = add i32 %F, %D 1743 ret i32 %G 1744} 1745 1746define i32 @add_add_add_commute3(i32 %A, i32 %B, i32 %C, i32 %D) { 1747; CHECK-LABEL: @add_add_add_commute3( 1748; CHECK-NEXT: [[E:%.*]] = add i32 [[B:%.*]], [[A:%.*]] 1749; CHECK-NEXT: [[F:%.*]] = add i32 [[E]], [[C:%.*]] 1750; CHECK-NEXT: [[G:%.*]] = add i32 [[F]], [[D:%.*]] 1751; CHECK-NEXT: ret i32 [[G]] 1752; 1753 %E = add i32 %B, %A 1754 %F = add i32 %C, %E 1755 %G = add i32 %D, %F 1756 ret i32 %G 1757} 1758