1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3; RUN: opt < %s -passes=instcombine -use-constant-int-for-fixed-length-splat -S | FileCheck %s 4 5declare void @use(i8) 6declare void @use_i1(i1) 7 8define i32 @select_0_or_1_from_bool(i1 %x) { 9; CHECK-LABEL: @select_0_or_1_from_bool( 10; CHECK-NEXT: [[NOT_X:%.*]] = xor i1 [[X:%.*]], true 11; CHECK-NEXT: [[ADD:%.*]] = zext i1 [[NOT_X]] to i32 12; CHECK-NEXT: ret i32 [[ADD]] 13; 14 %ext = sext i1 %x to i32 15 %add = add i32 %ext, 1 16 ret i32 %add 17} 18 19define <2 x i32> @select_0_or_1_from_bool_vec(<2 x i1> %x) { 20; CHECK-LABEL: @select_0_or_1_from_bool_vec( 21; CHECK-NEXT: [[NOT_X:%.*]] = xor <2 x i1> [[X:%.*]], splat (i1 true) 22; CHECK-NEXT: [[ADD:%.*]] = zext <2 x i1> [[NOT_X]] to <2 x i32> 23; CHECK-NEXT: ret <2 x i32> [[ADD]] 24; 25 %ext = sext <2 x i1> %x to <2 x i32> 26 %add = add <2 x i32> %ext, <i32 1, i32 1> 27 ret <2 x i32> %add 28} 29 30define i32 @select_C_minus_1_or_C_from_bool(i1 %x) { 31; CHECK-LABEL: @select_C_minus_1_or_C_from_bool( 32; CHECK-NEXT: [[ADD:%.*]] = select i1 [[X:%.*]], i32 41, i32 42 33; CHECK-NEXT: ret i32 [[ADD]] 34; 35 %ext = sext i1 %x to i32 36 %add = add i32 %ext, 42 37 ret i32 %add 38} 39 40define <2 x i32> @select_C_minus_1_or_C_from_bool_vec(<2 x i1> %x) { 41; CHECK-LABEL: @select_C_minus_1_or_C_from_bool_vec( 42; CHECK-NEXT: [[ADD:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> <i32 41, i32 42>, <2 x i32> <i32 42, i32 43> 43; CHECK-NEXT: ret <2 x i32> [[ADD]] 44; 45 %ext = sext <2 x i1> %x to <2 x i32> 46 %add = add <2 x i32> %ext, <i32 42, i32 43> 47 ret <2 x i32> %add 48} 49 50; This is an 'andn' of the low bit. 51 52define i32 @flip_and_mask(i32 %x) { 53; CHECK-LABEL: @flip_and_mask( 54; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 1 55; CHECK-NEXT: [[INC:%.*]] = xor i32 [[TMP1]], 1 56; CHECK-NEXT: ret i32 [[INC]] 57; 58 %shl = shl i32 %x, 31 59 %shr = ashr i32 %shl, 31 60 %inc = add i32 %shr, 1 61 ret i32 %inc 62} 63 64define <2 x i8> @flip_and_mask_splat(<2 x i8> %x) { 65; CHECK-LABEL: @flip_and_mask_splat( 66; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 1) 67; CHECK-NEXT: [[INC:%.*]] = xor <2 x i8> [[TMP1]], splat (i8 1) 68; CHECK-NEXT: ret <2 x i8> [[INC]] 69; 70 %shl = shl <2 x i8> %x, <i8 7, i8 7> 71 %shr = ashr <2 x i8> %shl, <i8 7, i8 7> 72 %inc = add <2 x i8> %shr, <i8 1, i8 1> 73 ret <2 x i8> %inc 74} 75 76define i32 @test1(i32 %A) { 77; CHECK-LABEL: @test1( 78; CHECK-NEXT: ret i32 [[A:%.*]] 79; 80 %B = add i32 %A, 0 81 ret i32 %B 82} 83 84define i32 @test2(i32 %A) { 85; CHECK-LABEL: @test2( 86; CHECK-NEXT: ret i32 [[A:%.*]] 87; 88 %B = add i32 %A, 5 89 %C = add i32 %B, -5 90 ret i32 %C 91} 92 93define i32 @test3(i32 %A) { 94; CHECK-LABEL: @test3( 95; CHECK-NEXT: ret i32 [[A:%.*]] 96; 97 %B = add i32 %A, 5 98 %C = sub i32 %B, 5 99 ret i32 %C 100} 101 102; D = B + -A = B - A 103define i32 @test4(i32 %A, i32 %BB) { 104; CHECK-LABEL: @test4( 105; CHECK-NEXT: [[B:%.*]] = xor i32 [[BB:%.*]], 1 106; CHECK-NEXT: [[D:%.*]] = sub i32 [[B]], [[A:%.*]] 107; CHECK-NEXT: ret i32 [[D]] 108; 109 %B = xor i32 %BB, 1 ; thwart complexity-based canonicalization 110 %C = sub i32 0, %A 111 %D = add i32 %B, %C 112 ret i32 %D 113} 114 115define i32 @test4_both_nsw(i32 %A, i32 %BB) { 116; CHECK-LABEL: @test4_both_nsw( 117; CHECK-NEXT: [[B:%.*]] = xor i32 [[BB:%.*]], 1 118; CHECK-NEXT: [[D:%.*]] = sub nsw i32 [[B]], [[A:%.*]] 119; CHECK-NEXT: ret i32 [[D]] 120; 121 %B = xor i32 %BB, 1 ; thwart complexity-based canonicalization 122 %C = sub nsw i32 0, %A 123 %D = add nsw i32 %B, %C 124 ret i32 %D 125} 126 127define i32 @test4_neg_nsw(i32 %A, i32 %BB) { 128; CHECK-LABEL: @test4_neg_nsw( 129; CHECK-NEXT: [[B:%.*]] = xor i32 [[BB:%.*]], 1 130; CHECK-NEXT: [[D:%.*]] = sub i32 [[B]], [[A:%.*]] 131; CHECK-NEXT: ret i32 [[D]] 132; 133 %B = xor i32 %BB, 1 ; thwart complexity-based canonicalization 134 %C = sub nsw i32 0, %A 135 %D = add i32 %B, %C 136 ret i32 %D 137} 138 139define i32 @test4_add_nsw(i32 %A, i32 %BB) { 140; CHECK-LABEL: @test4_add_nsw( 141; CHECK-NEXT: [[B:%.*]] = xor i32 [[BB:%.*]], 1 142; CHECK-NEXT: [[D:%.*]] = sub i32 [[B]], [[A:%.*]] 143; CHECK-NEXT: ret i32 [[D]] 144; 145 %B = xor i32 %BB, 1 ; thwart complexity-based canonicalization 146 %C = sub i32 0, %A 147 %D = add nsw i32 %B, %C 148 ret i32 %D 149} 150 151; D = -A + B = B - A 152define i32 @test5(i32 %A, i32 %B) { 153; CHECK-LABEL: @test5( 154; CHECK-NEXT: [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]] 155; CHECK-NEXT: ret i32 [[D]] 156; 157 %C = sub i32 0, %A 158 %D = add i32 %C, %B 159 ret i32 %D 160} 161 162define i32 @test5_both_nsw(i32 %A, i32 %B) { 163; CHECK-LABEL: @test5_both_nsw( 164; CHECK-NEXT: [[D:%.*]] = sub nsw i32 [[B:%.*]], [[A:%.*]] 165; CHECK-NEXT: ret i32 [[D]] 166; 167 %C = sub nsw i32 0, %A 168 %D = add nsw i32 %C, %B 169 ret i32 %D 170} 171 172define i32 @test5_neg_nsw(i32 %A, i32 %B) { 173; CHECK-LABEL: @test5_neg_nsw( 174; CHECK-NEXT: [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]] 175; CHECK-NEXT: ret i32 [[D]] 176; 177 %C = sub nsw i32 0, %A 178 %D = add i32 %C, %B 179 ret i32 %D 180} 181 182define i32 @test5_add_nsw(i32 %A, i32 %B) { 183; CHECK-LABEL: @test5_add_nsw( 184; CHECK-NEXT: [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]] 185; CHECK-NEXT: ret i32 [[D]] 186; 187 %C = sub i32 0, %A 188 %D = add nsw i32 %C, %B 189 ret i32 %D 190} 191 192define <2 x i8> @neg_op0_vec_poison_elt(<2 x i8> %a, <2 x i8> %b) { 193; CHECK-LABEL: @neg_op0_vec_poison_elt( 194; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> [[B:%.*]], [[A:%.*]] 195; CHECK-NEXT: ret <2 x i8> [[R]] 196; 197 %nega = sub <2 x i8> <i8 0, i8 poison>, %a 198 %r = add <2 x i8> %nega, %b 199 ret <2 x i8> %r 200} 201 202define <2 x i8> @neg_neg_vec_poison_elt(<2 x i8> %a, <2 x i8> %b) { 203; CHECK-LABEL: @neg_neg_vec_poison_elt( 204; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[A:%.*]], [[B:%.*]] 205; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]] 206; CHECK-NEXT: ret <2 x i8> [[R]] 207; 208 %nega = sub <2 x i8> <i8 poison, i8 0>, %a 209 %negb = sub <2 x i8> <i8 poison, i8 0>, %b 210 %r = add <2 x i8> %nega, %negb 211 ret <2 x i8> %r 212} 213 214; C = 7*A+A == 8*A == A << 3 215define i32 @test6(i32 %A) { 216; CHECK-LABEL: @test6( 217; CHECK-NEXT: [[C:%.*]] = shl i32 [[A:%.*]], 3 218; CHECK-NEXT: ret i32 [[C]] 219; 220 %B = mul i32 7, %A 221 %C = add i32 %B, %A 222 ret i32 %C 223} 224 225; C = A+7*A == 8*A == A << 3 226define i32 @test7(i32 %A) { 227; CHECK-LABEL: @test7( 228; CHECK-NEXT: [[C:%.*]] = shl i32 [[A:%.*]], 3 229; CHECK-NEXT: ret i32 [[C]] 230; 231 %B = mul i32 7, %A 232 %C = add i32 %A, %B 233 ret i32 %C 234} 235 236; (A & C1)+(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0 237define i32 @test8(i32 %A, i32 %B) { 238; CHECK-LABEL: @test8( 239; CHECK-NEXT: [[A1:%.*]] = and i32 [[A:%.*]], 7 240; CHECK-NEXT: [[B1:%.*]] = and i32 [[B:%.*]], 128 241; CHECK-NEXT: [[C:%.*]] = or disjoint i32 [[A1]], [[B1]] 242; CHECK-NEXT: ret i32 [[C]] 243; 244 %A1 = and i32 %A, 7 245 %B1 = and i32 %B, 128 246 %C = add i32 %A1, %B1 247 ret i32 %C 248} 249 250define i32 @test9(i32 %A) { 251; CHECK-LABEL: @test9( 252; CHECK-NEXT: [[C:%.*]] = shl i32 [[A:%.*]], 5 253; CHECK-NEXT: ret i32 [[C]] 254; 255 %B = shl i32 %A, 4 256 %C = add i32 %B, %B 257 ret i32 %C 258} 259 260; a != -b 261define i1 @test10(i8 %a, i8 %b) { 262; CHECK-LABEL: @test10( 263; CHECK-NEXT: [[ADD:%.*]] = sub i8 0, [[B:%.*]] 264; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A:%.*]], [[ADD]] 265; CHECK-NEXT: ret i1 [[C]] 266; 267 %add = add i8 %a, %b 268 %c = icmp ne i8 %add, 0 269 ret i1 %c 270} 271 272define <2 x i1> @test10vec(<2 x i8> %a, <2 x i8> %b) { 273; CHECK-LABEL: @test10vec( 274; CHECK-NEXT: [[C:%.*]] = sub <2 x i8> zeroinitializer, [[B:%.*]] 275; CHECK-NEXT: [[D:%.*]] = icmp ne <2 x i8> [[A:%.*]], [[C]] 276; CHECK-NEXT: ret <2 x i1> [[D]] 277; 278 %c = add <2 x i8> %a, %b 279 %d = icmp ne <2 x i8> %c, zeroinitializer 280 ret <2 x i1> %d 281} 282 283define i1 @test11(i8 %A) { 284; CHECK-LABEL: @test11( 285; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A:%.*]], 1 286; CHECK-NEXT: ret i1 [[C]] 287; 288 %B = add i8 %A, -1 289 %c = icmp ne i8 %B, 0 290 ret i1 %c 291} 292 293define <2 x i1> @test11vec(<2 x i8> %a) { 294; CHECK-LABEL: @test11vec( 295; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[A:%.*]], splat (i8 1) 296; CHECK-NEXT: ret <2 x i1> [[C]] 297; 298 %b = add <2 x i8> %a, <i8 -1, i8 -1> 299 %c = icmp ne <2 x i8> %b, zeroinitializer 300 ret <2 x i1> %c 301} 302 303define i8 @reassoc_shl1(i8 %x, i8 %y) { 304; CHECK-LABEL: @reassoc_shl1( 305; CHECK-NEXT: [[REASS_ADD:%.*]] = shl i8 [[X:%.*]], 1 306; CHECK-NEXT: [[R:%.*]] = add i8 [[Y:%.*]], [[REASS_ADD]] 307; CHECK-NEXT: ret i8 [[R]] 308; 309 %a = add i8 %y, %x 310 %r = add i8 %a, %x 311 ret i8 %r 312} 313 314define <2 x i8> @reassoc_shl1_commute1(<2 x i8> %x, <2 x i8> %y) { 315; CHECK-LABEL: @reassoc_shl1_commute1( 316; CHECK-NEXT: [[REASS_ADD:%.*]] = shl <2 x i8> [[X:%.*]], splat (i8 1) 317; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[Y:%.*]], [[REASS_ADD]] 318; CHECK-NEXT: ret <2 x i8> [[R]] 319; 320 %a = add <2 x i8> %x, %y 321 %r = add <2 x i8> %a, %x 322 ret <2 x i8> %r 323} 324 325define i8 @reassoc_shl1_commute2(i8 %px, i8 %py) { 326; CHECK-LABEL: @reassoc_shl1_commute2( 327; CHECK-NEXT: [[X:%.*]] = sdiv i8 42, [[PX:%.*]] 328; CHECK-NEXT: [[Y:%.*]] = sdiv i8 43, [[PY:%.*]] 329; CHECK-NEXT: [[REASS_ADD:%.*]] = shl i8 [[X]], 1 330; CHECK-NEXT: [[R:%.*]] = add i8 [[Y]], [[REASS_ADD]] 331; CHECK-NEXT: ret i8 [[R]] 332; 333 %x = sdiv i8 42, %px ; thwart complexity-based canonicalization 334 %y = sdiv i8 43, %py ; thwart complexity-based canonicalization 335 %a = add i8 %y, %x 336 %r = add i8 %x, %a 337 ret i8 %r 338} 339 340define i8 @reassoc_shl1_commute3(i8 %px, i8 %py) { 341; CHECK-LABEL: @reassoc_shl1_commute3( 342; CHECK-NEXT: [[X:%.*]] = sdiv i8 42, [[PX:%.*]] 343; CHECK-NEXT: [[Y:%.*]] = sdiv i8 43, [[PY:%.*]] 344; CHECK-NEXT: [[REASS_ADD:%.*]] = shl i8 [[X]], 1 345; CHECK-NEXT: [[R:%.*]] = add i8 [[Y]], [[REASS_ADD]] 346; CHECK-NEXT: ret i8 [[R]] 347; 348 %x = sdiv i8 42, %px ; thwart complexity-based canonicalization 349 %y = sdiv i8 43, %py ; thwart complexity-based canonicalization 350 %a = add i8 %x, %y 351 %r = add i8 %x, %a 352 ret i8 %r 353} 354 355define i8 @reassoc_shl1_extra_use(i8 %x, i8 %y) { 356; CHECK-LABEL: @reassoc_shl1_extra_use( 357; CHECK-NEXT: [[A:%.*]] = add i8 [[Y:%.*]], [[X:%.*]] 358; CHECK-NEXT: call void @use(i8 [[A]]) 359; CHECK-NEXT: [[R:%.*]] = add i8 [[A]], [[X]] 360; CHECK-NEXT: ret i8 [[R]] 361; 362 %a = add i8 %y, %x 363 call void @use(i8 %a) 364 %r = add i8 %a, %x 365 ret i8 %r 366} 367 368;; TODO: shl A, 1? 369define i32 @test13(i32 %A, i32 %B, i32 %C) { 370; CHECK-LABEL: @test13( 371; CHECK-NEXT: [[D_OK:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 372; CHECK-NEXT: [[E_OK:%.*]] = add i32 [[D_OK]], [[C:%.*]] 373; CHECK-NEXT: [[F:%.*]] = add i32 [[E_OK]], [[A]] 374; CHECK-NEXT: ret i32 [[F]] 375; 376 %D_OK = add i32 %A, %B 377 %E_OK = add i32 %D_OK, %C 378 %F = add i32 %E_OK, %A 379 ret i32 %F 380} 381 382define i32 @test14(i32 %offset, i32 %difference) { 383; CHECK-LABEL: @test14( 384; CHECK-NEXT: [[TMP_2:%.*]] = and i32 [[DIFFERENCE:%.*]], 3 385; CHECK-NEXT: [[TMP_3_OK:%.*]] = add i32 [[TMP_2]], [[OFFSET:%.*]] 386; CHECK-NEXT: [[TMP_5_MASK:%.*]] = and i32 [[DIFFERENCE]], -4 387; CHECK-NEXT: [[TMP_8:%.*]] = add i32 [[TMP_3_OK]], [[TMP_5_MASK]] 388; CHECK-NEXT: ret i32 [[TMP_8]] 389; 390 %tmp.2 = and i32 %difference, 3 391 %tmp.3_OK = add i32 %tmp.2, %offset 392 %tmp.5.mask = and i32 %difference, -4 393 ; == add %offset, %difference 394 %tmp.8 = add i32 %tmp.3_OK, %tmp.5.mask 395 ret i32 %tmp.8 396} 397 398; Only one bit set 399define i8 @test15(i8 %A) { 400; CHECK-LABEL: @test15( 401; CHECK-NEXT: [[C:%.*]] = and i8 [[A:%.*]], 16 402; CHECK-NEXT: ret i8 [[C]] 403; 404 %B = add i8 %A, -64 405 %C = and i8 %B, 16 406 ret i8 %C 407} 408 409define i32 @test17(i32 %A) { 410; CHECK-LABEL: @test17( 411; CHECK-NEXT: [[C:%.*]] = sub i32 0, [[A:%.*]] 412; CHECK-NEXT: ret i32 [[C]] 413; 414 %B = xor i32 %A, -1 415 %C = add i32 %B, 1 416 ret i32 %C 417} 418 419define i8 @test18(i8 %A) { 420; CHECK-LABEL: @test18( 421; CHECK-NEXT: [[C:%.*]] = sub i8 16, [[A:%.*]] 422; CHECK-NEXT: ret i8 [[C]] 423; 424 %B = xor i8 %A, -1 425 %C = add i8 %B, 17 426 ret i8 %C 427} 428 429; ~X + -127 and (-128) - X with nsw are equally poisonous 430define i8 @test18_nsw(i8 %A) { 431; CHECK-LABEL: @test18_nsw( 432; CHECK-NEXT: [[C:%.*]] = sub nsw i8 -128, [[A:%.*]] 433; CHECK-NEXT: ret i8 [[C]] 434; 435 %B = xor i8 %A, -1 436 %C = add nsw i8 %B, -127 437 ret i8 %C 438} 439 440; nuw couldn't propagate as nsw is. 441define i8 @test18_nuw(i8 %A) { 442; CHECK-LABEL: @test18_nuw( 443; CHECK-NEXT: [[C:%.*]] = sub i8 -128, [[A:%.*]] 444; CHECK-NEXT: ret i8 [[C]] 445; 446 %B = xor i8 %A, -1 447 %C = add nuw i8 %B, -127 448 ret i8 %C 449} 450 451; 127 - X with nsw will be more poisonous than ~X + -128 with nsw. (see X = -1) 452define i8 @test18_nsw_overflow(i8 %A) { 453; CHECK-LABEL: @test18_nsw_overflow( 454; CHECK-NEXT: [[C:%.*]] = sub i8 127, [[A:%.*]] 455; CHECK-NEXT: ret i8 [[C]] 456; 457 %B = xor i8 %A, -1 458 %C = add nsw i8 %B, -128 459 ret i8 %C 460} 461 462define <2 x i64> @test18vec(<2 x i64> %A) { 463; CHECK-LABEL: @test18vec( 464; CHECK-NEXT: [[ADD:%.*]] = sub <2 x i64> <i64 1, i64 2>, [[A:%.*]] 465; CHECK-NEXT: ret <2 x i64> [[ADD]] 466; 467 %xor = xor <2 x i64> %A, <i64 -1, i64 -1> 468 %add = add <2 x i64> %xor, <i64 2, i64 3> 469 ret <2 x i64> %add 470} 471 472define <2 x i8> @test18vec_nsw(<2 x i8> %A) { 473; CHECK-LABEL: @test18vec_nsw( 474; CHECK-NEXT: [[C:%.*]] = sub nsw <2 x i8> <i8 -124, i8 -125>, [[A:%.*]] 475; CHECK-NEXT: ret <2 x i8> [[C]] 476; 477 %B = xor <2 x i8> %A, <i8 -1, i8 -1> 478 %C = add nsw <2 x i8> %B, <i8 -123, i8 -124> 479 ret <2 x i8> %C 480} 481 482define <2 x i8> @test18vec_nsw_false(<2 x i8> %A) { 483; CHECK-LABEL: @test18vec_nsw_false( 484; CHECK-NEXT: [[C:%.*]] = sub nsw <2 x i8> <i8 -125, i8 -126>, [[A:%.*]] 485; CHECK-NEXT: ret <2 x i8> [[C]] 486; 487 %B = xor <2 x i8> %A, <i8 -1, i8 -1> 488 %C = add nsw <2 x i8> %B, <i8 -124, i8 -125> 489 ret <2 x i8> %C 490} 491 492 493define <2 x i8> @test18vec_nuw(<2 x i8> %A) { 494; CHECK-LABEL: @test18vec_nuw( 495; CHECK-NEXT: [[C:%.*]] = sub <2 x i8> <i8 -128, i8 -127>, [[A:%.*]] 496; CHECK-NEXT: ret <2 x i8> [[C]] 497; 498 %B = xor <2 x i8> %A, <i8 -1, i8 -1> 499 %C = add nuw <2 x i8> %B, <i8 -127, i8 -126> 500 ret <2 x i8> %C 501} 502 503define <2 x i8> @test18vec_nsw_overflow(<2 x i8> %A) { 504; CHECK-LABEL: @test18vec_nsw_overflow( 505; CHECK-NEXT: [[C:%.*]] = sub <2 x i8> <i8 -128, i8 127>, [[A:%.*]] 506; CHECK-NEXT: ret <2 x i8> [[C]] 507; 508 %B = xor <2 x i8> %A, <i8 -1, i8 -1> 509 %C = add nsw <2 x i8> %B, <i8 -127, i8 -128> 510 ret <2 x i8> %C 511} 512 513define i32 @test19(i1 %C) { 514; CHECK-LABEL: @test19( 515; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 1123, i32 133 516; CHECK-NEXT: ret i32 [[V]] 517; 518 %A = select i1 %C, i32 1000, i32 10 519 %V = add i32 %A, 123 520 ret i32 %V 521} 522 523define <2 x i32> @test19vec(i1 %C) { 524; CHECK-LABEL: @test19vec( 525; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> splat (i32 1123), <2 x i32> splat (i32 133) 526; CHECK-NEXT: ret <2 x i32> [[V]] 527; 528 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10> 529 %V = add <2 x i32> %A, <i32 123, i32 123> 530 ret <2 x i32> %V 531} 532 533; This is an InstSimplify fold, but test it here to make sure that 534; InstCombine does not prevent the fold. 535; With NSW, add of sign bit -> or of sign bit. 536 537define i32 @test20(i32 %x) { 538; CHECK-LABEL: @test20( 539; CHECK-NEXT: ret i32 [[X:%.*]] 540; 541 %y = xor i32 %x, -2147483648 542 %z = add nsw i32 %y, -2147483648 543 ret i32 %z 544} 545 546define i32 @xor_sign_bit(i32 %x) { 547; CHECK-LABEL: @xor_sign_bit( 548; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], -2147483606 549; CHECK-NEXT: ret i32 [[ADD]] 550; 551 %xor = xor i32 %x, 2147483648 552 %add = add i32 %xor, 42 553 ret i32 %add 554} 555 556define <2 x i32> @xor_sign_bit_vec_splat(<2 x i32> %x) { 557; CHECK-LABEL: @xor_sign_bit_vec_splat( 558; CHECK-NEXT: [[ADD:%.*]] = add <2 x i32> [[X:%.*]], splat (i32 -2147483606) 559; CHECK-NEXT: ret <2 x i32> [[ADD]] 560; 561 %xor = xor <2 x i32> %x, <i32 2147483648, i32 2147483648> 562 %add = add <2 x i32> %xor, <i32 42, i32 42> 563 ret <2 x i32> %add 564} 565 566; No-wrap info allows converting the add to 'or'. 567 568define i8 @add_nsw_signbit(i8 %x) { 569; CHECK-LABEL: @add_nsw_signbit( 570; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], -128 571; CHECK-NEXT: ret i8 [[Y]] 572; 573 %y = add nsw i8 %x, -128 574 ret i8 %y 575} 576 577; No-wrap info allows converting the add to 'or'. 578 579define i8 @add_nuw_signbit(i8 %x) { 580; CHECK-LABEL: @add_nuw_signbit( 581; CHECK-NEXT: [[Y:%.*]] = or i8 [[X:%.*]], -128 582; CHECK-NEXT: ret i8 [[Y]] 583; 584 %y = add nuw i8 %x, 128 585 ret i8 %y 586} 587 588define i32 @add_nsw_sext_add(i8 %x) { 589; CHECK-LABEL: @add_nsw_sext_add( 590; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32 591; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[TMP1]], 398 592; CHECK-NEXT: ret i32 [[R]] 593; 594 %add = add nsw i8 %x, 42 595 %ext = sext i8 %add to i32 596 %r = add i32 %ext, 356 597 ret i32 %r 598} 599 600; Negative test - extra use of the sext means increase of instructions. 601 602define i32 @add_nsw_sext_add_extra_use_1(i8 %x, ptr %p) { 603; CHECK-LABEL: @add_nsw_sext_add_extra_use_1( 604; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[X:%.*]], 42 605; CHECK-NEXT: [[EXT:%.*]] = sext i8 [[ADD]] to i32 606; CHECK-NEXT: store i32 [[EXT]], ptr [[P:%.*]], align 4 607; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[EXT]], 356 608; CHECK-NEXT: ret i32 [[R]] 609; 610 %add = add nsw i8 %x, 42 611 %ext = sext i8 %add to i32 612 store i32 %ext, ptr %p 613 %r = add i32 %ext, 356 614 ret i32 %r 615} 616 617define <2 x i32> @add_nsw_sext_add_vec_extra_use_2(<2 x i8> %x, ptr %p) { 618; CHECK-LABEL: @add_nsw_sext_add_vec_extra_use_2( 619; CHECK-NEXT: [[ADD:%.*]] = add nsw <2 x i8> [[X:%.*]], <i8 42, i8 -5> 620; CHECK-NEXT: store <2 x i8> [[ADD]], ptr [[P:%.*]], align 2 621; CHECK-NEXT: [[TMP1:%.*]] = sext <2 x i8> [[X]] to <2 x i32> 622; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i32> [[TMP1]], <i32 398, i32 7> 623; CHECK-NEXT: ret <2 x i32> [[R]] 624; 625 %add = add nsw <2 x i8> %x, <i8 42, i8 -5> 626 store <2 x i8> %add, ptr %p 627 %ext = sext <2 x i8> %add to <2 x i32> 628 %r = add <2 x i32> %ext, <i32 356, i32 12> 629 ret <2 x i32> %r 630} 631 632define <2 x i32> @add_nuw_zext_add_vec(<2 x i16> %x) { 633; CHECK-LABEL: @add_nuw_zext_add_vec( 634; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i16> [[X:%.*]] to <2 x i32> 635; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i32> [[TMP1]], <i32 65850, i32 -7> 636; CHECK-NEXT: ret <2 x i32> [[R]] 637; 638 %add = add nuw <2 x i16> %x, <i16 -42, i16 5> 639 %ext = zext <2 x i16> %add to <2 x i32> 640 %r = add <2 x i32> %ext, <i32 356, i32 -12> 641 ret <2 x i32> %r 642} 643 644; Negative test - extra use of the zext means increase of instructions. 645 646define i64 @add_nuw_zext_add_extra_use_1(i8 %x, ptr %p) { 647; CHECK-LABEL: @add_nuw_zext_add_extra_use_1( 648; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[X:%.*]], 42 649; CHECK-NEXT: [[EXT:%.*]] = zext i8 [[ADD]] to i64 650; CHECK-NEXT: store i64 [[EXT]], ptr [[P:%.*]], align 4 651; CHECK-NEXT: [[R:%.*]] = add nuw nsw i64 [[EXT]], 356 652; CHECK-NEXT: ret i64 [[R]] 653; 654 %add = add nuw i8 %x, 42 655 %ext = zext i8 %add to i64 656 store i64 %ext, ptr %p 657 %r = add i64 %ext, 356 658 ret i64 %r 659} 660 661define i64 @add_nuw_zext_add_extra_use_2(i8 %x, ptr %p) { 662; CHECK-LABEL: @add_nuw_zext_add_extra_use_2( 663; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[X:%.*]], 42 664; CHECK-NEXT: store i8 [[ADD]], ptr [[P:%.*]], align 1 665; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[X]] to i64 666; CHECK-NEXT: [[R:%.*]] = add nuw nsw i64 [[TMP1]], -314 667; CHECK-NEXT: ret i64 [[R]] 668; 669 %add = add nuw i8 %x, 42 670 store i8 %add, ptr %p 671 %ext = zext i8 %add to i64 672 %r = add i64 %ext, -356 673 ret i64 %r 674} 675 676define i1 @test21(i32 %x) { 677; CHECK-LABEL: @test21( 678; CHECK-NEXT: [[Y:%.*]] = icmp eq i32 [[X:%.*]], 119 679; CHECK-NEXT: ret i1 [[Y]] 680; 681 %t = add i32 %x, 4 682 %y = icmp eq i32 %t, 123 683 ret i1 %y 684} 685 686define <2 x i1> @test21vec(<2 x i32> %x) { 687; CHECK-LABEL: @test21vec( 688; CHECK-NEXT: [[Y:%.*]] = icmp eq <2 x i32> [[X:%.*]], splat (i32 119) 689; CHECK-NEXT: ret <2 x i1> [[Y]] 690; 691 %t = add <2 x i32> %x, <i32 4, i32 4> 692 %y = icmp eq <2 x i32> %t, <i32 123, i32 123> 693 ret <2 x i1> %y 694} 695 696define i32 @test22(i32 %V) { 697; CHECK-LABEL: @test22( 698; CHECK-NEXT: switch i32 [[V:%.*]], label [[DEFAULT:%.*]] [ 699; CHECK-NEXT: i32 10, label [[LAB1:%.*]] 700; CHECK-NEXT: i32 20, label [[LAB2:%.*]] 701; CHECK-NEXT: ] 702; CHECK: Default: 703; CHECK-NEXT: ret i32 123 704; CHECK: Lab1: 705; CHECK-NEXT: ret i32 12312 706; CHECK: Lab2: 707; CHECK-NEXT: ret i32 1231231 708; 709 %V2 = add i32 %V, 10 710 switch i32 %V2, label %Default [ 711 i32 20, label %Lab1 712 i32 30, label %Lab2 713 ] 714 715Default: ; preds = %0 716 ret i32 123 717 718Lab1: ; preds = %0 719 ret i32 12312 720 721Lab2: ; preds = %0 722 ret i32 1231231 723} 724 725define i32 @test23(i1 %C, i32 %a) { 726; CHECK-LABEL: @test23( 727; CHECK-NEXT: entry: 728; CHECK-NEXT: br i1 [[C:%.*]], label [[ENDIF:%.*]], label [[ELSE:%.*]] 729; CHECK: else: 730; CHECK-NEXT: br label [[ENDIF]] 731; CHECK: endif: 732; CHECK-NEXT: [[B_0:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 2, [[ELSE]] ] 733; CHECK-NEXT: ret i32 [[B_0]] 734; 735entry: 736 br i1 %C, label %endif, label %else 737 738else: ; preds = %entry 739 br label %endif 740 741endif: ; preds = %else, %entry 742 %b.0 = phi i32 [ 0, %entry ], [ 1, %else ] 743 %tmp.4 = add i32 %b.0, 1 744 ret i32 %tmp.4 745} 746 747define i32 @test24(i32 %A) { 748; CHECK-LABEL: @test24( 749; CHECK-NEXT: [[B:%.*]] = shl i32 [[A:%.*]], 1 750; CHECK-NEXT: ret i32 [[B]] 751; 752 %B = add i32 %A, 1 753 %C = shl i32 %B, 1 754 %D = sub i32 %C, 2 755 ret i32 %D 756} 757 758define i64 @test25(i64 %Y) { 759; CHECK-LABEL: @test25( 760; CHECK-NEXT: [[TMP_8:%.*]] = shl i64 [[Y:%.*]], 3 761; CHECK-NEXT: ret i64 [[TMP_8]] 762; 763 %tmp.4 = shl i64 %Y, 2 764 %tmp.12 = shl i64 %Y, 2 765 %tmp.8 = add i64 %tmp.4, %tmp.12 766 ret i64 %tmp.8 767} 768 769define i32 @test26(i32 %A, i32 %B) { 770; CHECK-LABEL: @test26( 771; CHECK-NEXT: ret i32 [[A:%.*]] 772; 773 %C = add i32 %A, %B 774 %D = sub i32 %C, %B 775 ret i32 %D 776} 777 778; Fold add through select. 779define i32 @test27(i1 %C, i32 %X, i32 %Y) { 780; CHECK-LABEL: @test27( 781; CHECK-NEXT: [[C_UPGRD_1_V:%.*]] = select i1 [[C:%.*]], i32 [[X:%.*]], i32 123 782; CHECK-NEXT: ret i32 [[C_UPGRD_1_V]] 783; 784 %A = add i32 %X, %Y 785 %B = add i32 %Y, 123 786 %C.upgrd.1 = select i1 %C, i32 %A, i32 %B 787 %D = sub i32 %C.upgrd.1, %Y 788 ret i32 %D 789} 790 791define i32 @test28(i32 %X) { 792; CHECK-LABEL: @test28( 793; CHECK-NEXT: [[Z:%.*]] = sub i32 -1192, [[X:%.*]] 794; CHECK-NEXT: ret i32 [[Z]] 795; 796 %Y = add i32 %X, 1234 797 %Z = sub i32 42, %Y 798 ret i32 %Z 799} 800 801define i32 @test29(i32 %x, i32 %y) { 802; CHECK-LABEL: @test29( 803; CHECK-NEXT: [[TMP_2:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]] 804; CHECK-NEXT: [[TMP_7:%.*]] = and i32 [[X]], 63 805; CHECK-NEXT: [[TMP_9:%.*]] = and i32 [[TMP_2]], -64 806; CHECK-NEXT: [[TMP_10:%.*]] = or disjoint i32 [[TMP_7]], [[TMP_9]] 807; CHECK-NEXT: ret i32 [[TMP_10]] 808; 809 %tmp.2 = sub i32 %x, %y 810 %tmp.2.mask = and i32 %tmp.2, 63 811 %tmp.6 = add i32 %tmp.2.mask, %y 812 %tmp.7 = and i32 %tmp.6, 63 813 %tmp.9 = and i32 %tmp.2, -64 814 %tmp.10 = or i32 %tmp.7, %tmp.9 815 ret i32 %tmp.10 816} 817 818; Add of sign bit -> xor of sign bit. 819define i64 @test30(i64 %x) { 820; CHECK-LABEL: @test30( 821; CHECK-NEXT: ret i64 [[X:%.*]] 822; 823 %tmp.2 = xor i64 %x, -9223372036854775808 824 %tmp.4 = add i64 %tmp.2, -9223372036854775808 825 ret i64 %tmp.4 826} 827 828define i32 @test31(i32 %A) { 829; CHECK-LABEL: @test31( 830; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[A:%.*]], 5 831; CHECK-NEXT: ret i32 [[TMP1]] 832; 833 %B = add i32 %A, 4 834 %C = mul i32 %B, 5 835 %D = sub i32 %C, 20 836 ret i32 %D 837} 838 839define i32 @test32(i32 %A) { 840; CHECK-LABEL: @test32( 841; CHECK-NEXT: [[B:%.*]] = shl i32 [[A:%.*]], 2 842; CHECK-NEXT: ret i32 [[B]] 843; 844 %B = add i32 %A, 4 845 %C = shl i32 %B, 2 846 %D = sub i32 %C, 16 847 ret i32 %D 848} 849 850define i8 @test33(i8 %A) { 851; CHECK-LABEL: @test33( 852; CHECK-NEXT: [[C:%.*]] = or i8 [[A:%.*]], 1 853; CHECK-NEXT: ret i8 [[C]] 854; 855 %B = and i8 %A, -2 856 %C = add i8 %B, 1 857 ret i8 %C 858} 859 860define i8 @test34(i8 %A) { 861; CHECK-LABEL: @test34( 862; CHECK-NEXT: [[C:%.*]] = and i8 [[A:%.*]], 12 863; CHECK-NEXT: ret i8 [[C]] 864; 865 %B = add i8 %A, 64 866 %C = and i8 %B, 12 867 ret i8 %C 868} 869 870; If all bits affected by the add are included 871; in the mask, do the mask op before the add. 872 873define i8 @masked_add(i8 %x) { 874; CHECK-LABEL: @masked_add( 875; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], -16 876; CHECK-NEXT: [[R:%.*]] = add i8 [[AND]], 96 877; CHECK-NEXT: ret i8 [[R]] 878; 879 %and = and i8 %x, 240 ; 0xf0 880 %r = add i8 %and, 96 ; 0x60 881 ret i8 %r 882} 883 884define <2 x i8> @masked_add_splat(<2 x i8> %x) { 885; CHECK-LABEL: @masked_add_splat( 886; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 -64) 887; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[AND]], splat (i8 64) 888; CHECK-NEXT: ret <2 x i8> [[R]] 889; 890 %and = and <2 x i8> %x, <i8 192, i8 192> ; 0xc0 891 %r = add <2 x i8> %and, <i8 64, i8 64> ; 0x40 892 ret <2 x i8> %r 893} 894 895define i8 @not_masked_add(i8 %x) { 896; CHECK-LABEL: @not_masked_add( 897; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 112 898; CHECK-NEXT: [[R:%.*]] = add nuw i8 [[AND]], 96 899; CHECK-NEXT: ret i8 [[R]] 900; 901 %and = and i8 %x, 112 ; 0x70 902 %r = add i8 %and, 96 ; 0x60 903 ret i8 %r 904} 905 906define i8 @masked_add_multi_use(i8 %x) { 907; CHECK-LABEL: @masked_add_multi_use( 908; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], -16 909; CHECK-NEXT: [[R:%.*]] = add i8 [[AND]], 96 910; CHECK-NEXT: call void @use(i8 [[AND]]) 911; CHECK-NEXT: ret i8 [[R]] 912; 913 %and = and i8 %x, -16 ; 0xf0 914 %r = add i8 %and, 96 ; 0x60 915 call void @use(i8 %and) ; extra use 916 ret i8 %r 917} 918 919define i32 @test35(i32 %a) { 920; CHECK-LABEL: @test35( 921; CHECK-NEXT: ret i32 -1 922; 923 %tmpnot = xor i32 %a, -1 924 %tmp2 = add i32 %tmpnot, %a 925 ret i32 %tmp2 926} 927 928define i32 @test36(i32 %a) { 929; CHECK-LABEL: @test36( 930; CHECK-NEXT: ret i32 0 931; 932 %x = and i32 %a, -2 933 %y = and i32 %a, -126 934 %z = add i32 %x, %y 935 %q = and i32 %z, 1 ; always zero 936 ret i32 %q 937} 938 939define i1 @test37(i32 %a, i32 %b) { 940; CHECK-LABEL: @test37( 941; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[B:%.*]], 0 942; CHECK-NEXT: ret i1 [[CMP]] 943; 944 %add = add i32 %a, %b 945 %cmp = icmp eq i32 %add, %a 946 ret i1 %cmp 947} 948 949define i1 @test38(i32 %a, i32 %b) { 950; CHECK-LABEL: @test38( 951; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0 952; CHECK-NEXT: ret i1 [[CMP]] 953; 954 %add = add i32 %a, %b 955 %cmp = icmp eq i32 %add, %b 956 ret i1 %cmp 957} 958 959define i1 @test39(i32 %a, i32 %b) { 960; CHECK-LABEL: @test39( 961; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[B:%.*]], 0 962; CHECK-NEXT: ret i1 [[CMP]] 963; 964 %add = add i32 %b, %a 965 %cmp = icmp eq i32 %add, %a 966 ret i1 %cmp 967} 968 969define i1 @test40(i32 %a, i32 %b) { 970; CHECK-LABEL: @test40( 971; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0 972; CHECK-NEXT: ret i1 [[CMP]] 973; 974 %add = add i32 %b, %a 975 %cmp = icmp eq i32 %add, %b 976 ret i1 %cmp 977} 978 979; (add (zext (add nuw X, C2)), C) --> (zext (add nuw X, C2 + C)) 980 981define i64 @test41(i32 %a) { 982; CHECK-LABEL: @test41( 983; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[A:%.*]], 15 984; CHECK-NEXT: [[SUB:%.*]] = zext i32 [[TMP1]] to i64 985; CHECK-NEXT: ret i64 [[SUB]] 986; 987 %add = add nuw i32 %a, 16 988 %zext = zext i32 %add to i64 989 %sub = add i64 %zext, -1 990 ret i64 %sub 991} 992 993define i64 @test41_multiuse_constants_cancel(i32 %a) { 994; CHECK-LABEL: @test41_multiuse_constants_cancel( 995; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[A:%.*]], 1 996; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[ADD]] to i64 997; CHECK-NEXT: [[SUB:%.*]] = zext i32 [[A]] to i64 998; CHECK-NEXT: [[EXTRAUSE:%.*]] = add nuw nsw i64 [[ZEXT]], [[SUB]] 999; CHECK-NEXT: ret i64 [[EXTRAUSE]] 1000; 1001 %add = add nuw i32 %a, 1 1002 %zext = zext i32 %add to i64 1003 %sub = add i64 %zext, -1 1004 %extrause = add i64 %zext, %sub 1005 ret i64 %extrause 1006} 1007 1008; (add (zext (add nuw X, C2)), C) --> (zext (add nuw X, C2 + C)) 1009 1010define <2 x i64> @test41vec(<2 x i32> %a) { 1011; CHECK-LABEL: @test41vec( 1012; CHECK-NEXT: [[TMP1:%.*]] = add nuw <2 x i32> [[A:%.*]], splat (i32 15) 1013; CHECK-NEXT: [[SUB:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64> 1014; CHECK-NEXT: ret <2 x i64> [[SUB]] 1015; 1016 %add = add nuw <2 x i32> %a, <i32 16, i32 16> 1017 %zext = zext <2 x i32> %add to <2 x i64> 1018 %sub = add <2 x i64> %zext, <i64 -1, i64 -1> 1019 ret <2 x i64> %sub 1020} 1021 1022define <2 x i64> @test41vec_and_multiuse(<2 x i32> %a) { 1023; CHECK-LABEL: @test41vec_and_multiuse( 1024; CHECK-NEXT: [[ADD:%.*]] = add nuw <2 x i32> [[A:%.*]], splat (i32 16) 1025; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i32> [[ADD]] to <2 x i64> 1026; CHECK-NEXT: [[REASS_ADD:%.*]] = shl nuw nsw <2 x i64> [[ZEXT]], splat (i64 1) 1027; CHECK-NEXT: [[EXTRAUSE:%.*]] = add nsw <2 x i64> [[REASS_ADD]], splat (i64 -1) 1028; CHECK-NEXT: ret <2 x i64> [[EXTRAUSE]] 1029; 1030 %add = add nuw <2 x i32> %a, <i32 16, i32 16> 1031 %zext = zext <2 x i32> %add to <2 x i64> 1032 %sub = add <2 x i64> %zext, <i64 -1, i64 -1> 1033 %extrause = add <2 x i64> %zext, %sub 1034 ret <2 x i64> %extrause 1035} 1036 1037define i32 @test42(i1 %C) { 1038; CHECK-LABEL: @test42( 1039; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 1123, i32 133 1040; CHECK-NEXT: ret i32 [[V]] 1041; 1042 %A = select i1 %C, i32 1000, i32 10 1043 %V = add i32 123, %A 1044 ret i32 %V 1045} 1046 1047define <2 x i32> @test42vec(i1 %C) { 1048; CHECK-LABEL: @test42vec( 1049; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> splat (i32 1123), <2 x i32> splat (i32 133) 1050; CHECK-NEXT: ret <2 x i32> [[V]] 1051; 1052 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10> 1053 %V = add <2 x i32> <i32 123, i32 123>, %A 1054 ret <2 x i32> %V 1055} 1056 1057define <2 x i32> @test42vec2(i1 %C) { 1058; CHECK-LABEL: @test42vec2( 1059; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 2833>, <2 x i32> <i32 133, i32 363> 1060; CHECK-NEXT: ret <2 x i32> [[V]] 1061; 1062 %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30> 1063 %V = add <2 x i32> <i32 123, i32 333>, %A 1064 ret <2 x i32> %V 1065} 1066 1067define i32 @test55(i1 %which) { 1068; CHECK-LABEL: @test55( 1069; CHECK-NEXT: entry: 1070; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 1071; CHECK: delay: 1072; CHECK-NEXT: br label [[FINAL]] 1073; CHECK: final: 1074; CHECK-NEXT: [[A:%.*]] = phi i32 [ 1123, [[ENTRY:%.*]] ], [ 133, [[DELAY]] ] 1075; CHECK-NEXT: ret i32 [[A]] 1076; 1077entry: 1078 br i1 %which, label %final, label %delay 1079 1080delay: 1081 br label %final 1082 1083final: 1084 %A = phi i32 [ 1000, %entry ], [ 10, %delay ] 1085 %value = add i32 123, %A 1086 ret i32 %value 1087} 1088 1089define <2 x i32> @test43vec(i1 %which) { 1090; CHECK-LABEL: @test43vec( 1091; CHECK-NEXT: entry: 1092; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 1093; CHECK: delay: 1094; CHECK-NEXT: br label [[FINAL]] 1095; CHECK: final: 1096; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ splat (i32 1123), [[ENTRY:%.*]] ], [ splat (i32 133), [[DELAY]] ] 1097; CHECK-NEXT: ret <2 x i32> [[A]] 1098; 1099entry: 1100 br i1 %which, label %final, label %delay 1101 1102delay: 1103 br label %final 1104 1105final: 1106 %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ] 1107 %value = add <2 x i32> <i32 123, i32 123>, %A 1108 ret <2 x i32> %value 1109} 1110 1111define <2 x i32> @test43vec2(i1 %which) { 1112; CHECK-LABEL: @test43vec2( 1113; CHECK-NEXT: entry: 1114; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 1115; CHECK: delay: 1116; CHECK-NEXT: br label [[FINAL]] 1117; CHECK: final: 1118; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1123, i32 2833>, [[ENTRY:%.*]] ], [ <i32 133, i32 363>, [[DELAY]] ] 1119; CHECK-NEXT: ret <2 x i32> [[A]] 1120; 1121entry: 1122 br i1 %which, label %final, label %delay 1123 1124delay: 1125 br label %final 1126 1127final: 1128 %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ] 1129 %value = add <2 x i32> <i32 123, i32 333>, %A 1130 ret <2 x i32> %value 1131} 1132 1133; E = (A + 1) + ~B = A - B 1134define i32 @add_not_increment(i32 %A, i32 %B) { 1135; CHECK-LABEL: @add_not_increment( 1136; CHECK-NEXT: [[E:%.*]] = sub i32 [[A:%.*]], [[B:%.*]] 1137; CHECK-NEXT: ret i32 [[E]] 1138; 1139 %C = xor i32 %B, -1 1140 %D = add i32 %A, 1 1141 %E = add i32 %D, %C 1142 ret i32 %E 1143} 1144 1145; E = (A + 1) + ~B = A - B 1146define <2 x i32> @add_not_increment_vec(<2 x i32> %A, <2 x i32> %B) { 1147; CHECK-LABEL: @add_not_increment_vec( 1148; CHECK-NEXT: [[E:%.*]] = sub <2 x i32> [[A:%.*]], [[B:%.*]] 1149; CHECK-NEXT: ret <2 x i32> [[E]] 1150; 1151 %C = xor <2 x i32> %B, <i32 -1, i32 -1> 1152 %D = add <2 x i32> %A, <i32 1, i32 1> 1153 %E = add <2 x i32> %D, %C 1154 ret <2 x i32> %E 1155} 1156 1157; E = ~B + (1 + A) = A - B 1158define i32 @add_not_increment_commuted(i32 %A, i32 %B) { 1159; CHECK-LABEL: @add_not_increment_commuted( 1160; CHECK-NEXT: [[E:%.*]] = sub i32 [[A:%.*]], [[B:%.*]] 1161; CHECK-NEXT: ret i32 [[E]] 1162; 1163 %C = xor i32 %B, -1 1164 %D = add i32 %A, 1 1165 %E = add i32 %C, %D 1166 ret i32 %E 1167} 1168 1169; E = (A + ~B) + 1 = A - B 1170define i32 @add_to_sub(i32 %M, i32 %B) { 1171; CHECK-LABEL: @add_to_sub( 1172; CHECK-NEXT: [[A:%.*]] = mul i32 [[M:%.*]], 42 1173; CHECK-NEXT: [[E:%.*]] = sub i32 [[A]], [[B:%.*]] 1174; CHECK-NEXT: ret i32 [[E]] 1175; 1176 %A = mul i32 %M, 42 ; thwart complexity-based ordering 1177 %C = xor i32 %B, -1 1178 %D = add i32 %A, %C 1179 %E = add i32 %D, 1 1180 ret i32 %E 1181} 1182 1183; E = (~B + A) + 1 = A - B 1184define i32 @add_to_sub2(i32 %A, i32 %M) { 1185; CHECK-LABEL: @add_to_sub2( 1186; CHECK-NEXT: [[B_NEG:%.*]] = mul i32 [[M:%.*]], -42 1187; CHECK-NEXT: [[E:%.*]] = add i32 [[B_NEG]], [[A:%.*]] 1188; CHECK-NEXT: ret i32 [[E]] 1189; 1190 %B = mul i32 %M, 42 ; thwart complexity-based ordering 1191 %C = xor i32 %B, -1 1192 %D = add i32 %C, %A 1193 %E = add i32 %D, 1 1194 ret i32 %E 1195} 1196 1197; (X | C1) + C2 --> (X | C1) ^ C1 iff (C1 == -C2) 1198define i32 @test44(i32 %A) { 1199; CHECK-LABEL: @test44( 1200; CHECK-NEXT: [[C:%.*]] = and i32 [[A:%.*]], -124 1201; CHECK-NEXT: ret i32 [[C]] 1202; 1203 %B = or i32 %A, 123 1204 %C = add i32 %B, -123 1205 ret i32 %C 1206} 1207 1208define i32 @test44_extra_use(i32 %A) { 1209; CHECK-LABEL: @test44_extra_use( 1210; CHECK-NEXT: [[B:%.*]] = or i32 [[A:%.*]], 123 1211; CHECK-NEXT: [[C:%.*]] = and i32 [[A]], -124 1212; CHECK-NEXT: [[D:%.*]] = mul i32 [[B]], [[C]] 1213; CHECK-NEXT: ret i32 [[D]] 1214; 1215 %B = or i32 %A, 123 1216 %C = add i32 %B, -123 1217 %D = mul i32 %B, %C 1218 ret i32 %D 1219} 1220 1221define i32 @test44_non_matching(i32 %A) { 1222; CHECK-LABEL: @test44_non_matching( 1223; CHECK-NEXT: [[B:%.*]] = or i32 [[A:%.*]], 123 1224; CHECK-NEXT: [[C:%.*]] = add i32 [[B]], -321 1225; CHECK-NEXT: ret i32 [[C]] 1226; 1227 %B = or i32 %A, 123 1228 %C = add i32 %B, -321 1229 ret i32 %C 1230} 1231 1232define <2 x i32> @test44_vec(<2 x i32> %A) { 1233; CHECK-LABEL: @test44_vec( 1234; CHECK-NEXT: [[C:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 -124) 1235; CHECK-NEXT: ret <2 x i32> [[C]] 1236; 1237 %B = or <2 x i32> %A, <i32 123, i32 123> 1238 %C = add <2 x i32> %B, <i32 -123, i32 -123> 1239 ret <2 x i32> %C 1240} 1241 1242define <2 x i32> @test44_vec_non_matching(<2 x i32> %A) { 1243; CHECK-LABEL: @test44_vec_non_matching( 1244; CHECK-NEXT: [[B:%.*]] = or <2 x i32> [[A:%.*]], splat (i32 123) 1245; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[B]], splat (i32 -321) 1246; CHECK-NEXT: ret <2 x i32> [[C]] 1247; 1248 %B = or <2 x i32> %A, <i32 123, i32 123> 1249 %C = add <2 x i32> %B, <i32 -321, i32 -321> 1250 ret <2 x i32> %C 1251} 1252 1253define <2 x i32> @test44_vec_poison(<2 x i32> %A) { 1254; CHECK-LABEL: @test44_vec_poison( 1255; CHECK-NEXT: [[B:%.*]] = or <2 x i32> [[A:%.*]], <i32 123, i32 poison> 1256; CHECK-NEXT: [[C:%.*]] = add nsw <2 x i32> [[B]], <i32 -123, i32 poison> 1257; CHECK-NEXT: ret <2 x i32> [[C]] 1258; 1259 %B = or <2 x i32> %A, <i32 123, i32 poison> 1260 %C = add <2 x i32> %B, <i32 -123, i32 poison> 1261 ret <2 x i32> %C 1262} 1263 1264define <2 x i32> @test44_vec_non_splat(<2 x i32> %A) { 1265; CHECK-LABEL: @test44_vec_non_splat( 1266; CHECK-NEXT: [[B:%.*]] = or <2 x i32> [[A:%.*]], <i32 123, i32 456> 1267; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[B]], <i32 -123, i32 -456> 1268; CHECK-NEXT: ret <2 x i32> [[C]] 1269; 1270 %B = or <2 x i32> %A, <i32 123, i32 456> 1271 %C = add <2 x i32> %B, <i32 -123, i32 -456> 1272 ret <2 x i32> %C 1273} 1274 1275define i32 @lshr_add(i1 %x, i1 %y) { 1276; CHECK-LABEL: @lshr_add( 1277; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X:%.*]], true 1278; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[Y:%.*]], [[TMP1]] 1279; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP2]] to i32 1280; CHECK-NEXT: ret i32 [[R]] 1281; 1282 %xz = zext i1 %x to i32 1283 %ys = sext i1 %y to i32 1284 %sub = add i32 %xz, %ys 1285 %r = lshr i32 %sub, 31 1286 ret i32 %r 1287} 1288 1289define i5 @and_add(i1 %x, i1 %y) { 1290; CHECK-LABEL: @and_add( 1291; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X:%.*]], true 1292; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[Y:%.*]], [[TMP1]] 1293; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i5 -2, i5 0 1294; CHECK-NEXT: ret i5 [[R]] 1295; 1296 %xz = zext i1 %x to i5 1297 %ys = sext i1 %y to i5 1298 %sub = add i5 %xz, %ys 1299 %r = and i5 %sub, 30 1300 ret i5 %r 1301} 1302 1303define <2 x i8> @ashr_add_commute(<2 x i1> %x, <2 x i1> %y) { 1304; CHECK-LABEL: @ashr_add_commute( 1305; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i1> [[X:%.*]], splat (i1 true) 1306; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i1> [[Y:%.*]], [[TMP1]] 1307; CHECK-NEXT: [[TMP3:%.*]] = sext <2 x i1> [[TMP2]] to <2 x i8> 1308; CHECK-NEXT: ret <2 x i8> [[TMP3]] 1309; 1310 %xz = zext <2 x i1> %x to <2 x i8> 1311 %ys = sext <2 x i1> %y to <2 x i8> 1312 %sub = add nsw <2 x i8> %ys, %xz 1313 %r = ashr <2 x i8> %sub, <i8 1, i8 1> 1314 ret <2 x i8> %r 1315} 1316 1317define i32 @cmp_math(i32 %x, i32 %y) { 1318; CHECK-LABEL: @cmp_math( 1319; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 1320; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i32 1321; CHECK-NEXT: ret i32 [[R]] 1322; 1323 %gt = icmp ugt i32 %x, %y 1324 %lt = icmp ult i32 %x, %y 1325 %xz = zext i1 %gt to i32 1326 %yz = zext i1 %lt to i32 1327 %s = sub i32 %xz, %yz 1328 %r = lshr i32 %s, 31 1329 ret i32 %r 1330} 1331 1332; Negative test - wrong type 1333 1334define i32 @lshr_add_nonbool(i2 %x, i1 %y) { 1335; CHECK-LABEL: @lshr_add_nonbool( 1336; CHECK-NEXT: [[XZ:%.*]] = zext i2 [[X:%.*]] to i32 1337; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32 1338; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]] 1339; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31 1340; CHECK-NEXT: ret i32 [[R]] 1341; 1342 %xz = zext i2 %x to i32 1343 %ys = sext i1 %y to i32 1344 %sub = add i32 %xz, %ys 1345 %r = lshr i32 %sub, 31 1346 ret i32 %r 1347} 1348 1349; Negative test - wrong demand 1350 1351define i32 @and31_add(i1 %x, i1 %y) { 1352; CHECK-LABEL: @and31_add( 1353; CHECK-NEXT: [[XZ:%.*]] = zext i1 [[X:%.*]] to i32 1354; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32 1355; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]] 1356; CHECK-NEXT: [[R:%.*]] = and i32 [[SUB]], 31 1357; CHECK-NEXT: ret i32 [[R]] 1358; 1359 %xz = zext i1 %x to i32 1360 %ys = sext i1 %y to i32 1361 %sub = add i32 %xz, %ys 1362 %r = and i32 %sub, 31 1363 ret i32 %r 1364} 1365 1366; Negative test - extra use 1367 1368define i32 @lshr_add_use(i1 %x, i1 %y, ptr %p) { 1369; CHECK-LABEL: @lshr_add_use( 1370; CHECK-NEXT: [[XZ:%.*]] = zext i1 [[X:%.*]] to i32 1371; CHECK-NEXT: store i32 [[XZ]], ptr [[P:%.*]], align 4 1372; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32 1373; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]] 1374; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31 1375; CHECK-NEXT: ret i32 [[R]] 1376; 1377 %xz = zext i1 %x to i32 1378 store i32 %xz, ptr %p 1379 %ys = sext i1 %y to i32 1380 %sub = add i32 %xz, %ys 1381 %r = lshr i32 %sub, 31 1382 ret i32 %r 1383} 1384 1385; Negative test - extra use 1386 1387define i32 @lshr_add_use2(i1 %x, i1 %y, ptr %p) { 1388; CHECK-LABEL: @lshr_add_use2( 1389; CHECK-NEXT: [[XZ:%.*]] = zext i1 [[X:%.*]] to i32 1390; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32 1391; CHECK-NEXT: store i32 [[YS]], ptr [[P:%.*]], align 4 1392; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]] 1393; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31 1394; CHECK-NEXT: ret i32 [[R]] 1395; 1396 %xz = zext i1 %x to i32 1397 %ys = sext i1 %y to i32 1398 store i32 %ys, ptr %p 1399 %sub = add i32 %xz, %ys 1400 %r = lshr i32 %sub, 31 1401 ret i32 %r 1402} 1403 1404define i32 @lshr_add_sexts(i1 %x, i1 %y) { 1405; CHECK-LABEL: @lshr_add_sexts( 1406; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y:%.*]] 1407; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i32 1408; CHECK-NEXT: ret i32 [[R]] 1409; 1410 %xs = sext i1 %x to i32 1411 %ys = sext i1 %y to i32 1412 %sub = add i32 %xs, %ys 1413 %r = lshr i32 %sub, 31 1414 ret i32 %r 1415} 1416 1417define i5 @and_add_sexts(i1 %x, i1 %y) { 1418; CHECK-LABEL: @and_add_sexts( 1419; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y:%.*]] 1420; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i5 -2, i5 0 1421; CHECK-NEXT: ret i5 [[R]] 1422; 1423 %xs = sext i1 %x to i5 1424 %ys = sext i1 %y to i5 1425 %sub = add i5 %xs, %ys 1426 %r = and i5 %sub, 30 1427 ret i5 %r 1428} 1429 1430define <2 x i8> @ashr_add_sexts(<2 x i1> %x, <2 x i1> %y) { 1431; CHECK-LABEL: @ashr_add_sexts( 1432; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i1> [[Y:%.*]], [[X:%.*]] 1433; CHECK-NEXT: [[TMP2:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8> 1434; CHECK-NEXT: ret <2 x i8> [[TMP2]] 1435; 1436 %xs = sext <2 x i1> %x to <2 x i8> 1437 %ys = sext <2 x i1> %y to <2 x i8> 1438 %sub = add nsw <2 x i8> %ys, %xs 1439 %r = ashr <2 x i8> %sub, <i8 1, i8 1> 1440 ret <2 x i8> %r 1441} 1442 1443define i32 @cmp_math_sexts(i32 %x, i32 %y) { 1444; CHECK-LABEL: @cmp_math_sexts( 1445; CHECK-NEXT: [[DOTNOT:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]] 1446; CHECK-NEXT: [[R:%.*]] = zext i1 [[DOTNOT]] to i32 1447; CHECK-NEXT: ret i32 [[R]] 1448; 1449 %gt = icmp ugt i32 %x, %y 1450 %lt = icmp ult i32 %x, %y 1451 %xz = sext i1 %gt to i32 1452 %yz = zext i1 %lt to i32 1453 %s = sub i32 %xz, %yz 1454 %r = lshr i32 %s, 31 1455 ret i32 %r 1456} 1457 1458; Negative test - wrong type 1459 1460define i32 @lshr_add_nonbool_sexts(i2 %x, i1 %y) { 1461; CHECK-LABEL: @lshr_add_nonbool_sexts( 1462; CHECK-NEXT: [[XS:%.*]] = sext i2 [[X:%.*]] to i32 1463; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32 1464; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]] 1465; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31 1466; CHECK-NEXT: ret i32 [[R]] 1467; 1468 %xs = sext i2 %x to i32 1469 %ys = sext i1 %y to i32 1470 %sub = add i32 %xs, %ys 1471 %r = lshr i32 %sub, 31 1472 ret i32 %r 1473} 1474 1475; Negative test - wrong demand 1476 1477define i32 @and31_add_sexts(i1 %x, i1 %y) { 1478; CHECK-LABEL: @and31_add_sexts( 1479; CHECK-NEXT: [[XS:%.*]] = sext i1 [[X:%.*]] to i32 1480; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32 1481; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]] 1482; CHECK-NEXT: [[R:%.*]] = and i32 [[SUB]], 31 1483; CHECK-NEXT: ret i32 [[R]] 1484; 1485 %xs = sext i1 %x to i32 1486 %ys = sext i1 %y to i32 1487 %sub = add i32 %xs, %ys 1488 %r = and i32 %sub, 31 1489 ret i32 %r 1490} 1491 1492define i32 @lshr_add_use_sexts(i1 %x, i1 %y, ptr %p) { 1493; CHECK-LABEL: @lshr_add_use_sexts( 1494; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32 1495; CHECK-NEXT: store i32 [[YS]], ptr [[P:%.*]], align 4 1496; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y]] 1497; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i32 1498; CHECK-NEXT: ret i32 [[R]] 1499; 1500 %xs = sext i1 %x to i32 1501 %ys = sext i1 %y to i32 1502 store i32 %ys, ptr %p 1503 %sub = add i32 %xs, %ys 1504 %r = lshr i32 %sub, 31 1505 ret i32 %r 1506} 1507 1508define i32 @lshr_add_use_sexts_2(i1 %x, i1 %y, ptr %p) { 1509; CHECK-LABEL: @lshr_add_use_sexts_2( 1510; CHECK-NEXT: [[XS:%.*]] = sext i1 [[X:%.*]] to i32 1511; CHECK-NEXT: store i32 [[XS]], ptr [[P:%.*]], align 4 1512; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X]], [[Y:%.*]] 1513; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i32 1514; CHECK-NEXT: ret i32 [[R]] 1515; 1516 %xs = sext i1 %x to i32 1517 store i32 %xs, ptr %p 1518 %ys = sext i1 %y to i32 1519 %sub = add i32 %xs, %ys 1520 %r = lshr i32 %sub, 31 1521 ret i32 %r 1522} 1523 1524; Negative test - extra use 1525 1526declare void @use_sexts(i32, i32) 1527 1528define i32 @lshr_add_use_sexts_both(i1 %x, i1 %y) { 1529; CHECK-LABEL: @lshr_add_use_sexts_both( 1530; CHECK-NEXT: [[XS:%.*]] = sext i1 [[X:%.*]] to i32 1531; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32 1532; CHECK-NEXT: call void @use_sexts(i32 [[XS]], i32 [[YS]]) 1533; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]] 1534; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31 1535; CHECK-NEXT: ret i32 [[R]] 1536; 1537 %xs = sext i1 %x to i32 1538 %ys = sext i1 %y to i32 1539 call void @use_sexts(i32 %xs, i32 %ys) 1540 %sub = add i32 %xs, %ys 1541 %r = lshr i32 %sub, 31 1542 ret i32 %r 1543} 1544 1545define i8 @add_like_or_t0(i8 %x) { 1546; CHECK-LABEL: @add_like_or_t0( 1547; CHECK-NEXT: [[I0:%.*]] = shl i8 [[X:%.*]], 4 1548; CHECK-NEXT: [[R:%.*]] = add i8 [[I0]], 57 1549; CHECK-NEXT: ret i8 [[R]] 1550; 1551 %i0 = shl i8 %x, 4 1552 %i1 = or i8 %i0, 15 ; no common bits 1553 %r = add i8 %i1, 42 1554 ret i8 %r 1555} 1556define i8 @add_like_or_n1(i8 %x) { 1557; CHECK-LABEL: @add_like_or_n1( 1558; CHECK-NEXT: [[I0:%.*]] = shl i8 [[X:%.*]], 4 1559; CHECK-NEXT: [[I1:%.*]] = or i8 [[I0]], 31 1560; CHECK-NEXT: [[R:%.*]] = add i8 [[I1]], 42 1561; CHECK-NEXT: ret i8 [[R]] 1562; 1563 %i0 = shl i8 %x, 4 1564 %i1 = or i8 %i0, 31 ; 4'th bit might be common-set 1565 %r = add i8 %i1, 42 1566 ret i8 %r 1567} 1568define i8 @add_like_or_t2_extrause(i8 %x) { 1569; CHECK-LABEL: @add_like_or_t2_extrause( 1570; CHECK-NEXT: [[I0:%.*]] = shl i8 [[X:%.*]], 4 1571; CHECK-NEXT: [[I1:%.*]] = or disjoint i8 [[I0]], 15 1572; CHECK-NEXT: call void @use(i8 [[I1]]) 1573; CHECK-NEXT: [[R:%.*]] = add i8 [[I0]], 57 1574; CHECK-NEXT: ret i8 [[R]] 1575; 1576 %i0 = shl i8 %x, 4 1577 %i1 = or i8 %i0, 15 ; no common bits 1578 call void @use(i8 %i1) ; extra use 1579 %r = add i8 %i1, 42 1580 ret i8 %r 1581} 1582define i8 @fold_add_constant_preserve_nsw(i8 %x) { 1583; CHECK-LABEL: @fold_add_constant_preserve_nsw( 1584; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[X:%.*]], -120 1585; CHECK-NEXT: ret i8 [[ADD]] 1586; 1587 %or = or disjoint i8 %x, -128 1588 %add = add nsw i8 %or, 8 1589 ret i8 %add 1590} 1591define i8 @fold_add_constant_no_nsw(i8 %x) { 1592; CHECK-LABEL: @fold_add_constant_no_nsw( 1593; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X:%.*]], 120 1594; CHECK-NEXT: ret i8 [[ADD]] 1595; 1596 %or = or disjoint i8 %x, -128 1597 %add = add nsw i8 %or, -8 1598 ret i8 %add 1599} 1600define i8 @fold_add_constant_preserve_nuw(i8 %x) { 1601; CHECK-LABEL: @fold_add_constant_preserve_nuw( 1602; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[X:%.*]], -116 1603; CHECK-NEXT: ret i8 [[ADD]] 1604; 1605 %or = or disjoint i8 %x, 128 1606 %add = add nuw i8 %or, 12 1607 ret i8 %add 1608} 1609define i32 @sdiv_to_udiv(i32 %arg0, i32 %arg1) { 1610; CHECK-LABEL: @sdiv_to_udiv( 1611; CHECK-NEXT: [[T0:%.*]] = shl nuw nsw i32 [[ARG0:%.*]], 8 1612; CHECK-NEXT: [[T2:%.*]] = add nuw nsw i32 [[T0]], 6242049 1613; CHECK-NEXT: [[T3:%.*]] = udiv i32 [[T2]], 192 1614; CHECK-NEXT: ret i32 [[T3]] 1615; 1616 %t0 = shl nuw nsw i32 %arg0, 8 1617 %t1 = or disjoint i32 %t0, 1 1618 %t2 = add nuw nsw i32 %t1, 6242048 1619 %t3 = sdiv i32 %t2, 192 1620 ret i32 %t3 1621} 1622 1623define i8 @add_like_or_disjoint(i8 %x) { 1624; CHECK-LABEL: @add_like_or_disjoint( 1625; CHECK-NEXT: [[R:%.*]] = add i8 [[X:%.*]], 57 1626; CHECK-NEXT: ret i8 [[R]] 1627; 1628 %i1 = or disjoint i8 %x, 15 1629 %r = add i8 %i1, 42 1630 ret i8 %r 1631} 1632 1633define i8 @add_and_xor(i8 noundef %x, i8 %y) { 1634; CHECK-LABEL: @add_and_xor( 1635; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y:%.*]], [[X:%.*]] 1636; CHECK-NEXT: ret i8 [[ADD]] 1637; 1638 %xor = xor i8 %x, -1 1639 %and = and i8 %xor, %y 1640 %add = add i8 %and, %x 1641 ret i8 %add 1642} 1643 1644define i8 @add_and_xor_wrong_const(i8 %x, i8 %y) { 1645; CHECK-LABEL: @add_and_xor_wrong_const( 1646; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -2 1647; CHECK-NEXT: [[AND:%.*]] = and i8 [[XOR]], [[Y:%.*]] 1648; CHECK-NEXT: [[ADD:%.*]] = add i8 [[AND]], [[X]] 1649; CHECK-NEXT: ret i8 [[ADD]] 1650; 1651 %xor = xor i8 %x, -2 1652 %and = and i8 %xor, %y 1653 %add = add i8 %and, %x 1654 ret i8 %add 1655} 1656 1657define i8 @add_and_xor_wrong_op(i8 %x, i8 %y, i8 %z) { 1658; CHECK-LABEL: @add_and_xor_wrong_op( 1659; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[Z:%.*]], -1 1660; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y:%.*]], [[XOR]] 1661; CHECK-NEXT: [[ADD:%.*]] = add i8 [[AND]], [[X:%.*]] 1662; CHECK-NEXT: ret i8 [[ADD]] 1663; 1664 %xor = xor i8 %z, -1 1665 %and = and i8 %xor, %y 1666 %add = add i8 %and, %x 1667 ret i8 %add 1668} 1669 1670define i8 @add_and_xor_commuted1(i8 noundef %x, i8 %_y) { 1671; CHECK-LABEL: @add_and_xor_commuted1( 1672; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]] 1673; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X:%.*]] 1674; CHECK-NEXT: ret i8 [[ADD]] 1675; 1676 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization 1677 %xor = xor i8 %x, -1 1678 %and = and i8 %y, %xor 1679 %add = add i8 %and, %x 1680 ret i8 %add 1681} 1682 1683define i8 @add_and_xor_commuted2(i8 noundef %_x, i8 %y) { 1684; CHECK-LABEL: @add_and_xor_commuted2( 1685; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]] 1686; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y:%.*]] 1687; CHECK-NEXT: ret i8 [[ADD]] 1688; 1689 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization 1690 %xor = xor i8 %x, -1 1691 %and = and i8 %xor, %y 1692 %add = add i8 %x, %and 1693 ret i8 %add 1694} 1695 1696define i8 @add_and_xor_commuted3(i8 noundef %_x, i8 %_y) { 1697; CHECK-LABEL: @add_and_xor_commuted3( 1698; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]] 1699; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]] 1700; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y]] 1701; CHECK-NEXT: ret i8 [[ADD]] 1702; 1703 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization 1704 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization 1705 %xor = xor i8 %x, -1 1706 %and = and i8 %y, %xor 1707 %add = add i8 %x, %and 1708 ret i8 %add 1709} 1710 1711define i8 @add_and_xor_extra_use(i8 noundef %x, i8 %y) { 1712; CHECK-LABEL: @add_and_xor_extra_use( 1713; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -1 1714; CHECK-NEXT: call void @use(i8 [[XOR]]) 1715; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y:%.*]], [[XOR]] 1716; CHECK-NEXT: call void @use(i8 [[AND]]) 1717; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]] 1718; CHECK-NEXT: ret i8 [[ADD]] 1719; 1720 %xor = xor i8 %x, -1 1721 call void @use(i8 %xor) 1722 %and = and i8 %xor, %y 1723 call void @use(i8 %and) 1724 %add = add i8 %and, %x 1725 ret i8 %add 1726} 1727 1728define i8 @add_xor_and_const(i8 noundef %x) { 1729; CHECK-LABEL: @add_xor_and_const( 1730; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X:%.*]], 42 1731; CHECK-NEXT: ret i8 [[ADD]] 1732; 1733 %and = and i8 %x, 42 1734 %xor = xor i8 %and, 42 1735 %add = add i8 %xor, %x 1736 ret i8 %add 1737} 1738 1739define i8 @add_xor_and_const_wrong_const(i8 %x) { 1740; CHECK-LABEL: @add_xor_and_const_wrong_const( 1741; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 42 1742; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[AND]], 88 1743; CHECK-NEXT: [[ADD:%.*]] = add i8 [[XOR]], [[X]] 1744; CHECK-NEXT: ret i8 [[ADD]] 1745; 1746 %and = and i8 %x, 42 1747 %xor = xor i8 %and, 88 1748 %add = add i8 %xor, %x 1749 ret i8 %add 1750} 1751 1752define i8 @add_xor_and_var(i8 noundef %x, i8 noundef %y) { 1753; CHECK-LABEL: @add_xor_and_var( 1754; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]] 1755; CHECK-NEXT: call void @use(i8 [[AND]]) 1756; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]] 1757; CHECK-NEXT: ret i8 [[ADD]] 1758; 1759 %and = and i8 %x, %y 1760 call void @use(i8 %and) 1761 %xor = xor i8 %and, %y 1762 %add = add i8 %xor, %x 1763 ret i8 %add 1764} 1765 1766define i8 @add_xor_and_var_wrong_op1(i8 %x, i8 %y, i8 %z) { 1767; CHECK-LABEL: @add_xor_and_var_wrong_op1( 1768; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]] 1769; CHECK-NEXT: call void @use(i8 [[AND]]) 1770; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[AND]], [[Z:%.*]] 1771; CHECK-NEXT: [[ADD:%.*]] = add i8 [[XOR]], [[X]] 1772; CHECK-NEXT: ret i8 [[ADD]] 1773; 1774 %and = and i8 %x, %y 1775 call void @use(i8 %and) 1776 %xor = xor i8 %and, %z 1777 %add = add i8 %xor, %x 1778 ret i8 %add 1779} 1780 1781define i8 @add_xor_and_var_wrong_op2(i8 %x, i8 %y, i8 %z) { 1782; CHECK-LABEL: @add_xor_and_var_wrong_op2( 1783; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]] 1784; CHECK-NEXT: call void @use(i8 [[AND]]) 1785; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[AND]], [[Y]] 1786; CHECK-NEXT: [[ADD:%.*]] = add i8 [[XOR]], [[Z:%.*]] 1787; CHECK-NEXT: ret i8 [[ADD]] 1788; 1789 %and = and i8 %x, %y 1790 call void @use(i8 %and) 1791 %xor = xor i8 %and, %y 1792 %add = add i8 %xor, %z 1793 ret i8 %add 1794} 1795 1796define i8 @add_xor_and_var_commuted1(i8 noundef %x, i8 noundef %y) { 1797; CHECK-LABEL: @add_xor_and_var_commuted1( 1798; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y:%.*]], [[X:%.*]] 1799; CHECK-NEXT: call void @use(i8 [[AND]]) 1800; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]] 1801; CHECK-NEXT: ret i8 [[ADD]] 1802; 1803 %and = and i8 %y, %x 1804 call void @use(i8 %and) 1805 %xor = xor i8 %and, %y 1806 %add = add i8 %xor, %x 1807 ret i8 %add 1808} 1809 1810define i8 @add_xor_and_var_commuted2(i8 noundef %_x, i8 noundef %_y) { 1811; CHECK-LABEL: @add_xor_and_var_commuted2( 1812; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]] 1813; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]] 1814; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[Y]] 1815; CHECK-NEXT: call void @use(i8 [[AND]]) 1816; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]] 1817; CHECK-NEXT: ret i8 [[ADD]] 1818; 1819 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization 1820 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization 1821 %and = and i8 %x, %y 1822 call void @use(i8 %and) 1823 %xor = xor i8 %y, %and 1824 %add = add i8 %xor, %x 1825 ret i8 %add 1826} 1827 1828define i8 @add_xor_and_var_commuted3(i8 noundef %x, i8 noundef %_y) { 1829; CHECK-LABEL: @add_xor_and_var_commuted3( 1830; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]] 1831; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y]], [[X:%.*]] 1832; CHECK-NEXT: call void @use(i8 [[AND]]) 1833; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]] 1834; CHECK-NEXT: ret i8 [[ADD]] 1835; 1836 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization 1837 %and = and i8 %y, %x 1838 call void @use(i8 %and) 1839 %xor = xor i8 %y, %and 1840 %add = add i8 %xor, %x 1841 ret i8 %add 1842} 1843 1844define i8 @add_xor_and_var_commuted4(i8 noundef %_x, i8 noundef %y) { 1845; CHECK-LABEL: @add_xor_and_var_commuted4( 1846; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]] 1847; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[Y:%.*]] 1848; CHECK-NEXT: call void @use(i8 [[AND]]) 1849; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y]] 1850; CHECK-NEXT: ret i8 [[ADD]] 1851; 1852 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization 1853 %and = and i8 %x, %y 1854 call void @use(i8 %and) 1855 %xor = xor i8 %and, %y 1856 %add = add i8 %x, %xor 1857 ret i8 %add 1858} 1859 1860define i8 @add_xor_and_var_commuted5(i8 noundef %_x, i8 noundef %_y) { 1861; CHECK-LABEL: @add_xor_and_var_commuted5( 1862; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]] 1863; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]] 1864; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y]], [[X]] 1865; CHECK-NEXT: call void @use(i8 [[AND]]) 1866; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y]] 1867; CHECK-NEXT: ret i8 [[ADD]] 1868; 1869 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization 1870 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization 1871 %and = and i8 %y, %x 1872 call void @use(i8 %and) 1873 %xor = xor i8 %and, %y 1874 %add = add i8 %x, %xor 1875 ret i8 %add 1876} 1877 1878define i8 @add_xor_and_var_commuted6(i8 noundef %_x, i8 noundef %_y) { 1879; CHECK-LABEL: @add_xor_and_var_commuted6( 1880; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]] 1881; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]] 1882; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[Y]] 1883; CHECK-NEXT: call void @use(i8 [[AND]]) 1884; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y]] 1885; CHECK-NEXT: ret i8 [[ADD]] 1886; 1887 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization 1888 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization 1889 %and = and i8 %x, %y 1890 call void @use(i8 %and) 1891 %xor = xor i8 %y, %and 1892 %add = add i8 %x, %xor 1893 ret i8 %add 1894} 1895 1896define i8 @add_xor_and_var_commuted7(i8 noundef %_x, i8 noundef %_y) { 1897; CHECK-LABEL: @add_xor_and_var_commuted7( 1898; CHECK-NEXT: [[X:%.*]] = udiv i8 42, [[_X:%.*]] 1899; CHECK-NEXT: [[Y:%.*]] = udiv i8 42, [[_Y:%.*]] 1900; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y]], [[X]] 1901; CHECK-NEXT: call void @use(i8 [[AND]]) 1902; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], [[Y]] 1903; CHECK-NEXT: ret i8 [[ADD]] 1904; 1905 %x = udiv i8 42, %_x ; thwart complexity-based canonicalization 1906 %y = udiv i8 42, %_y ; thwart complexity-based canonicalization 1907 %and = and i8 %y, %x 1908 call void @use(i8 %and) 1909 %xor = xor i8 %y, %and 1910 %add = add i8 %x, %xor 1911 ret i8 %add 1912} 1913 1914define i8 @add_xor_and_var_extra_use(i8 noundef %x, i8 noundef %y) { 1915; CHECK-LABEL: @add_xor_and_var_extra_use( 1916; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]] 1917; CHECK-NEXT: call void @use(i8 [[AND]]) 1918; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[AND]], [[Y]] 1919; CHECK-NEXT: call void @use(i8 [[XOR]]) 1920; CHECK-NEXT: [[ADD:%.*]] = or i8 [[Y]], [[X]] 1921; CHECK-NEXT: ret i8 [[ADD]] 1922; 1923 %and = and i8 %x, %y 1924 call void @use(i8 %and) 1925 %xor = xor i8 %and, %y 1926 call void @use(i8 %xor) 1927 %add = add i8 %xor, %x 1928 ret i8 %add 1929} 1930 1931define i32 @add_add_add(i32 %A, i32 %B, i32 %C, i32 %D) { 1932; CHECK-LABEL: @add_add_add( 1933; CHECK-NEXT: [[E:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 1934; CHECK-NEXT: [[F:%.*]] = add i32 [[E]], [[C:%.*]] 1935; CHECK-NEXT: [[G:%.*]] = add i32 [[F]], [[D:%.*]] 1936; CHECK-NEXT: ret i32 [[G]] 1937; 1938 %E = add i32 %A, %B 1939 %F = add i32 %E, %C 1940 %G = add i32 %F, %D 1941 ret i32 %G 1942} 1943 1944define i32 @add_add_add_commute1(i32 %A, i32 %B, i32 %C, i32 %D) { 1945; CHECK-LABEL: @add_add_add_commute1( 1946; CHECK-NEXT: [[E:%.*]] = add i32 [[B:%.*]], [[A:%.*]] 1947; CHECK-NEXT: [[F:%.*]] = add i32 [[E]], [[C:%.*]] 1948; CHECK-NEXT: [[G:%.*]] = add i32 [[F]], [[D:%.*]] 1949; CHECK-NEXT: ret i32 [[G]] 1950; 1951 %E = add i32 %B, %A 1952 %F = add i32 %E, %C 1953 %G = add i32 %F, %D 1954 ret i32 %G 1955} 1956 1957define i32 @add_add_add_commute2(i32 %A, i32 %B, i32 %C, i32 %D) { 1958; CHECK-LABEL: @add_add_add_commute2( 1959; CHECK-NEXT: [[E:%.*]] = add i32 [[B:%.*]], [[A:%.*]] 1960; CHECK-NEXT: [[F:%.*]] = add i32 [[C:%.*]], [[E]] 1961; CHECK-NEXT: [[G:%.*]] = add i32 [[F]], [[D:%.*]] 1962; CHECK-NEXT: ret i32 [[G]] 1963; 1964 %E = add i32 %B, %A 1965 %F = add i32 %C, %E 1966 %G = add i32 %F, %D 1967 ret i32 %G 1968} 1969 1970define i32 @add_add_add_commute3(i32 %A, i32 %B, i32 %C, i32 %D) { 1971; CHECK-LABEL: @add_add_add_commute3( 1972; CHECK-NEXT: [[E:%.*]] = add i32 [[B:%.*]], [[A:%.*]] 1973; CHECK-NEXT: [[F:%.*]] = add i32 [[C:%.*]], [[E]] 1974; CHECK-NEXT: [[G:%.*]] = add i32 [[D:%.*]], [[F]] 1975; CHECK-NEXT: ret i32 [[G]] 1976; 1977 %E = add i32 %B, %A 1978 %F = add i32 %C, %E 1979 %G = add i32 %D, %F 1980 ret i32 %G 1981} 1982 1983; x * y + x --> (y + 1) * x 1984 1985define i8 @mul_add_common_factor_commute1(i8 %x, i8 %y) { 1986; CHECK-LABEL: @mul_add_common_factor_commute1( 1987; CHECK-NEXT: [[X1:%.*]] = add i8 [[Y:%.*]], 1 1988; CHECK-NEXT: [[A:%.*]] = mul i8 [[X:%.*]], [[X1]] 1989; CHECK-NEXT: ret i8 [[A]] 1990; 1991 %m = mul nsw i8 %x, %y 1992 %a = add nsw i8 %m, %x 1993 ret i8 %a 1994} 1995 1996define <2 x i8> @mul_add_common_factor_commute2(<2 x i8> %x, <2 x i8> %y) { 1997; CHECK-LABEL: @mul_add_common_factor_commute2( 1998; CHECK-NEXT: [[M1:%.*]] = add <2 x i8> [[Y:%.*]], splat (i8 1) 1999; CHECK-NEXT: [[A:%.*]] = mul nuw <2 x i8> [[M1]], [[X:%.*]] 2000; CHECK-NEXT: ret <2 x i8> [[A]] 2001; 2002 %m = mul nuw <2 x i8> %y, %x 2003 %a = add nuw <2 x i8> %m, %x 2004 ret <2 x i8> %a 2005} 2006 2007define i8 @mul_add_common_factor_commute3(i8 %p, i8 %y) { 2008; CHECK-LABEL: @mul_add_common_factor_commute3( 2009; CHECK-NEXT: [[X:%.*]] = mul i8 [[P:%.*]], [[P]] 2010; CHECK-NEXT: [[M1:%.*]] = add i8 [[Y:%.*]], 1 2011; CHECK-NEXT: [[A:%.*]] = mul i8 [[X]], [[M1]] 2012; CHECK-NEXT: ret i8 [[A]] 2013; 2014 %x = mul i8 %p, %p ; thwart complexity-based canonicalization 2015 %m = mul nuw i8 %x, %y 2016 %a = add nsw i8 %x, %m 2017 ret i8 %a 2018} 2019 2020define i8 @mul_add_common_factor_commute4(i8 %p, i8 %q) { 2021; CHECK-LABEL: @mul_add_common_factor_commute4( 2022; CHECK-NEXT: [[X:%.*]] = mul i8 [[P:%.*]], [[P]] 2023; CHECK-NEXT: [[Y:%.*]] = mul i8 [[Q:%.*]], [[Q]] 2024; CHECK-NEXT: [[M1:%.*]] = add i8 [[Y]], 1 2025; CHECK-NEXT: [[A:%.*]] = mul i8 [[X]], [[M1]] 2026; CHECK-NEXT: ret i8 [[A]] 2027; 2028 %x = mul i8 %p, %p ; thwart complexity-based canonicalization 2029 %y = mul i8 %q, %q ; thwart complexity-based canonicalization 2030 %m = mul nsw i8 %y, %x 2031 %a = add nuw i8 %x, %m 2032 ret i8 %a 2033} 2034 2035; negative test - uses 2036 2037define i8 @mul_add_common_factor_use(i8 %x, i8 %y) { 2038; CHECK-LABEL: @mul_add_common_factor_use( 2039; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], [[Y:%.*]] 2040; CHECK-NEXT: call void @use(i8 [[M]]) 2041; CHECK-NEXT: [[A:%.*]] = add i8 [[M]], [[X]] 2042; CHECK-NEXT: ret i8 [[A]] 2043; 2044 %m = mul i8 %x, %y 2045 call void @use(i8 %m) 2046 %a = add i8 %m, %x 2047 ret i8 %a 2048} 2049 2050define i8 @not_mul(i8 %x) { 2051; CHECK-LABEL: @not_mul( 2052; CHECK-NEXT: [[TMP1:%.*]] = mul i8 [[X:%.*]], -41 2053; CHECK-NEXT: [[PLUSX:%.*]] = add i8 [[TMP1]], -1 2054; CHECK-NEXT: ret i8 [[PLUSX]] 2055; 2056 %mul = mul nsw i8 %x, 42 2057 %not = xor i8 %mul, -1 2058 %plusx = add nsw i8 %not, %x 2059 ret i8 %plusx 2060} 2061 2062define <2 x i8> @not_mul_commute(<2 x i8> %p) { 2063; CHECK-LABEL: @not_mul_commute( 2064; CHECK-NEXT: [[X:%.*]] = mul <2 x i8> [[P:%.*]], [[P]] 2065; CHECK-NEXT: [[TMP1:%.*]] = mul <2 x i8> [[X]], splat (i8 43) 2066; CHECK-NEXT: [[PLUSX:%.*]] = add <2 x i8> [[TMP1]], splat (i8 -1) 2067; CHECK-NEXT: ret <2 x i8> [[PLUSX]] 2068; 2069 %x = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization 2070 %mul = mul nuw <2 x i8> %x, <i8 -42, i8 -42> 2071 %not = xor <2 x i8> %mul, <i8 -1, i8 -1> 2072 %plusx = add nuw <2 x i8> %x, %not 2073 ret <2 x i8> %plusx 2074} 2075 2076; negative test - need common operand 2077 2078define i8 @not_mul_wrong_op(i8 %x, i8 %y) { 2079; CHECK-LABEL: @not_mul_wrong_op( 2080; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X:%.*]], 42 2081; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[MUL]], -1 2082; CHECK-NEXT: [[PLUSX:%.*]] = add i8 [[Y:%.*]], [[NOT]] 2083; CHECK-NEXT: ret i8 [[PLUSX]] 2084; 2085 %mul = mul i8 %x, 42 2086 %not = xor i8 %mul, -1 2087 %plusx = add i8 %not, %y 2088 ret i8 %plusx 2089} 2090 2091; negative test - avoid creating an extra mul 2092 2093define i8 @not_mul_use1(i8 %x) { 2094; CHECK-LABEL: @not_mul_use1( 2095; CHECK-NEXT: [[MUL:%.*]] = mul nsw i8 [[X:%.*]], 42 2096; CHECK-NEXT: call void @use(i8 [[MUL]]) 2097; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[MUL]], -1 2098; CHECK-NEXT: [[PLUSX:%.*]] = add nsw i8 [[X]], [[NOT]] 2099; CHECK-NEXT: ret i8 [[PLUSX]] 2100; 2101 %mul = mul nsw i8 %x, 42 2102 call void @use(i8 %mul) 2103 %not = xor i8 %mul, -1 2104 %plusx = add nsw i8 %not, %x 2105 ret i8 %plusx 2106} 2107 2108; negative test - too many instructions 2109 2110define i8 @not_mul_use2(i8 %x) { 2111; CHECK-LABEL: @not_mul_use2( 2112; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X:%.*]], 42 2113; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[MUL]], -1 2114; CHECK-NEXT: call void @use(i8 [[NOT]]) 2115; CHECK-NEXT: [[PLUSX:%.*]] = add i8 [[X]], [[NOT]] 2116; CHECK-NEXT: ret i8 [[PLUSX]] 2117; 2118 %mul = mul i8 %x, 42 2119 %not = xor i8 %mul, -1 2120 call void @use(i8 %not) 2121 %plusx = add i8 %not, %x 2122 ret i8 %plusx 2123} 2124 2125define i8 @full_ashr_inc(i8 %x) { 2126; CHECK-LABEL: @full_ashr_inc( 2127; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt i8 [[X:%.*]], -1 2128; CHECK-NEXT: [[R:%.*]] = zext i1 [[ISNOTNEG]] to i8 2129; CHECK-NEXT: ret i8 [[R]] 2130; 2131 %a = ashr i8 %x, 7 2132 %r = add i8 %a, 1 2133 ret i8 %r 2134} 2135 2136define <2 x i6> @full_ashr_inc_vec(<2 x i6> %x) { 2137; CHECK-LABEL: @full_ashr_inc_vec( 2138; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt <2 x i6> [[X:%.*]], splat (i6 -1) 2139; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[ISNOTNEG]] to <2 x i6> 2140; CHECK-NEXT: ret <2 x i6> [[R]] 2141; 2142 %a = ashr <2 x i6> %x, <i6 5, i6 poison> 2143 %r = add <2 x i6> %a, <i6 1, i6 1> 2144 ret <2 x i6> %r 2145} 2146 2147; negative test - extra use 2148 2149define i8 @full_ashr_inc_use(i8 %x) { 2150; CHECK-LABEL: @full_ashr_inc_use( 2151; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 7 2152; CHECK-NEXT: call void @use(i8 [[A]]) 2153; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[A]], 1 2154; CHECK-NEXT: ret i8 [[R]] 2155; 2156 %a = ashr i8 %x, 7 2157 call void @use(i8 %a) 2158 %r = add i8 %a, 1 2159 ret i8 %r 2160} 2161 2162; negative test - wrong shift amount 2163 2164define i8 @not_full_ashr_inc(i8 %x) { 2165; CHECK-LABEL: @not_full_ashr_inc( 2166; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 6 2167; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[A]], 1 2168; CHECK-NEXT: ret i8 [[R]] 2169; 2170 %a = ashr i8 %x, 6 2171 %r = add i8 %a, 1 2172 ret i8 %r 2173} 2174 2175; negative test - wrong add amount 2176 2177define i8 @full_ashr_not_inc(i8 %x) { 2178; CHECK-LABEL: @full_ashr_not_inc( 2179; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 7 2180; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[A]], 2 2181; CHECK-NEXT: ret i8 [[R]] 2182; 2183 %a = ashr i8 %x, 7 2184 %r = add i8 %a, 2 2185 ret i8 %r 2186} 2187 2188define i8 @select_negate_or_zero(i1 %b, i8 %x, i8 %y) { 2189; CHECK-LABEL: @select_negate_or_zero( 2190; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i8 0, i8 [[X:%.*]] 2191; CHECK-NEXT: [[ADD1:%.*]] = sub i8 [[Y:%.*]], [[TMP1]] 2192; CHECK-NEXT: ret i8 [[ADD1]] 2193; 2194 %negx = sub i8 0, %x 2195 %sel = select i1 %b, i8 0, i8 %negx 2196 %add = add i8 %sel, %y 2197 ret i8 %add 2198} 2199 2200; commuted add operands - same result 2201 2202define <2 x i8> @select_negate_or_zero_commute(<2 x i1> %b, <2 x i8> %x, <2 x i8> %p) { 2203; CHECK-LABEL: @select_negate_or_zero_commute( 2204; CHECK-NEXT: [[Y:%.*]] = mul <2 x i8> [[P:%.*]], [[P]] 2205; CHECK-NEXT: [[TMP1:%.*]] = select <2 x i1> [[B:%.*]], <2 x i8> zeroinitializer, <2 x i8> [[X:%.*]] 2206; CHECK-NEXT: [[ADD1:%.*]] = sub <2 x i8> [[Y]], [[TMP1]] 2207; CHECK-NEXT: ret <2 x i8> [[ADD1]] 2208; 2209 %y = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization 2210 %negx = sub <2 x i8> <i8 poison, i8 0>, %x 2211 %sel = select <2 x i1> %b, <2 x i8> <i8 poison, i8 0>, <2 x i8> %negx 2212 %add = add <2 x i8> %y, %sel 2213 ret <2 x i8> %add 2214} 2215 2216; swapped select operands and extra use are ok 2217 2218define i8 @select_negate_or_zero_swap(i1 %b, i8 %x, i8 %y) { 2219; CHECK-LABEL: @select_negate_or_zero_swap( 2220; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X:%.*]] 2221; CHECK-NEXT: call void @use(i8 [[NEGX]]) 2222; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i8 [[X]], i8 0 2223; CHECK-NEXT: [[ADD1:%.*]] = sub i8 [[Y:%.*]], [[TMP1]] 2224; CHECK-NEXT: ret i8 [[ADD1]] 2225; 2226 %negx = sub i8 0, %x 2227 call void @use(i8 %negx) 2228 %sel = select i1 %b, i8 %negx, i8 0 2229 %add = add i8 %sel, %y 2230 ret i8 %add 2231} 2232 2233; commuted add operands - same result 2234 2235define i8 @select_negate_or_zero_swap_commute(i1 %b, i8 %x, i8 %p) { 2236; CHECK-LABEL: @select_negate_or_zero_swap_commute( 2237; CHECK-NEXT: [[Y:%.*]] = mul i8 [[P:%.*]], [[P]] 2238; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i8 [[X:%.*]], i8 0 2239; CHECK-NEXT: [[ADD1:%.*]] = sub i8 [[Y]], [[TMP1]] 2240; CHECK-NEXT: ret i8 [[ADD1]] 2241; 2242 %y = mul i8 %p, %p ; thwart complexity-based canonicalization 2243 %negx = sub i8 0, %x 2244 %sel = select i1 %b, i8 %negx, i8 0 2245 %add = add i8 %y, %sel 2246 ret i8 %add 2247} 2248 2249; negative test - one arm of the select must simplify 2250 2251define i8 @select_negate_or_nonzero(i1 %b, i8 %x, i8 %y) { 2252; CHECK-LABEL: @select_negate_or_nonzero( 2253; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X:%.*]] 2254; CHECK-NEXT: [[SEL:%.*]] = select i1 [[B:%.*]], i8 42, i8 [[NEGX]] 2255; CHECK-NEXT: [[ADD:%.*]] = add i8 [[SEL]], [[Y:%.*]] 2256; CHECK-NEXT: ret i8 [[ADD]] 2257; 2258 %negx = sub i8 0, %x 2259 %sel = select i1 %b, i8 42, i8 %negx 2260 %add = add i8 %sel, %y 2261 ret i8 %add 2262} 2263 2264; negative test - must have a negate, not any subtract 2265 2266define i8 @select_nonnegate_or_zero(i1 %b, i8 %x, i8 %y) { 2267; CHECK-LABEL: @select_nonnegate_or_zero( 2268; CHECK-NEXT: [[NEGX:%.*]] = sub i8 42, [[X:%.*]] 2269; CHECK-NEXT: [[SEL:%.*]] = select i1 [[B:%.*]], i8 0, i8 [[NEGX]] 2270; CHECK-NEXT: [[ADD:%.*]] = add i8 [[SEL]], [[Y:%.*]] 2271; CHECK-NEXT: ret i8 [[ADD]] 2272; 2273 %negx = sub i8 42, %x 2274 %sel = select i1 %b, i8 0, i8 %negx 2275 %add = add i8 %sel, %y 2276 ret i8 %add 2277} 2278 2279; negative test - don't create an extra instruction 2280 2281define i8 @select_negate_or_nonzero_use(i1 %b, i8 %x, i8 %y) { 2282; CHECK-LABEL: @select_negate_or_nonzero_use( 2283; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X:%.*]] 2284; CHECK-NEXT: [[SEL:%.*]] = select i1 [[B:%.*]], i8 0, i8 [[NEGX]] 2285; CHECK-NEXT: call void @use(i8 [[SEL]]) 2286; CHECK-NEXT: [[ADD:%.*]] = add i8 [[SEL]], [[Y:%.*]] 2287; CHECK-NEXT: ret i8 [[ADD]] 2288; 2289 %negx = sub i8 0, %x 2290 %sel = select i1 %b, i8 0, i8 %negx 2291 call void @use(i8 %sel) 2292 %add = add i8 %sel, %y 2293 ret i8 %add 2294} 2295 2296; extra reduction because y + ~y -> -1 2297 2298define i5 @select_negate_not(i1 %b, i5 %x, i5 %y) { 2299; CHECK-LABEL: @select_negate_not( 2300; CHECK-NEXT: [[TMP1:%.*]] = sub i5 [[Y:%.*]], [[X:%.*]] 2301; CHECK-NEXT: [[ADD1:%.*]] = select i1 [[B:%.*]], i5 -1, i5 [[TMP1]] 2302; CHECK-NEXT: ret i5 [[ADD1]] 2303; 2304 %negx = sub i5 0, %x 2305 %noty = xor i5 %y, -1 2306 %sel = select i1 %b, i5 %noty, i5 %negx 2307 %add = add i5 %sel, %y 2308 ret i5 %add 2309} 2310 2311define i5 @select_negate_not_commute(i1 %b, i5 %x, i5 %p) { 2312; CHECK-LABEL: @select_negate_not_commute( 2313; CHECK-NEXT: [[Y:%.*]] = mul i5 [[P:%.*]], [[P]] 2314; CHECK-NEXT: [[TMP1:%.*]] = sub i5 [[Y]], [[X:%.*]] 2315; CHECK-NEXT: [[ADD1:%.*]] = select i1 [[B:%.*]], i5 -1, i5 [[TMP1]] 2316; CHECK-NEXT: ret i5 [[ADD1]] 2317; 2318 %y = mul i5 %p, %p ; thwart complexity-based canonicalization 2319 %negx = sub i5 0, %x 2320 %noty = xor i5 %y, -1 2321 %sel = select i1 %b, i5 %noty, i5 %negx 2322 %add = add i5 %y, %sel 2323 ret i5 %add 2324} 2325 2326define i5 @select_negate_not_swap(i1 %b, i5 %x, i5 %y) { 2327; CHECK-LABEL: @select_negate_not_swap( 2328; CHECK-NEXT: [[TMP1:%.*]] = sub i5 [[Y:%.*]], [[X:%.*]] 2329; CHECK-NEXT: [[ADD1:%.*]] = select i1 [[B:%.*]], i5 [[TMP1]], i5 -1 2330; CHECK-NEXT: ret i5 [[ADD1]] 2331; 2332 %negx = sub i5 0, %x 2333 %noty = xor i5 %y, -1 2334 %sel = select i1 %b, i5 %negx, i5 %noty 2335 %add = add i5 %sel, %y 2336 ret i5 %add 2337} 2338 2339define i5 @select_negate_not_swap_commute(i1 %b, i5 %x, i5 %p) { 2340; CHECK-LABEL: @select_negate_not_swap_commute( 2341; CHECK-NEXT: [[Y:%.*]] = mul i5 [[P:%.*]], [[P]] 2342; CHECK-NEXT: [[TMP1:%.*]] = sub i5 [[Y]], [[X:%.*]] 2343; CHECK-NEXT: [[ADD1:%.*]] = select i1 [[B:%.*]], i5 [[TMP1]], i5 -1 2344; CHECK-NEXT: ret i5 [[ADD1]] 2345; 2346 %y = mul i5 %p, %p ; thwart complexity-based canonicalization 2347 %negx = sub i5 0, %x 2348 %noty = xor i5 %y, -1 2349 %sel = select i1 %b, i5 %negx, i5 %noty 2350 %add = add i5 %y, %sel 2351 ret i5 %add 2352} 2353 2354define i32 @add_select_sub_both_arms_simplify(i1 %b, i32 %a) { 2355; CHECK-LABEL: @add_select_sub_both_arms_simplify( 2356; CHECK-NEXT: [[ADD:%.*]] = select i1 [[B:%.*]], i32 [[A:%.*]], i32 99 2357; CHECK-NEXT: ret i32 [[ADD]] 2358; 2359 %sub = sub i32 99, %a 2360 %sel = select i1 %b, i32 0, i32 %sub 2361 %add = add i32 %sel, %a 2362 ret i32 %add 2363} 2364 2365define <2 x i8> @add_select_sub_both_arms_simplify_swap(<2 x i1> %b, <2 x i8> %a) { 2366; CHECK-LABEL: @add_select_sub_both_arms_simplify_swap( 2367; CHECK-NEXT: [[ADD:%.*]] = select <2 x i1> [[B:%.*]], <2 x i8> <i8 42, i8 99>, <2 x i8> [[A:%.*]] 2368; CHECK-NEXT: ret <2 x i8> [[ADD]] 2369; 2370 %sub = sub <2 x i8> <i8 42, i8 99>, %a 2371 %sel = select <2 x i1> %b, <2 x i8> %sub, <2 x i8> zeroinitializer 2372 %add = add <2 x i8> %sel, %a 2373 ret <2 x i8> %add 2374} 2375 2376define i8 @add_select_sub_both_arms_simplify_use1(i1 %b, i8 %a) { 2377; CHECK-LABEL: @add_select_sub_both_arms_simplify_use1( 2378; CHECK-NEXT: [[SUB:%.*]] = sub i8 42, [[A:%.*]] 2379; CHECK-NEXT: call void @use(i8 [[SUB]]) 2380; CHECK-NEXT: [[ADD:%.*]] = select i1 [[B:%.*]], i8 [[A]], i8 42 2381; CHECK-NEXT: ret i8 [[ADD]] 2382; 2383 %sub = sub i8 42, %a 2384 call void @use(i8 %sub) 2385 %sel = select i1 %b, i8 0, i8 %sub 2386 %add = add i8 %sel, %a 2387 ret i8 %add 2388} 2389 2390define i8 @add_select_sub_both_arms_simplify_use2(i1 %b, i8 %a) { 2391; CHECK-LABEL: @add_select_sub_both_arms_simplify_use2( 2392; CHECK-NEXT: [[SUB:%.*]] = sub i8 42, [[A:%.*]] 2393; CHECK-NEXT: [[SEL:%.*]] = select i1 [[B:%.*]], i8 0, i8 [[SUB]] 2394; CHECK-NEXT: call void @use(i8 [[SEL]]) 2395; CHECK-NEXT: [[ADD:%.*]] = add i8 [[SEL]], [[A]] 2396; CHECK-NEXT: ret i8 [[ADD]] 2397; 2398 %sub = sub i8 42, %a 2399 %sel = select i1 %b, i8 0, i8 %sub 2400 call void @use(i8 %sel) 2401 %add = add i8 %sel, %a 2402 ret i8 %add 2403} 2404 2405define i5 @demand_low_bits_uses(i8 %x, i8 %y) { 2406; CHECK-LABEL: @demand_low_bits_uses( 2407; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 5 2408; CHECK-NEXT: [[A:%.*]] = sub i8 [[Y:%.*]], [[TMP1]] 2409; CHECK-NEXT: call void @use(i8 [[A]]) 2410; CHECK-NEXT: [[R:%.*]] = trunc i8 [[Y]] to i5 2411; CHECK-NEXT: ret i5 [[R]] 2412; 2413 %m = mul i8 %x, -32 ; 0xE0 2414 %a = add i8 %m, %y 2415 call void @use(i8 %a) 2416 %r = trunc i8 %a to i5 2417 ret i5 %r 2418} 2419 2420; negative test - demands one more bit 2421 2422define i6 @demand_low_bits_uses_extra_bit(i8 %x, i8 %y) { 2423; CHECK-LABEL: @demand_low_bits_uses_extra_bit( 2424; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 5 2425; CHECK-NEXT: [[A:%.*]] = sub i8 [[Y:%.*]], [[TMP1]] 2426; CHECK-NEXT: call void @use(i8 [[A]]) 2427; CHECK-NEXT: [[R:%.*]] = trunc i8 [[A]] to i6 2428; CHECK-NEXT: ret i6 [[R]] 2429; 2430 %m = mul i8 %x, -32 ; 0xE0 2431 %a = add i8 %m, %y 2432 call void @use(i8 %a) 2433 %r = trunc i8 %a to i6 2434 ret i6 %r 2435} 2436 2437define i8 @demand_low_bits_uses_commute(i8 %x, i8 %p, i8 %z) { 2438; CHECK-LABEL: @demand_low_bits_uses_commute( 2439; CHECK-NEXT: [[Y:%.*]] = mul i8 [[P:%.*]], [[P]] 2440; CHECK-NEXT: [[M:%.*]] = and i8 [[X:%.*]], -64 2441; CHECK-NEXT: [[A:%.*]] = add i8 [[Y]], [[M]] 2442; CHECK-NEXT: call void @use(i8 [[A]]) 2443; CHECK-NEXT: [[S:%.*]] = sub i8 [[Y]], [[Z:%.*]] 2444; CHECK-NEXT: [[R:%.*]] = shl i8 [[S]], 2 2445; CHECK-NEXT: ret i8 [[R]] 2446; 2447 %y = mul i8 %p, %p ; thwart complexity-based canonicalization 2448 %m = and i8 %x, -64 ; 0xC0 2449 %a = add i8 %y, %m 2450 call void @use(i8 %a) 2451 %s = sub i8 %a, %z 2452 %r = shl i8 %s, 2 2453 ret i8 %r 2454} 2455 2456; negative test - demands one more bit 2457 2458define i8 @demand_low_bits_uses_commute_extra_bit(i8 %x, i8 %p, i8 %z) { 2459; CHECK-LABEL: @demand_low_bits_uses_commute_extra_bit( 2460; CHECK-NEXT: [[Y:%.*]] = mul i8 [[P:%.*]], [[P]] 2461; CHECK-NEXT: [[M:%.*]] = and i8 [[X:%.*]], -64 2462; CHECK-NEXT: [[A:%.*]] = add i8 [[Y]], [[M]] 2463; CHECK-NEXT: call void @use(i8 [[A]]) 2464; CHECK-NEXT: [[S:%.*]] = sub i8 [[A]], [[Z:%.*]] 2465; CHECK-NEXT: [[R:%.*]] = shl i8 [[S]], 1 2466; CHECK-NEXT: ret i8 [[R]] 2467; 2468 %y = mul i8 %p, %p ; thwart complexity-based canonicalization 2469 %m = and i8 %x, -64 ; 0xC0 2470 %a = add i8 %y, %m 2471 call void @use(i8 %a) 2472 %s = sub i8 %a, %z 2473 %r = shl i8 %s, 1 2474 ret i8 %r 2475} 2476 2477define { i64, i64 } @PR57576(i64 noundef %x, i64 noundef %y, i64 noundef %z, i64 noundef %w) { 2478; CHECK-LABEL: @PR57576( 2479; CHECK-NEXT: [[ZX:%.*]] = zext i64 [[X:%.*]] to i128 2480; CHECK-NEXT: [[ZY:%.*]] = zext i64 [[Y:%.*]] to i128 2481; CHECK-NEXT: [[ZZ:%.*]] = zext i64 [[Z:%.*]] to i128 2482; CHECK-NEXT: [[SHY:%.*]] = shl nuw i128 [[ZY]], 64 2483; CHECK-NEXT: [[XY:%.*]] = or disjoint i128 [[SHY]], [[ZX]] 2484; CHECK-NEXT: [[SUB:%.*]] = sub i128 [[XY]], [[ZZ]] 2485; CHECK-NEXT: [[T:%.*]] = trunc i128 [[SUB]] to i64 2486; CHECK-NEXT: [[TMP1:%.*]] = lshr i128 [[SUB]], 64 2487; CHECK-NEXT: [[DOTTR:%.*]] = trunc nuw i128 [[TMP1]] to i64 2488; CHECK-NEXT: [[DOTNARROW:%.*]] = sub i64 [[DOTTR]], [[W:%.*]] 2489; CHECK-NEXT: [[R1:%.*]] = insertvalue { i64, i64 } poison, i64 [[T]], 0 2490; CHECK-NEXT: [[R2:%.*]] = insertvalue { i64, i64 } [[R1]], i64 [[DOTNARROW]], 1 2491; CHECK-NEXT: ret { i64, i64 } [[R2]] 2492; 2493 %zx = zext i64 %x to i128 2494 %zy = zext i64 %y to i128 2495 %zw = zext i64 %w to i128 2496 %zz = zext i64 %z to i128 2497 %shy = shl nuw i128 %zy, 64 2498 %mw = mul i128 %zw, -18446744073709551616 2499 %xy = or i128 %shy, %zx 2500 %sub = sub i128 %xy, %zz 2501 %add = add i128 %sub, %mw 2502 %t = trunc i128 %add to i64 2503 %h = lshr i128 %add, 64 2504 %t2 = trunc i128 %h to i64 2505 %r1 = insertvalue { i64, i64 } poison, i64 %t, 0 2506 %r2 = insertvalue { i64, i64 } %r1, i64 %t2, 1 2507 ret { i64, i64 } %r2 2508} 2509 2510define i8 @mul_negpow2(i8 %x, i8 %y) { 2511; CHECK-LABEL: @mul_negpow2( 2512; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 1 2513; CHECK-NEXT: [[A:%.*]] = sub i8 [[Y:%.*]], [[TMP1]] 2514; CHECK-NEXT: ret i8 [[A]] 2515; 2516 %m = mul i8 %x, -2 2517 %a = add i8 %m, %y 2518 ret i8 %a 2519} 2520 2521define <2 x i8> @mul_negpow2_commute_vec(<2 x i8> %x, <2 x i8> %p) { 2522; CHECK-LABEL: @mul_negpow2_commute_vec( 2523; CHECK-NEXT: [[Y:%.*]] = mul <2 x i8> [[P:%.*]], [[P]] 2524; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i8> [[X:%.*]], splat (i8 3) 2525; CHECK-NEXT: [[A:%.*]] = sub <2 x i8> [[Y]], [[TMP1]] 2526; CHECK-NEXT: ret <2 x i8> [[A]] 2527; 2528 %y = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization 2529 %m = mul <2 x i8> %x, <i8 -8, i8 -8> 2530 %a = add <2 x i8> %y, %m 2531 ret <2 x i8> %a 2532} 2533 2534; negative test - extra use 2535 2536define i8 @mul_negpow2_use(i8 %x) { 2537; CHECK-LABEL: @mul_negpow2_use( 2538; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], -2 2539; CHECK-NEXT: call void @use(i8 [[M]]) 2540; CHECK-NEXT: [[A:%.*]] = add i8 [[M]], 42 2541; CHECK-NEXT: ret i8 [[A]] 2542; 2543 %m = mul i8 %x, -2 2544 call void @use(i8 %m) 2545 %a = add i8 %m, 42 2546 ret i8 %a 2547} 2548 2549; negative test - not negative-power-of-2 multiplier 2550 2551define i8 @mul_not_negpow2(i8 %x) { 2552; CHECK-LABEL: @mul_not_negpow2( 2553; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], -3 2554; CHECK-NEXT: [[A:%.*]] = add i8 [[M]], 42 2555; CHECK-NEXT: ret i8 [[A]] 2556; 2557 %m = mul i8 %x, -3 2558 %a = add i8 %m, 42 2559 ret i8 %a 2560} 2561 2562define i16 @add_sub_zext(i8 %x, i8 %y) { 2563; CHECK-LABEL: @add_sub_zext( 2564; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[Y:%.*]] to i16 2565; CHECK-NEXT: ret i16 [[TMP1]] 2566; 2567 %1 = sub nuw i8 %y, %x 2568 %2 = zext i8 %1 to i16 2569 %3 = zext i8 %x to i16 2570 %4 = add i16 %2, %3 2571 ret i16 %4 2572} 2573 2574define i16 @add_commute_sub_zext(i8 %x, i8 %y) { 2575; CHECK-LABEL: @add_commute_sub_zext( 2576; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[Y:%.*]] to i16 2577; CHECK-NEXT: ret i16 [[TMP1]] 2578; 2579 %1 = sub nuw i8 %y, %x 2580 %2 = zext i8 %1 to i16 2581 %3 = zext i8 %x to i16 2582 %4 = add i16 %3, %2 2583 ret i16 %4 2584} 2585 2586define <2 x i8> @add_sub_2xi5_zext(<2 x i5> %x, <2 x i5> %y) { 2587; CHECK-LABEL: @add_sub_2xi5_zext( 2588; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i5> [[Y:%.*]] to <2 x i8> 2589; CHECK-NEXT: ret <2 x i8> [[TMP1]] 2590; 2591 %1 = sub nuw <2 x i5> %y, %x 2592 %2 = zext <2 x i5> %1 to <2 x i8> 2593 %3 = zext <2 x i5> %x to <2 x i8> 2594 %4 = add <2 x i8> %3, %2 2595 ret <2 x i8> %4 2596} 2597 2598 2599define i3 @add_commute_sub_i2_zext_i3(i2 %x, i2 %y) { 2600; CHECK-LABEL: @add_commute_sub_i2_zext_i3( 2601; CHECK-NEXT: [[TMP1:%.*]] = zext i2 [[Y:%.*]] to i3 2602; CHECK-NEXT: ret i3 [[TMP1]] 2603; 2604 %1 = sub nuw i2 %y, %x 2605 %2 = zext i2 %1 to i3 2606 %3 = zext i2 %x to i3 2607 %4 = add i3 %3, %2 2608 ret i3 %4 2609} 2610 2611define i16 @add_sub_use_zext(i8 %x, i8 %y) { 2612; CHECK-LABEL: @add_sub_use_zext( 2613; CHECK-NEXT: [[TMP1:%.*]] = sub nuw i8 [[Y:%.*]], [[X:%.*]] 2614; CHECK-NEXT: call void @use(i8 [[TMP1]]) 2615; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[Y]] to i16 2616; CHECK-NEXT: ret i16 [[TMP2]] 2617; 2618 %1 = sub nuw i8 %y, %x 2619 call void @use(i8 %1) 2620 %2 = zext i8 %1 to i16 2621 %3 = zext i8 %x to i16 2622 %4 = add i16 %2, %3 2623 ret i16 %4 2624} 2625 2626; Negative test: x - y + x != y 2627define i16 @add_sub_commute_zext(i8 %x, i8 %y) { 2628; CHECK-LABEL: @add_sub_commute_zext( 2629; CHECK-NEXT: [[TMP1:%.*]] = sub nuw i8 [[X:%.*]], [[Y:%.*]] 2630; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i16 2631; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[X]] to i16 2632; CHECK-NEXT: [[TMP4:%.*]] = add nuw nsw i16 [[TMP2]], [[TMP3]] 2633; CHECK-NEXT: ret i16 [[TMP4]] 2634; 2635 %1 = sub nuw i8 %x, %y 2636 %2 = zext i8 %1 to i16 2637 %3 = zext i8 %x to i16 2638 %4 = add i16 %2, %3 2639 ret i16 %4 2640} 2641 2642; Negative test: no nuw flags 2643define i16 @add_no_nuw_sub_zext(i8 %x, i8 %y) { 2644; CHECK-LABEL: @add_no_nuw_sub_zext( 2645; CHECK-NEXT: [[TMP1:%.*]] = sub i8 [[Y:%.*]], [[X:%.*]] 2646; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i16 2647; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[X]] to i16 2648; CHECK-NEXT: [[TMP4:%.*]] = add nuw nsw i16 [[TMP3]], [[TMP2]] 2649; CHECK-NEXT: ret i16 [[TMP4]] 2650; 2651 %1 = sub i8 %y, %x 2652 %2 = zext i8 %1 to i16 2653 %3 = zext i8 %x to i16 2654 %4 = add i16 %3, %2 2655 ret i16 %4 2656} 2657 2658define i16 @add_no_nuw_sub_commute_zext(i8 %x, i8 %y) { 2659; CHECK-LABEL: @add_no_nuw_sub_commute_zext( 2660; CHECK-NEXT: [[TMP1:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] 2661; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i16 2662; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[X]] to i16 2663; CHECK-NEXT: [[TMP4:%.*]] = add nuw nsw i16 [[TMP3]], [[TMP2]] 2664; CHECK-NEXT: ret i16 [[TMP4]] 2665; 2666 %1 = sub i8 %x, %y 2667 %2 = zext i8 %1 to i16 2668 %3 = zext i8 %x to i16 2669 %4 = add i16 %3, %2 2670 ret i16 %4 2671} 2672 2673define i16 @add_sub_zext_constant(i8 %x) { 2674; CHECK-LABEL: @add_sub_zext_constant( 2675; CHECK-NEXT: ret i16 254 2676; 2677 %1 = sub nuw i8 254, %x 2678 %2 = zext i8 %1 to i16 2679 %3 = zext i8 %x to i16 2680 %4 = add i16 %2, %3 2681 ret i16 %4 2682} 2683 2684define <vscale x 1 x i32> @add_to_or_scalable(<vscale x 1 x i32> %in) { 2685; CHECK-LABEL: @add_to_or_scalable( 2686; CHECK-NEXT: [[SHL:%.*]] = shl <vscale x 1 x i32> [[IN:%.*]], splat (i32 1) 2687; CHECK-NEXT: [[ADD:%.*]] = or disjoint <vscale x 1 x i32> [[SHL]], splat (i32 1) 2688; CHECK-NEXT: ret <vscale x 1 x i32> [[ADD]] 2689; 2690 %shl = shl <vscale x 1 x i32> %in, splat (i32 1) 2691 %add = add <vscale x 1 x i32> %shl, splat (i32 1) 2692 ret <vscale x 1 x i32> %add 2693} 2694 2695define i5 @zext_zext_not(i3 noundef %x) { 2696; CHECK-LABEL: @zext_zext_not( 2697; CHECK-NEXT: ret i5 7 2698; 2699 %zx = zext i3 %x to i5 2700 %notx = xor i3 %x, -1 2701 %znotx = zext i3 %notx to i5 2702 %r = add i5 %zx, %znotx 2703 ret i5 %r 2704} 2705 2706define <2 x i5> @zext_zext_not_commute(<2 x i3> noundef %x) { 2707; CHECK-LABEL: @zext_zext_not_commute( 2708; CHECK-NEXT: ret <2 x i5> splat (i5 7) 2709; 2710 %zx = zext <2 x i3> %x to <2 x i5> 2711 %notx = xor <2 x i3> %x, <i3 -1, i3 poison> 2712 %znotx = zext <2 x i3> %notx to <2 x i5> 2713 %r = add <2 x i5> %znotx, %zx 2714 ret <2 x i5> %r 2715} 2716 2717define i9 @sext_sext_not(i3 noundef %x) { 2718; CHECK-LABEL: @sext_sext_not( 2719; CHECK-NEXT: ret i9 -1 2720; 2721 %sx = sext i3 %x to i9 2722 %notx = xor i3 %x, -1 2723 %snotx = sext i3 %notx to i9 2724 %r = add i9 %sx, %snotx 2725 ret i9 %r 2726} 2727 2728define i8 @sext_sext_not_commute(i3 noundef %x) { 2729; CHECK-LABEL: @sext_sext_not_commute( 2730; CHECK-NEXT: [[SX:%.*]] = sext i3 [[X:%.*]] to i8 2731; CHECK-NEXT: call void @use(i8 [[SX]]) 2732; CHECK-NEXT: ret i8 -1 2733; 2734 2735 %sx = sext i3 %x to i8 2736 call void @use(i8 %sx) 2737 %notx = xor i3 %x, -1 2738 %snotx = sext i3 %notx to i8 2739 %r = add i8 %snotx, %sx 2740 ret i8 %r 2741} 2742 2743define i5 @zext_sext_not(i4 noundef %x) { 2744; CHECK-LABEL: @zext_sext_not( 2745; CHECK-NEXT: [[ZX:%.*]] = zext i4 [[X:%.*]] to i5 2746; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -1 2747; CHECK-NEXT: [[SNOTX:%.*]] = sext i4 [[NOTX]] to i5 2748; CHECK-NEXT: [[R:%.*]] = or disjoint i5 [[ZX]], [[SNOTX]] 2749; CHECK-NEXT: ret i5 [[R]] 2750; 2751 %zx = zext i4 %x to i5 2752 %notx = xor i4 %x, -1 2753 %snotx = sext i4 %notx to i5 2754 %r = add i5 %zx, %snotx 2755 ret i5 %r 2756} 2757 2758define i8 @zext_sext_not_commute(i4 noundef %x) { 2759; CHECK-LABEL: @zext_sext_not_commute( 2760; CHECK-NEXT: [[ZX:%.*]] = zext i4 [[X:%.*]] to i8 2761; CHECK-NEXT: call void @use(i8 [[ZX]]) 2762; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -1 2763; CHECK-NEXT: [[SNOTX:%.*]] = sext i4 [[NOTX]] to i8 2764; CHECK-NEXT: call void @use(i8 [[SNOTX]]) 2765; CHECK-NEXT: [[R:%.*]] = or disjoint i8 [[SNOTX]], [[ZX]] 2766; CHECK-NEXT: ret i8 [[R]] 2767; 2768 %zx = zext i4 %x to i8 2769 call void @use(i8 %zx) 2770 %notx = xor i4 %x, -1 2771 %snotx = sext i4 %notx to i8 2772 call void @use(i8 %snotx) 2773 %r = add i8 %snotx, %zx 2774 ret i8 %r 2775} 2776 2777define i9 @sext_zext_not(i4 noundef %x) { 2778; CHECK-LABEL: @sext_zext_not( 2779; CHECK-NEXT: [[SX:%.*]] = sext i4 [[X:%.*]] to i9 2780; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -1 2781; CHECK-NEXT: [[ZNOTX:%.*]] = zext i4 [[NOTX]] to i9 2782; CHECK-NEXT: [[R:%.*]] = or disjoint i9 [[SX]], [[ZNOTX]] 2783; CHECK-NEXT: ret i9 [[R]] 2784; 2785 %sx = sext i4 %x to i9 2786 %notx = xor i4 %x, -1 2787 %znotx = zext i4 %notx to i9 2788 %r = add i9 %sx, %znotx 2789 ret i9 %r 2790} 2791 2792define i9 @sext_zext_not_commute(i4 noundef %x) { 2793; CHECK-LABEL: @sext_zext_not_commute( 2794; CHECK-NEXT: [[SX:%.*]] = sext i4 [[X:%.*]] to i9 2795; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -1 2796; CHECK-NEXT: [[ZNOTX:%.*]] = zext i4 [[NOTX]] to i9 2797; CHECK-NEXT: [[R:%.*]] = or disjoint i9 [[ZNOTX]], [[SX]] 2798; CHECK-NEXT: ret i9 [[R]] 2799; 2800 %sx = sext i4 %x to i9 2801 %notx = xor i4 %x, -1 2802 %znotx = zext i4 %notx to i9 2803 %r = add i9 %znotx, %sx 2804 ret i9 %r 2805} 2806 2807; PR57741 2808 2809define i32 @floor_sdiv(i32 %x) { 2810; CHECK-LABEL: @floor_sdiv( 2811; CHECK-NEXT: [[R:%.*]] = ashr i32 [[X:%.*]], 2 2812; CHECK-NEXT: ret i32 [[R]] 2813; 2814 %d = sdiv i32 %x, 4 2815 %a = and i32 %x, -2147483645 2816 %i = icmp ugt i32 %a, -2147483648 2817 %s = sext i1 %i to i32 2818 %r = add i32 %d, %s 2819 ret i32 %r 2820} 2821 2822define i8 @floor_sdiv_by_2(i8 %x) { 2823; CHECK-LABEL: @floor_sdiv_by_2( 2824; CHECK-NEXT: [[RV:%.*]] = ashr i8 [[X:%.*]], 1 2825; CHECK-NEXT: ret i8 [[RV]] 2826; 2827 %div = sdiv i8 %x, 2 2828 %and = and i8 %x, -127 2829 %icmp = icmp eq i8 %and, -127 2830 %sext = sext i1 %icmp to i8 2831 %rv = add nsw i8 %div, %sext 2832 ret i8 %rv 2833} 2834 2835define i8 @floor_sdiv_by_2_wrong_mask(i8 %x) { 2836; CHECK-LABEL: @floor_sdiv_by_2_wrong_mask( 2837; CHECK-NEXT: [[DIV:%.*]] = sdiv i8 [[X:%.*]], 2 2838; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], 127 2839; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i8 [[AND]], 127 2840; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[ICMP]] to i8 2841; CHECK-NEXT: [[RV:%.*]] = add nsw i8 [[DIV]], [[SEXT]] 2842; CHECK-NEXT: ret i8 [[RV]] 2843; 2844 %div = sdiv i8 %x, 2 2845 %and = and i8 %x, 127 2846 %icmp = icmp eq i8 %and, 127 2847 %sext = sext i1 %icmp to i8 2848 %rv = add nsw i8 %div, %sext 2849 ret i8 %rv 2850} 2851 2852define i8 @floor_sdiv_by_2_wrong_constant(i8 %x) { 2853; CHECK-LABEL: @floor_sdiv_by_2_wrong_constant( 2854; CHECK-NEXT: [[DIV:%.*]] = sdiv i8 [[X:%.*]], 4 2855; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -125 2856; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i8 [[AND]], -125 2857; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[ICMP]] to i8 2858; CHECK-NEXT: [[RV:%.*]] = add nsw i8 [[DIV]], [[SEXT]] 2859; CHECK-NEXT: ret i8 [[RV]] 2860; 2861 %div = sdiv i8 %x, 4 2862 %and = and i8 %x, -125 2863 %icmp = icmp eq i8 %and, -125 2864 %sext = sext i1 %icmp to i8 2865 %rv = add nsw i8 %div, %sext 2866 ret i8 %rv 2867} 2868 2869define i8 @floor_sdiv_by_2_wrong_cast(i8 %x) { 2870; CHECK-LABEL: @floor_sdiv_by_2_wrong_cast( 2871; CHECK-NEXT: [[DIV:%.*]] = sdiv i8 [[X:%.*]], 2 2872; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -127 2873; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i8 [[AND]], -127 2874; CHECK-NEXT: [[SEXT:%.*]] = zext i1 [[ICMP]] to i8 2875; CHECK-NEXT: [[RV:%.*]] = add nsw i8 [[DIV]], [[SEXT]] 2876; CHECK-NEXT: ret i8 [[RV]] 2877; 2878 %div = sdiv i8 %x, 2 2879 %and = and i8 %x, -127 2880 %icmp = icmp eq i8 %and, -127 2881 %sext = zext i1 %icmp to i8 2882 %rv = add nsw i8 %div, %sext 2883 ret i8 %rv 2884} 2885 2886; vectors work too and commute is handled by complexity-based canonicalization 2887 2888define <2 x i32> @floor_sdiv_vec_commute(<2 x i32> %x) { 2889; CHECK-LABEL: @floor_sdiv_vec_commute( 2890; CHECK-NEXT: [[R:%.*]] = ashr <2 x i32> [[X:%.*]], splat (i32 2) 2891; CHECK-NEXT: ret <2 x i32> [[R]] 2892; 2893 %d = sdiv <2 x i32> %x, <i32 4, i32 4> 2894 %a = and <2 x i32> %x, <i32 -2147483645, i32 -2147483645> 2895 %i = icmp ugt <2 x i32> %a, <i32 -2147483648, i32 -2147483648> 2896 %s = sext <2 x i1> %i to <2 x i32> 2897 %r = add <2 x i32> %s, %d 2898 ret <2 x i32> %r 2899} 2900 2901; extra uses are ok 2902 2903define i8 @floor_sdiv_uses(i8 %x) { 2904; CHECK-LABEL: @floor_sdiv_uses( 2905; CHECK-NEXT: [[D:%.*]] = sdiv i8 [[X:%.*]], 16 2906; CHECK-NEXT: call void @use(i8 [[D]]) 2907; CHECK-NEXT: [[A:%.*]] = and i8 [[X]], -113 2908; CHECK-NEXT: call void @use(i8 [[A]]) 2909; CHECK-NEXT: [[I:%.*]] = icmp ugt i8 [[A]], -128 2910; CHECK-NEXT: [[S:%.*]] = sext i1 [[I]] to i8 2911; CHECK-NEXT: call void @use(i8 [[S]]) 2912; CHECK-NEXT: [[R:%.*]] = ashr i8 [[X]], 4 2913; CHECK-NEXT: ret i8 [[R]] 2914; 2915 %d = sdiv i8 %x, 16 2916 call void @use(i8 %d) 2917 %a = and i8 %x, 143 ; 128 + 15 2918 call void @use(i8 %a) 2919 %i = icmp ugt i8 %a, 128 2920 %s = sext i1 %i to i8 2921 call void @use(i8 %s) 2922 %r = add i8 %d, %s 2923 ret i8 %r 2924} 2925 2926; negative test 2927 2928define i32 @floor_sdiv_wrong_div(i32 %x) { 2929; CHECK-LABEL: @floor_sdiv_wrong_div( 2930; CHECK-NEXT: [[D:%.*]] = sdiv i32 [[X:%.*]], 8 2931; CHECK-NEXT: [[A:%.*]] = and i32 [[X]], -2147483645 2932; CHECK-NEXT: [[I:%.*]] = icmp ugt i32 [[A]], -2147483648 2933; CHECK-NEXT: [[S:%.*]] = sext i1 [[I]] to i32 2934; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[D]], [[S]] 2935; CHECK-NEXT: ret i32 [[R]] 2936; 2937 %d = sdiv i32 %x, 8 2938 %a = and i32 %x, -2147483645 2939 %i = icmp ugt i32 %a, -2147483648 2940 %s = sext i1 %i to i32 2941 %r = add i32 %d, %s 2942 ret i32 %r 2943} 2944 2945; negative test 2946 2947define i32 @floor_sdiv_wrong_mask(i32 %x) { 2948; CHECK-LABEL: @floor_sdiv_wrong_mask( 2949; CHECK-NEXT: [[D:%.*]] = sdiv i32 [[X:%.*]], 4 2950; CHECK-NEXT: [[A:%.*]] = and i32 [[X]], -2147483644 2951; CHECK-NEXT: [[I:%.*]] = icmp ugt i32 [[A]], -2147483648 2952; CHECK-NEXT: [[S:%.*]] = sext i1 [[I]] to i32 2953; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[D]], [[S]] 2954; CHECK-NEXT: ret i32 [[R]] 2955; 2956 %d = sdiv i32 %x, 4 2957 %a = and i32 %x, -2147483644 2958 %i = icmp ugt i32 %a, -2147483648 2959 %s = sext i1 %i to i32 2960 %r = add i32 %d, %s 2961 ret i32 %r 2962} 2963 2964; negative test 2965 2966define i32 @floor_sdiv_wrong_cmp(i32 %x) { 2967; CHECK-LABEL: @floor_sdiv_wrong_cmp( 2968; CHECK-NEXT: [[D:%.*]] = sdiv i32 [[X:%.*]], 4 2969; CHECK-NEXT: [[A:%.*]] = and i32 [[X]], -2147483646 2970; CHECK-NEXT: [[I:%.*]] = icmp eq i32 [[A]], -2147483646 2971; CHECK-NEXT: [[S:%.*]] = sext i1 [[I]] to i32 2972; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[D]], [[S]] 2973; CHECK-NEXT: ret i32 [[R]] 2974; 2975 %d = sdiv i32 %x, 4 2976 %a = and i32 %x, -2147483645 2977 %i = icmp ugt i32 %a, -2147483647 2978 %s = sext i1 %i to i32 2979 %r = add i32 %d, %s 2980 ret i32 %r 2981} 2982 2983; negative test 2984 2985define i32 @floor_sdiv_wrong_ext(i32 %x) { 2986; CHECK-LABEL: @floor_sdiv_wrong_ext( 2987; CHECK-NEXT: [[D:%.*]] = sdiv i32 [[X:%.*]], 4 2988; CHECK-NEXT: [[A:%.*]] = and i32 [[X]], -2147483645 2989; CHECK-NEXT: [[I:%.*]] = icmp ugt i32 [[A]], -2147483648 2990; CHECK-NEXT: [[S:%.*]] = zext i1 [[I]] to i32 2991; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[D]], [[S]] 2992; CHECK-NEXT: ret i32 [[R]] 2993; 2994 %d = sdiv i32 %x, 4 2995 %a = and i32 %x, -2147483645 2996 %i = icmp ugt i32 %a, -2147483648 2997 %s = zext i1 %i to i32 2998 %r = add i32 %d, %s 2999 ret i32 %r 3000} 3001 3002; negative test 3003 3004define i32 @floor_sdiv_wrong_op(i32 %x, i32 %y) { 3005; CHECK-LABEL: @floor_sdiv_wrong_op( 3006; CHECK-NEXT: [[D:%.*]] = sdiv i32 [[X:%.*]], 4 3007; CHECK-NEXT: [[A:%.*]] = and i32 [[Y:%.*]], -2147483645 3008; CHECK-NEXT: [[I:%.*]] = icmp ugt i32 [[A]], -2147483648 3009; CHECK-NEXT: [[S:%.*]] = zext i1 [[I]] to i32 3010; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[D]], [[S]] 3011; CHECK-NEXT: ret i32 [[R]] 3012; 3013 %d = sdiv i32 %x, 4 3014 %a = and i32 %y, -2147483645 3015 %i = icmp ugt i32 %a, -2147483648 3016 %s = zext i1 %i to i32 3017 %r = add i32 %d, %s 3018 ret i32 %r 3019} 3020 3021define i32 @floor_sdiv_using_srem_by_8(i32 %x) { 3022; CHECK-LABEL: @floor_sdiv_using_srem_by_8( 3023; CHECK-NEXT: [[F:%.*]] = ashr i32 [[X:%.*]], 3 3024; CHECK-NEXT: ret i32 [[F]] 3025; 3026 %d = sdiv i32 %x, 8 3027 %r = srem i32 %x, 8 3028 %i = icmp ugt i32 %r, -2147483648 3029 %s = sext i1 %i to i32 3030 %f = add i32 %d, %s 3031 ret i32 %f 3032} 3033 3034define i32 @floor_sdiv_using_srem_by_2(i32 %x) { 3035; CHECK-LABEL: @floor_sdiv_using_srem_by_2( 3036; CHECK-NEXT: [[F:%.*]] = ashr i32 [[X:%.*]], 1 3037; CHECK-NEXT: ret i32 [[F]] 3038; 3039 %d = sdiv i32 %x, 2 3040 %r = srem i32 %x, 2 3041 %i = icmp ugt i32 %r, -2147483648 3042 %s = sext i1 %i to i32 3043 %f = add i32 %d, %s 3044 ret i32 %f 3045} 3046 3047; (X s>> (BW - 1)) + (zext (X s> 0)) --> (X s>> (BW - 1)) | (zext (X != 0)) 3048 3049define i8 @signum_i8_i8(i8 %x) { 3050; CHECK-LABEL: @signum_i8_i8( 3051; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X:%.*]], 7 3052; CHECK-NEXT: [[ISNOTNULL:%.*]] = icmp ne i8 [[X]], 0 3053; CHECK-NEXT: [[ISNOTNULL_ZEXT:%.*]] = zext i1 [[ISNOTNULL]] to i8 3054; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGNBIT]], [[ISNOTNULL_ZEXT]] 3055; CHECK-NEXT: ret i8 [[R]] 3056; 3057 %sgt0 = icmp sgt i8 %x, 0 3058 %zgt0 = zext i1 %sgt0 to i8 3059 %signbit = ashr i8 %x, 7 3060 %r = add i8 %zgt0, %signbit 3061 ret i8 %r 3062} 3063 3064; extra use of shift is ok 3065 3066define i8 @signum_i8_i8_use1(i8 %x) { 3067; CHECK-LABEL: @signum_i8_i8_use1( 3068; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X:%.*]], 7 3069; CHECK-NEXT: call void @use(i8 [[SIGNBIT]]) 3070; CHECK-NEXT: [[ISNOTNULL:%.*]] = icmp ne i8 [[X]], 0 3071; CHECK-NEXT: [[ISNOTNULL_ZEXT:%.*]] = zext i1 [[ISNOTNULL]] to i8 3072; CHECK-NEXT: [[R:%.*]] = or i8 [[SIGNBIT]], [[ISNOTNULL_ZEXT]] 3073; CHECK-NEXT: ret i8 [[R]] 3074; 3075 %sgt0 = icmp sgt i8 %x, 0 3076 %zgt0 = zext i1 %sgt0 to i8 3077 %signbit = ashr i8 %x, 7 3078 call void @use(i8 %signbit) 3079 %r = add i8 %zgt0, %signbit 3080 ret i8 %r 3081} 3082 3083; negative test 3084 3085define i8 @signum_i8_i8_use2(i8 %x) { 3086; CHECK-LABEL: @signum_i8_i8_use2( 3087; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0 3088; CHECK-NEXT: [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8 3089; CHECK-NEXT: call void @use(i8 [[ZGT0]]) 3090; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 7 3091; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]] 3092; CHECK-NEXT: ret i8 [[R]] 3093; 3094 %sgt0 = icmp sgt i8 %x, 0 3095 %zgt0 = zext i1 %sgt0 to i8 3096 call void @use(i8 %zgt0) 3097 %signbit = ashr i8 %x, 7 3098 %r = add i8 %zgt0, %signbit 3099 ret i8 %r 3100} 3101 3102; negative test 3103 3104define i8 @signum_i8_i8_use3(i8 %x) { 3105; CHECK-LABEL: @signum_i8_i8_use3( 3106; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0 3107; CHECK-NEXT: call void @use_i1(i1 [[SGT0]]) 3108; CHECK-NEXT: [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8 3109; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 7 3110; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]] 3111; CHECK-NEXT: ret i8 [[R]] 3112; 3113 %sgt0 = icmp sgt i8 %x, 0 3114 call void @use_i1(i1 %sgt0) 3115 %zgt0 = zext i1 %sgt0 to i8 3116 %signbit = ashr i8 %x, 7 3117 %r = add i8 %zgt0, %signbit 3118 ret i8 %r 3119} 3120 3121; poison is ok to propagate in shift amount 3122; complexity canonicalization guarantees that shift is op0 of add 3123 3124define <2 x i5> @signum_v2i5_v2i5(<2 x i5> %x) { 3125; CHECK-LABEL: @signum_v2i5_v2i5( 3126; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr <2 x i5> [[X:%.*]], <i5 4, i5 poison> 3127; CHECK-NEXT: [[ISNOTNULL:%.*]] = icmp ne <2 x i5> [[X]], zeroinitializer 3128; CHECK-NEXT: [[ISNOTNULL_ZEXT:%.*]] = zext <2 x i1> [[ISNOTNULL]] to <2 x i5> 3129; CHECK-NEXT: [[R:%.*]] = or <2 x i5> [[SIGNBIT]], [[ISNOTNULL_ZEXT]] 3130; CHECK-NEXT: ret <2 x i5> [[R]] 3131; 3132 %sgt0 = icmp sgt <2 x i5> %x, zeroinitializer 3133 %zgt0 = zext <2 x i1> %sgt0 to <2 x i5> 3134 %signbit = ashr <2 x i5> %x, <i5 4, i5 poison> 3135 %r = add <2 x i5> %signbit, %zgt0 3136 ret <2 x i5> %r 3137} 3138 3139; negative test 3140 3141define i8 @signum_i8_i8_wrong_sh_amt(i8 %x) { 3142; CHECK-LABEL: @signum_i8_i8_wrong_sh_amt( 3143; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0 3144; CHECK-NEXT: [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8 3145; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 6 3146; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]] 3147; CHECK-NEXT: ret i8 [[R]] 3148; 3149 %sgt0 = icmp sgt i8 %x, 0 3150 %zgt0 = zext i1 %sgt0 to i8 3151 %signbit = ashr i8 %x, 6 3152 %r = add i8 %zgt0, %signbit 3153 ret i8 %r 3154} 3155 3156; negative test 3157 3158define i8 @signum_i8_i8_wrong_ext(i8 %x) { 3159; CHECK-LABEL: @signum_i8_i8_wrong_ext( 3160; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0 3161; CHECK-NEXT: [[ZGT0:%.*]] = sext i1 [[SGT0]] to i8 3162; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 7 3163; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]] 3164; CHECK-NEXT: ret i8 [[R]] 3165; 3166 %sgt0 = icmp sgt i8 %x, 0 3167 %zgt0 = sext i1 %sgt0 to i8 3168 %signbit = ashr i8 %x, 7 3169 %r = add i8 %zgt0, %signbit 3170 ret i8 %r 3171} 3172 3173; negative test 3174 3175define i8 @signum_i8_i8_wrong_pred(i8 %x) { 3176; CHECK-LABEL: @signum_i8_i8_wrong_pred( 3177; CHECK-NEXT: [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], -1 3178; CHECK-NEXT: [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8 3179; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X]], 7 3180; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]] 3181; CHECK-NEXT: ret i8 [[R]] 3182; 3183 %sgt0 = icmp sge i8 %x, 0 3184 %zgt0 = zext i1 %sgt0 to i8 3185 %signbit = ashr i8 %x, 7 3186 %r = add i8 %zgt0, %signbit 3187 ret i8 %r 3188} 3189 3190define i32 @dec_zext_add_assume_nonzero(i8 %x) { 3191; CHECK-LABEL: @dec_zext_add_assume_nonzero( 3192; CHECK-NEXT: [[Z:%.*]] = icmp ne i8 [[X:%.*]], 0 3193; CHECK-NEXT: call void @llvm.assume(i1 [[Z]]) 3194; CHECK-NEXT: [[C:%.*]] = zext i8 [[X]] to i32 3195; CHECK-NEXT: ret i32 [[C]] 3196; 3197 %z = icmp ne i8 %x, 0 3198 call void @llvm.assume(i1 %z) 3199 %a = add i8 %x, -1 3200 %b = zext i8 %a to i32 3201 %c = add i32 %b, 1 3202 ret i32 %c 3203} 3204 3205define i32 @dec_zext_add_nonzero(i8 %x) { 3206; CHECK-LABEL: @dec_zext_add_nonzero( 3207; CHECK-NEXT: [[O:%.*]] = or i8 [[X:%.*]], 4 3208; CHECK-NEXT: [[C:%.*]] = zext i8 [[O]] to i32 3209; CHECK-NEXT: ret i32 [[C]] 3210; 3211 %o = or i8 %x, 4 3212 %a = add i8 %o, -1 3213 %b = zext i8 %a to i32 3214 %c = add i32 %b, 1 3215 ret i32 %c 3216} 3217 3218define <2 x i32> @dec_zext_add_nonzero_vec(<2 x i8> %x) { 3219; CHECK-LABEL: @dec_zext_add_nonzero_vec( 3220; CHECK-NEXT: [[O:%.*]] = or <2 x i8> [[X:%.*]], splat (i8 8) 3221; CHECK-NEXT: [[C:%.*]] = zext <2 x i8> [[O]] to <2 x i32> 3222; CHECK-NEXT: ret <2 x i32> [[C]] 3223; 3224 %o = or <2 x i8> %x, <i8 8, i8 8> 3225 %a = add <2 x i8> %o, <i8 -1, i8 -1> 3226 %b = zext <2 x i8> %a to <2 x i32> 3227 %c = add <2 x i32> %b, <i32 1, i32 1> 3228 ret <2 x i32> %c 3229} 3230 3231; Negative test: Folding this with undef is not safe. 3232 3233define <2 x i32> @dec_zext_add_nonzero_vec_undef0(<2 x i8> %x) { 3234; CHECK-LABEL: @dec_zext_add_nonzero_vec_undef0( 3235; CHECK-NEXT: [[O:%.*]] = or <2 x i8> [[X:%.*]], <i8 8, i8 undef> 3236; CHECK-NEXT: [[A:%.*]] = add <2 x i8> [[O]], splat (i8 -1) 3237; CHECK-NEXT: [[B:%.*]] = zext <2 x i8> [[A]] to <2 x i32> 3238; CHECK-NEXT: [[C:%.*]] = add nuw nsw <2 x i32> [[B]], splat (i32 1) 3239; CHECK-NEXT: ret <2 x i32> [[C]] 3240; 3241 %o = or <2 x i8> %x, <i8 8, i8 undef> 3242 %a = add <2 x i8> %o, <i8 -1, i8 -1> 3243 %b = zext <2 x i8> %a to <2 x i32> 3244 %c = add <2 x i32> %b, <i32 1, i32 1> 3245 ret <2 x i32> %c 3246} 3247 3248define <2 x i32> @dec_zext_add_nonzero_poison0(<2 x i8> %x) { 3249; CHECK-LABEL: @dec_zext_add_nonzero_poison0( 3250; CHECK-NEXT: [[O:%.*]] = or <2 x i8> [[X:%.*]], <i8 8, i8 poison> 3251; CHECK-NEXT: [[C:%.*]] = zext <2 x i8> [[O]] to <2 x i32> 3252; CHECK-NEXT: ret <2 x i32> [[C]] 3253; 3254 %o = or <2 x i8> %x, <i8 8, i8 poison> 3255 %a = add <2 x i8> %o, <i8 -1, i8 -1> 3256 %b = zext <2 x i8> %a to <2 x i32> 3257 %c = add <2 x i32> %b, <i32 1, i32 1> 3258 ret <2 x i32> %c 3259} 3260 3261define <2 x i32> @dec_zext_add_nonzero_vec_poison1(<2 x i8> %x) { 3262; CHECK-LABEL: @dec_zext_add_nonzero_vec_poison1( 3263; CHECK-NEXT: [[O:%.*]] = or <2 x i8> [[X:%.*]], splat (i8 8) 3264; CHECK-NEXT: [[C:%.*]] = zext <2 x i8> [[O]] to <2 x i32> 3265; CHECK-NEXT: ret <2 x i32> [[C]] 3266; 3267 %o = or <2 x i8> %x, <i8 8, i8 8> 3268 %a = add <2 x i8> %o, <i8 -1, i8 poison> 3269 %b = zext <2 x i8> %a to <2 x i32> 3270 %c = add <2 x i32> %b, <i32 1, i32 1> 3271 ret <2 x i32> %c 3272} 3273 3274define <2 x i32> @dec_zext_add_nonzero_vec_poison2(<2 x i8> %x) { 3275; CHECK-LABEL: @dec_zext_add_nonzero_vec_poison2( 3276; CHECK-NEXT: [[O:%.*]] = or <2 x i8> [[X:%.*]], splat (i8 8) 3277; CHECK-NEXT: [[A:%.*]] = add nsw <2 x i8> [[O]], splat (i8 -1) 3278; CHECK-NEXT: [[B:%.*]] = zext <2 x i8> [[A]] to <2 x i32> 3279; CHECK-NEXT: [[C:%.*]] = add nuw nsw <2 x i32> [[B]], <i32 1, i32 poison> 3280; CHECK-NEXT: ret <2 x i32> [[C]] 3281; 3282 %o = or <2 x i8> %x, <i8 8, i8 8> 3283 %a = add <2 x i8> %o, <i8 -1, i8 -1> 3284 %b = zext <2 x i8> %a to <2 x i32> 3285 %c = add <2 x i32> %b, <i32 1, i32 poison> 3286 ret <2 x i32> %c 3287} 3288 3289define i32 @add_zext_sext_i1(i1 %a) { 3290; CHECK-LABEL: @add_zext_sext_i1( 3291; CHECK-NEXT: ret i32 0 3292; 3293 %zext = zext i1 %a to i32 3294 %sext = sext i1 %a to i32 3295 %add = add i32 %zext, %sext 3296 ret i32 %add 3297} 3298 3299define i32 @add_sext_zext_i1(i1 %a) { 3300; CHECK-LABEL: @add_sext_zext_i1( 3301; CHECK-NEXT: ret i32 0 3302; 3303 %zext = zext i1 %a to i32 3304 %sext = sext i1 %a to i32 3305 %add = add i32 %sext, %zext 3306 ret i32 %add 3307} 3308 3309define <2 x i32> @add_zext_sext_i1_vec(<2 x i1> %a) { 3310; CHECK-LABEL: @add_zext_sext_i1_vec( 3311; CHECK-NEXT: ret <2 x i32> zeroinitializer 3312; 3313 %zext = zext <2 x i1> %a to <2 x i32> 3314 %sext = sext <2 x i1> %a to <2 x i32> 3315 %add = add <2 x i32> %zext, %sext 3316 ret <2 x i32> %add 3317} 3318 3319define i32 @add_zext_zext_i1(i1 %a) { 3320; CHECK-LABEL: @add_zext_zext_i1( 3321; CHECK-NEXT: [[ADD:%.*]] = select i1 [[A:%.*]], i32 2, i32 0 3322; CHECK-NEXT: ret i32 [[ADD]] 3323; 3324 %zext = zext i1 %a to i32 3325 %add = add i32 %zext, %zext 3326 ret i32 %add 3327} 3328 3329define i32 @add_sext_sext_i1(i1 %a) { 3330; CHECK-LABEL: @add_sext_sext_i1( 3331; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[A:%.*]] to i32 3332; CHECK-NEXT: [[ADD:%.*]] = shl nsw i32 [[SEXT]], 1 3333; CHECK-NEXT: ret i32 [[ADD]] 3334; 3335 %sext = sext i1 %a to i32 3336 %add = add i32 %sext, %sext 3337 ret i32 %add 3338} 3339 3340define i32 @add_zext_sext_not_i1(i8 %a) { 3341; CHECK-LABEL: @add_zext_sext_not_i1( 3342; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[A:%.*]] to i32 3343; CHECK-NEXT: [[SEXT:%.*]] = sext i8 [[A]] to i32 3344; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[ZEXT]], [[SEXT]] 3345; CHECK-NEXT: ret i32 [[ADD]] 3346; 3347 %zext = zext i8 %a to i32 3348 %sext = sext i8 %a to i32 3349 %add = add i32 %zext, %sext 3350 ret i32 %add 3351} 3352 3353define i32 @add_zext_sext_i1_different_values(i1 %a, i1 %b) { 3354; CHECK-LABEL: @add_zext_sext_i1_different_values( 3355; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[A:%.*]] to i32 3356; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[B:%.*]] to i32 3357; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[ZEXT]], [[SEXT]] 3358; CHECK-NEXT: ret i32 [[ADD]] 3359; 3360 %zext = zext i1 %a to i32 3361 %sext = sext i1 %b to i32 3362 %add = add i32 %zext, %sext 3363 ret i32 %add 3364} 3365 3366define i32 @add_reduce_sqr_sum_nsw(i32 %a, i32 %b) { 3367; CHECK-LABEL: @add_reduce_sqr_sum_nsw( 3368; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 3369; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3370; CHECK-NEXT: ret i32 [[ADD]] 3371; 3372 %a_sq = mul nsw i32 %a, %a 3373 %two_a = shl i32 %a, 1 3374 %two_a_plus_b = add i32 %two_a, %b 3375 %mul = mul i32 %two_a_plus_b, %b 3376 %add = add i32 %mul, %a_sq 3377 ret i32 %add 3378} 3379 3380define i32 @add_reduce_sqr_sum_u(i32 %a, i32 %b) { 3381; CHECK-LABEL: @add_reduce_sqr_sum_u( 3382; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 3383; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3384; CHECK-NEXT: ret i32 [[ADD]] 3385; 3386 %a_sq = mul i32 %a, %a 3387 %two_a = shl i32 %a, 1 3388 %two_a_plus_b = add i32 %two_a, %b 3389 %mul = mul i32 %two_a_plus_b, %b 3390 %add = add i32 %mul, %a_sq 3391 ret i32 %add 3392} 3393 3394define i32 @add_reduce_sqr_sum_nuw(i32 %a, i32 %b) { 3395; CHECK-LABEL: @add_reduce_sqr_sum_nuw( 3396; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 3397; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3398; CHECK-NEXT: ret i32 [[ADD]] 3399; 3400 %a_sq = mul nuw i32 %a, %a 3401 %two_a = mul i32 %a, 2 3402 %two_a_plus_b = add i32 %two_a, %b 3403 %mul = mul nuw i32 %two_a_plus_b, %b 3404 %add = add i32 %mul, %a_sq 3405 ret i32 %add 3406} 3407 3408define i32 @add_reduce_sqr_sum_flipped(i32 %a, i32 %b) { 3409; CHECK-LABEL: @add_reduce_sqr_sum_flipped( 3410; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 3411; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3412; CHECK-NEXT: ret i32 [[ADD]] 3413; 3414 %a_sq = mul nsw i32 %a, %a 3415 %two_a = shl i32 %a, 1 3416 %two_a_plus_b = add i32 %two_a, %b 3417 %mul = mul i32 %two_a_plus_b, %b 3418 %add = add i32 %a_sq, %mul 3419 ret i32 %add 3420} 3421 3422define i32 @add_reduce_sqr_sum_flipped2(i32 %a, i32 %bx) { 3423; CHECK-LABEL: @add_reduce_sqr_sum_flipped2( 3424; CHECK-NEXT: [[B:%.*]] = xor i32 [[BX:%.*]], 42 3425; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B]] 3426; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3427; CHECK-NEXT: ret i32 [[ADD]] 3428; 3429 %b = xor i32 %bx, 42 ; thwart complexity-based canonicalization 3430 %a_sq = mul nsw i32 %a, %a 3431 %two_a = shl i32 %a, 1 3432 %two_a_plus_b = add i32 %two_a, %b 3433 %mul = mul i32 %b, %two_a_plus_b 3434 %add = add i32 %mul, %a_sq 3435 ret i32 %add 3436} 3437 3438define i32 @add_reduce_sqr_sum_flipped3(i32 %a, i32 %b) { 3439; CHECK-LABEL: @add_reduce_sqr_sum_flipped3( 3440; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 3441; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3442; CHECK-NEXT: ret i32 [[ADD]] 3443; 3444 %a_sq = mul nsw i32 %a, %a 3445 %two_a = shl i32 %a, 1 3446 %two_a_plus_b = add i32 %b, %two_a 3447 %mul = mul i32 %two_a_plus_b, %b 3448 %add = add i32 %mul, %a_sq 3449 ret i32 %add 3450} 3451 3452define i32 @add_reduce_sqr_sum_order2(i32 %a, i32 %b) { 3453; CHECK-LABEL: @add_reduce_sqr_sum_order2( 3454; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 3455; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3456; CHECK-NEXT: ret i32 [[AB2]] 3457; 3458 %a_sq = mul nsw i32 %a, %a 3459 %twoa = mul i32 %a, 2 3460 %twoab = mul i32 %twoa, %b 3461 %b_sq = mul i32 %b, %b 3462 %twoab_b2 = add i32 %twoab, %b_sq 3463 %ab2 = add i32 %a_sq, %twoab_b2 3464 ret i32 %ab2 3465} 3466 3467define i32 @add_reduce_sqr_sum_order2_flipped(i32 %a, i32 %b) { 3468; CHECK-LABEL: @add_reduce_sqr_sum_order2_flipped( 3469; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 3470; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3471; CHECK-NEXT: ret i32 [[AB2]] 3472; 3473 %a_sq = mul nsw i32 %a, %a 3474 %twoa = mul i32 %a, 2 3475 %twoab = mul i32 %twoa, %b 3476 %b_sq = mul i32 %b, %b 3477 %twoab_b2 = add i32 %twoab, %b_sq 3478 %ab2 = add i32 %twoab_b2, %a_sq 3479 ret i32 %ab2 3480} 3481 3482define i32 @add_reduce_sqr_sum_order2_flipped2(i32 %a, i32 %bx) { 3483; CHECK-LABEL: @add_reduce_sqr_sum_order2_flipped2( 3484; CHECK-NEXT: [[B:%.*]] = xor i32 [[BX:%.*]], 42 3485; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B]] 3486; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3487; CHECK-NEXT: ret i32 [[AB2]] 3488; 3489 %b = xor i32 %bx, 42 ; thwart complexity-based canonicalization 3490 %a_sq = mul nsw i32 %a, %a 3491 %twoa = mul i32 %a, 2 3492 %twoab = mul i32 %twoa, %b 3493 %b_sq = mul i32 %b, %b 3494 %twoab_b2 = add i32 %b_sq, %twoab 3495 %ab2 = add i32 %a_sq, %twoab_b2 3496 ret i32 %ab2 3497} 3498 3499define i32 @add_reduce_sqr_sum_order2_flipped3(i32 %a, i32 %bx) { 3500; CHECK-LABEL: @add_reduce_sqr_sum_order2_flipped3( 3501; CHECK-NEXT: [[B:%.*]] = xor i32 [[BX:%.*]], 42 3502; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B]] 3503; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3504; CHECK-NEXT: ret i32 [[AB2]] 3505; 3506 %b = xor i32 %bx, 42 ; thwart complexity-based canonicalization 3507 %a_sq = mul nsw i32 %a, %a 3508 %twoa = mul i32 %a, 2 3509 %twoab = mul i32 %b, %twoa 3510 %b_sq = mul i32 %b, %b 3511 %twoab_b2 = add i32 %twoab, %b_sq 3512 %ab2 = add i32 %a_sq, %twoab_b2 3513 ret i32 %ab2 3514} 3515 3516define i32 @add_reduce_sqr_sum_order3(i32 %a, i32 %b) { 3517; CHECK-LABEL: @add_reduce_sqr_sum_order3( 3518; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 3519; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3520; CHECK-NEXT: ret i32 [[AB2]] 3521; 3522 %a_sq = mul nsw i32 %a, %a 3523 %twoa = mul i32 %a, 2 3524 %twoab = mul i32 %twoa, %b 3525 %b_sq = mul i32 %b, %b 3526 %a2_b2 = add i32 %a_sq, %b_sq 3527 %ab2 = add i32 %twoab, %a2_b2 3528 ret i32 %ab2 3529} 3530 3531define i32 @add_reduce_sqr_sum_order3_flipped(i32 %a, i32 %b) { 3532; CHECK-LABEL: @add_reduce_sqr_sum_order3_flipped( 3533; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 3534; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3535; CHECK-NEXT: ret i32 [[AB2]] 3536; 3537 %a_sq = mul nsw i32 %a, %a 3538 %twoa = mul i32 %a, 2 3539 %twoab = mul i32 %twoa, %b 3540 %b_sq = mul i32 %b, %b 3541 %a2_b2 = add i32 %a_sq, %b_sq 3542 %ab2 = add i32 %a2_b2, %twoab 3543 ret i32 %ab2 3544} 3545 3546define i32 @add_reduce_sqr_sum_order3_flipped2(i32 %a, i32 %b) { 3547; CHECK-LABEL: @add_reduce_sqr_sum_order3_flipped2( 3548; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 3549; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3550; CHECK-NEXT: ret i32 [[AB2]] 3551; 3552 %a_sq = mul nsw i32 %a, %a 3553 %twoa = mul i32 %a, 2 3554 %twoab = mul i32 %twoa, %b 3555 %b_sq = mul i32 %b, %b 3556 %a2_b2 = add i32 %b_sq, %a_sq 3557 %ab2 = add i32 %twoab, %a2_b2 3558 ret i32 %ab2 3559} 3560 3561define i32 @add_reduce_sqr_sum_order3_flipped3(i32 %a, i32 %b) { 3562; CHECK-LABEL: @add_reduce_sqr_sum_order3_flipped3( 3563; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 3564; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3565; CHECK-NEXT: ret i32 [[AB2]] 3566; 3567 %a_sq = mul nsw i32 %a, %a 3568 %twoa = mul i32 %a, 2 3569 %twoab = mul i32 %b, %twoa 3570 %b_sq = mul i32 %b, %b 3571 %a2_b2 = add i32 %a_sq, %b_sq 3572 %ab2 = add i32 %twoab, %a2_b2 3573 ret i32 %ab2 3574} 3575 3576define i32 @add_reduce_sqr_sum_order4(i32 %a, i32 %b) { 3577; CHECK-LABEL: @add_reduce_sqr_sum_order4( 3578; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 3579; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3580; CHECK-NEXT: ret i32 [[AB2]] 3581; 3582 %a_sq = mul nsw i32 %a, %a 3583 %ab = mul i32 %a, %b 3584 %twoab = mul i32 %ab, 2 3585 %b_sq = mul i32 %b, %b 3586 %a2_b2 = add i32 %a_sq, %b_sq 3587 %ab2 = add i32 %twoab, %a2_b2 3588 ret i32 %ab2 3589} 3590 3591define i32 @add_reduce_sqr_sum_order4_flipped(i32 %a, i32 %b) { 3592; CHECK-LABEL: @add_reduce_sqr_sum_order4_flipped( 3593; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 3594; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3595; CHECK-NEXT: ret i32 [[AB2]] 3596; 3597 %a_sq = mul nsw i32 %a, %a 3598 %ab = mul i32 %a, %b 3599 %twoab = mul i32 %ab, 2 3600 %b_sq = mul i32 %b, %b 3601 %a2_b2 = add i32 %a_sq, %b_sq 3602 %ab2 = add i32 %a2_b2, %twoab 3603 ret i32 %ab2 3604} 3605 3606define i32 @add_reduce_sqr_sum_order4_flipped2(i32 %a, i32 %b) { 3607; CHECK-LABEL: @add_reduce_sqr_sum_order4_flipped2( 3608; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 3609; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3610; CHECK-NEXT: ret i32 [[AB2]] 3611; 3612 %a_sq = mul nsw i32 %a, %a 3613 %ab = mul i32 %a, %b 3614 %twoab = mul i32 %ab, 2 3615 %b_sq = mul i32 %b, %b 3616 %a2_b2 = add i32 %b_sq, %a_sq 3617 %ab2 = add i32 %twoab, %a2_b2 3618 ret i32 %ab2 3619} 3620 3621define i32 @add_reduce_sqr_sum_order4_flipped3(i32 %a, i32 %b) { 3622; CHECK-LABEL: @add_reduce_sqr_sum_order4_flipped3( 3623; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 3624; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3625; CHECK-NEXT: ret i32 [[AB2]] 3626; 3627 %a_sq = mul nsw i32 %a, %a 3628 %ab = mul i32 %a, %b 3629 %twoab = mul i32 2, %ab 3630 %b_sq = mul i32 %b, %b 3631 %a2_b2 = add i32 %a_sq, %b_sq 3632 %ab2 = add i32 %twoab, %a2_b2 3633 ret i32 %ab2 3634} 3635 3636define i32 @add_reduce_sqr_sum_order4_flipped4(i32 %a, i32 %b) { 3637; CHECK-LABEL: @add_reduce_sqr_sum_order4_flipped4( 3638; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]] 3639; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3640; CHECK-NEXT: ret i32 [[AB2]] 3641; 3642 %a_sq = mul nsw i32 %a, %a 3643 %ab = mul i32 %b, %a 3644 %twoab = mul i32 %ab, 2 3645 %b_sq = mul i32 %b, %b 3646 %a2_b2 = add i32 %a_sq, %b_sq 3647 %ab2 = add i32 %twoab, %a2_b2 3648 ret i32 %ab2 3649} 3650 3651define i32 @add_reduce_sqr_sum_order5(i32 %a, i32 %b) { 3652; CHECK-LABEL: @add_reduce_sqr_sum_order5( 3653; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]] 3654; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3655; CHECK-NEXT: ret i32 [[AB2]] 3656; 3657 %a_sq = mul nsw i32 %a, %a 3658 %twob = mul i32 %b, 2 3659 %twoab = mul i32 %twob, %a 3660 %b_sq = mul i32 %b, %b 3661 %a2_b2 = add i32 %a_sq, %b_sq 3662 %ab2 = add i32 %twoab, %a2_b2 3663 ret i32 %ab2 3664} 3665 3666define i32 @add_reduce_sqr_sum_order5_flipped(i32 %a, i32 %b) { 3667; CHECK-LABEL: @add_reduce_sqr_sum_order5_flipped( 3668; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]] 3669; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3670; CHECK-NEXT: ret i32 [[AB2]] 3671; 3672 %a_sq = mul nsw i32 %a, %a 3673 %twob = mul i32 %b, 2 3674 %twoab = mul i32 %twob, %a 3675 %b_sq = mul i32 %b, %b 3676 %a2_b2 = add i32 %a_sq, %b_sq 3677 %ab2 = add i32 %a2_b2, %twoab 3678 ret i32 %ab2 3679} 3680 3681define i32 @add_reduce_sqr_sum_order5_flipped2(i32 %a, i32 %b) { 3682; CHECK-LABEL: @add_reduce_sqr_sum_order5_flipped2( 3683; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]] 3684; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3685; CHECK-NEXT: ret i32 [[AB2]] 3686; 3687 %a_sq = mul nsw i32 %a, %a 3688 %twob = mul i32 %b, 2 3689 %twoab = mul i32 %twob, %a 3690 %b_sq = mul i32 %b, %b 3691 %a2_b2 = add i32 %b_sq, %a_sq 3692 %ab2 = add i32 %twoab, %a2_b2 3693 ret i32 %ab2 3694} 3695 3696define i32 @add_reduce_sqr_sum_order5_flipped3(i32 %ax, i32 %b) { 3697; CHECK-LABEL: @add_reduce_sqr_sum_order5_flipped3( 3698; CHECK-NEXT: [[A:%.*]] = xor i32 [[AX:%.*]], 42 3699; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], [[A]] 3700; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3701; CHECK-NEXT: ret i32 [[AB2]] 3702; 3703 %a = xor i32 %ax, 42 ; thwart complexity-based canonicalization 3704 %a_sq = mul nsw i32 %a, %a 3705 %twob = mul i32 %b, 2 3706 %twoab = mul i32 %a, %twob 3707 %b_sq = mul i32 %b, %b 3708 %a2_b2 = add i32 %a_sq, %b_sq 3709 %ab2 = add i32 %twoab, %a2_b2 3710 ret i32 %ab2 3711} 3712 3713define i32 @add_reduce_sqr_sum_order5_flipped4(i32 %a, i32 %b) { 3714; CHECK-LABEL: @add_reduce_sqr_sum_order5_flipped4( 3715; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]] 3716; CHECK-NEXT: [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]] 3717; CHECK-NEXT: ret i32 [[AB2]] 3718; 3719 %a_sq = mul nsw i32 %a, %a 3720 %twob = mul i32 2, %b 3721 %twoab = mul i32 %twob, %a 3722 %b_sq = mul i32 %b, %b 3723 %a2_b2 = add i32 %a_sq, %b_sq 3724 %ab2 = add i32 %twoab, %a2_b2 3725 ret i32 %ab2 3726} 3727 3728define i32 @add_reduce_sqr_sum_not_one_use(i32 %a, i32 %b) { 3729; CHECK-LABEL: @add_reduce_sqr_sum_not_one_use( 3730; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]] 3731; CHECK-NEXT: [[TWO_A:%.*]] = shl i32 [[A]], 1 3732; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = add i32 [[TWO_A]], [[B:%.*]] 3733; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TWO_A_PLUS_B]], [[B]] 3734; CHECK-NEXT: tail call void @fake_func(i32 [[MUL]]) 3735; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]] 3736; CHECK-NEXT: ret i32 [[ADD]] 3737; 3738 %a_sq = mul nsw i32 %a, %a 3739 %two_a = shl i32 %a, 1 3740 %two_a_plus_b = add i32 %two_a, %b 3741 %mul = mul i32 %two_a_plus_b, %b 3742 tail call void @fake_func (i32 %mul) 3743 %add = add i32 %mul, %a_sq 3744 ret i32 %add 3745} 3746 3747define i32 @add_reduce_sqr_sum_not_one_use2(i32 %a, i32 %b) { 3748; CHECK-LABEL: @add_reduce_sqr_sum_not_one_use2( 3749; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]] 3750; CHECK-NEXT: [[TWO_A:%.*]] = shl i32 [[A]], 1 3751; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = add i32 [[TWO_A]], [[B:%.*]] 3752; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TWO_A_PLUS_B]], [[B]] 3753; CHECK-NEXT: tail call void @fake_func(i32 [[A_SQ]]) 3754; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]] 3755; CHECK-NEXT: ret i32 [[ADD]] 3756; 3757 %a_sq = mul nsw i32 %a, %a 3758 %two_a = shl i32 %a, 1 3759 %two_a_plus_b = add i32 %two_a, %b 3760 %mul = mul i32 %two_a_plus_b, %b 3761 tail call void @fake_func (i32 %a_sq) 3762 %add = add i32 %mul, %a_sq 3763 ret i32 %add 3764} 3765 3766define i32 @add_reduce_sqr_sum_order2_not_one_use(i32 %a, i32 %b) { 3767; CHECK-LABEL: @add_reduce_sqr_sum_order2_not_one_use( 3768; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]] 3769; CHECK-NEXT: [[TWOA:%.*]] = shl i32 [[A]], 1 3770; CHECK-NEXT: [[TWOAB1:%.*]] = add i32 [[TWOA]], [[B:%.*]] 3771; CHECK-NEXT: [[TWOAB_B2:%.*]] = mul i32 [[TWOAB1]], [[B]] 3772; CHECK-NEXT: tail call void @fake_func(i32 [[TWOAB_B2]]) 3773; CHECK-NEXT: [[AB2:%.*]] = add i32 [[A_SQ]], [[TWOAB_B2]] 3774; CHECK-NEXT: ret i32 [[AB2]] 3775; 3776 %a_sq = mul nsw i32 %a, %a 3777 %twoa = mul i32 %a, 2 3778 %twoab = mul i32 %twoa, %b 3779 %b_sq = mul i32 %b, %b 3780 %twoab_b2 = add i32 %twoab, %b_sq 3781 tail call void @fake_func (i32 %twoab_b2) 3782 %ab2 = add i32 %a_sq, %twoab_b2 3783 ret i32 %ab2 3784} 3785 3786define i32 @add_reduce_sqr_sum_order2_not_one_use2(i32 %a, i32 %b) { 3787; CHECK-LABEL: @add_reduce_sqr_sum_order2_not_one_use2( 3788; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]] 3789; CHECK-NEXT: [[TWOA:%.*]] = shl i32 [[A]], 1 3790; CHECK-NEXT: [[TWOAB1:%.*]] = add i32 [[TWOA]], [[B:%.*]] 3791; CHECK-NEXT: [[TWOAB_B2:%.*]] = mul i32 [[TWOAB1]], [[B]] 3792; CHECK-NEXT: tail call void @fake_func(i32 [[A_SQ]]) 3793; CHECK-NEXT: [[AB2:%.*]] = add i32 [[A_SQ]], [[TWOAB_B2]] 3794; CHECK-NEXT: ret i32 [[AB2]] 3795; 3796 %a_sq = mul nsw i32 %a, %a 3797 %twoa = mul i32 %a, 2 3798 %twoab = mul i32 %twoa, %b 3799 %b_sq = mul i32 %b, %b 3800 %twoab_b2 = add i32 %twoab, %b_sq 3801 tail call void @fake_func (i32 %a_sq) 3802 %ab2 = add i32 %a_sq, %twoab_b2 3803 ret i32 %ab2 3804} 3805 3806define i32 @add_reduce_sqr_sum_order3_not_one_use(i32 %a, i32 %b) { 3807; CHECK-LABEL: @add_reduce_sqr_sum_order3_not_one_use( 3808; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]] 3809; CHECK-NEXT: [[TWOA:%.*]] = shl i32 [[A]], 1 3810; CHECK-NEXT: [[TWOAB:%.*]] = mul i32 [[TWOA]], [[B:%.*]] 3811; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]] 3812; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]] 3813; CHECK-NEXT: tail call void @fake_func(i32 [[TWOAB]]) 3814; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]] 3815; CHECK-NEXT: ret i32 [[AB2]] 3816; 3817 %a_sq = mul nsw i32 %a, %a 3818 %twoa = mul i32 %a, 2 3819 %twoab = mul i32 %twoa, %b 3820 %b_sq = mul i32 %b, %b 3821 %a2_b2 = add i32 %a_sq, %b_sq 3822 tail call void @fake_func (i32 %twoab) 3823 %ab2 = add i32 %twoab, %a2_b2 3824 ret i32 %ab2 3825} 3826 3827define i32 @add_reduce_sqr_sum_order3_not_one_use2(i32 %a, i32 %b) { 3828; CHECK-LABEL: @add_reduce_sqr_sum_order3_not_one_use2( 3829; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]] 3830; CHECK-NEXT: [[TWOA:%.*]] = shl i32 [[A]], 1 3831; CHECK-NEXT: [[TWOAB:%.*]] = mul i32 [[TWOA]], [[B:%.*]] 3832; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]] 3833; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]] 3834; CHECK-NEXT: tail call void @fake_func(i32 [[A2_B2]]) 3835; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]] 3836; CHECK-NEXT: ret i32 [[AB2]] 3837; 3838 %a_sq = mul nsw i32 %a, %a 3839 %twoa = mul i32 %a, 2 3840 %twoab = mul i32 %twoa, %b 3841 %b_sq = mul i32 %b, %b 3842 %a2_b2 = add i32 %a_sq, %b_sq 3843 tail call void @fake_func (i32 %a2_b2) 3844 %ab2 = add i32 %twoab, %a2_b2 3845 ret i32 %ab2 3846} 3847 3848define i32 @add_reduce_sqr_sum_order4_not_one_use(i32 %a, i32 %b) { 3849; CHECK-LABEL: @add_reduce_sqr_sum_order4_not_one_use( 3850; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]] 3851; CHECK-NEXT: [[AB:%.*]] = mul i32 [[A]], [[B:%.*]] 3852; CHECK-NEXT: [[TWOAB:%.*]] = shl i32 [[AB]], 1 3853; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]] 3854; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]] 3855; CHECK-NEXT: tail call void @fake_func(i32 [[TWOAB]]) 3856; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]] 3857; CHECK-NEXT: ret i32 [[AB2]] 3858; 3859 %a_sq = mul nsw i32 %a, %a 3860 %ab = mul i32 %a, %b 3861 %twoab = mul i32 %ab, 2 3862 %b_sq = mul i32 %b, %b 3863 %a2_b2 = add i32 %a_sq, %b_sq 3864 tail call void @fake_func (i32 %twoab) 3865 %ab2 = add i32 %twoab, %a2_b2 3866 ret i32 %ab2 3867} 3868 3869define i32 @add_reduce_sqr_sum_order4_not_one_use2(i32 %a, i32 %b) { 3870; CHECK-LABEL: @add_reduce_sqr_sum_order4_not_one_use2( 3871; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]] 3872; CHECK-NEXT: [[AB:%.*]] = mul i32 [[A]], [[B:%.*]] 3873; CHECK-NEXT: [[TWOAB:%.*]] = shl i32 [[AB]], 1 3874; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]] 3875; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]] 3876; CHECK-NEXT: tail call void @fake_func(i32 [[A2_B2]]) 3877; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]] 3878; CHECK-NEXT: ret i32 [[AB2]] 3879; 3880 %a_sq = mul nsw i32 %a, %a 3881 %ab = mul i32 %a, %b 3882 %twoab = mul i32 %ab, 2 3883 %b_sq = mul i32 %b, %b 3884 %a2_b2 = add i32 %a_sq, %b_sq 3885 tail call void @fake_func (i32 %a2_b2) 3886 %ab2 = add i32 %twoab, %a2_b2 3887 ret i32 %ab2 3888} 3889 3890define i32 @add_reduce_sqr_sum_order5_not_one_use(i32 %a, i32 %b) { 3891; CHECK-LABEL: @add_reduce_sqr_sum_order5_not_one_use( 3892; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]] 3893; CHECK-NEXT: [[TWOB:%.*]] = shl i32 [[B:%.*]], 1 3894; CHECK-NEXT: [[TWOAB:%.*]] = mul i32 [[TWOB]], [[A]] 3895; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]] 3896; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]] 3897; CHECK-NEXT: tail call void @fake_func(i32 [[TWOAB]]) 3898; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]] 3899; CHECK-NEXT: ret i32 [[AB2]] 3900; 3901 %a_sq = mul nsw i32 %a, %a 3902 %twob = mul i32 %b, 2 3903 %twoab = mul i32 %twob, %a 3904 %b_sq = mul i32 %b, %b 3905 %a2_b2 = add i32 %a_sq, %b_sq 3906 tail call void @fake_func (i32 %twoab) 3907 %ab2 = add i32 %twoab, %a2_b2 3908 ret i32 %ab2 3909} 3910 3911define i32 @add_reduce_sqr_sum_order5_not_one_use2(i32 %a, i32 %b) { 3912; CHECK-LABEL: @add_reduce_sqr_sum_order5_not_one_use2( 3913; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]] 3914; CHECK-NEXT: [[TWOB:%.*]] = shl i32 [[B:%.*]], 1 3915; CHECK-NEXT: [[TWOAB:%.*]] = mul i32 [[TWOB]], [[A]] 3916; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]] 3917; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]] 3918; CHECK-NEXT: tail call void @fake_func(i32 [[A2_B2]]) 3919; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]] 3920; CHECK-NEXT: ret i32 [[AB2]] 3921; 3922 %a_sq = mul nsw i32 %a, %a 3923 %twob = mul i32 %b, 2 3924 %twoab = mul i32 %twob, %a 3925 %b_sq = mul i32 %b, %b 3926 %a2_b2 = add i32 %a_sq, %b_sq 3927 tail call void @fake_func (i32 %a2_b2) 3928 %ab2 = add i32 %twoab, %a2_b2 3929 ret i32 %ab2 3930} 3931 3932define i32 @add_reduce_sqr_sum_invalid0(i32 %a, i32 %b) { 3933; CHECK-LABEL: @add_reduce_sqr_sum_invalid0( 3934; CHECK-NEXT: [[TWO_A:%.*]] = shl i32 [[A:%.*]], 1 3935; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = add i32 [[TWO_A]], [[B:%.*]] 3936; CHECK-NEXT: [[MUL1:%.*]] = add i32 [[TWO_A_PLUS_B]], [[A]] 3937; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[MUL1]], [[B]] 3938; CHECK-NEXT: ret i32 [[ADD]] 3939; 3940 %not_a_sq = mul nsw i32 %a, %b 3941 %two_a = shl i32 %a, 1 3942 %two_a_plus_b = add i32 %two_a, %b 3943 %mul = mul i32 %two_a_plus_b, %b 3944 %add = add i32 %mul, %not_a_sq 3945 ret i32 %add 3946} 3947 3948define i32 @add_reduce_sqr_sum_invalid1(i32 %a, i32 %b) { 3949; CHECK-LABEL: @add_reduce_sqr_sum_invalid1( 3950; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]] 3951; CHECK-NEXT: [[NOT_TWO_A_PLUS_B:%.*]] = mul i32 [[A]], 3 3952; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[NOT_TWO_A_PLUS_B]], [[B:%.*]] 3953; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]] 3954; CHECK-NEXT: ret i32 [[ADD]] 3955; 3956 %a_sq = mul nsw i32 %a, %a 3957 %two_a = shl i32 %a, 1 3958 %not_two_a_plus_b = add i32 %two_a, %a 3959 %mul = mul i32 %not_two_a_plus_b, %b 3960 %add = add i32 %mul, %a_sq 3961 ret i32 %add 3962} 3963 3964define i32 @add_reduce_sqr_sum_invalid2(i32 %a, i32 %b) { 3965; CHECK-LABEL: @add_reduce_sqr_sum_invalid2( 3966; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]] 3967; CHECK-NEXT: [[NOT_TWO_A:%.*]] = shl i32 [[A]], 2 3968; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = add i32 [[NOT_TWO_A]], [[B:%.*]] 3969; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TWO_A_PLUS_B]], [[B]] 3970; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]] 3971; CHECK-NEXT: ret i32 [[ADD]] 3972; 3973 %a_sq = mul nsw i32 %a, %a 3974 %not_two_a = shl i32 %a, 2 3975 %two_a_plus_b = add i32 %not_two_a, %b 3976 %mul = mul i32 %two_a_plus_b, %b 3977 %add = add i32 %mul, %a_sq 3978 ret i32 %add 3979} 3980 3981define i32 @add_reduce_sqr_sum_invalid3(i32 %a, i32 %b) { 3982; CHECK-LABEL: @add_reduce_sqr_sum_invalid3( 3983; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = mul i32 [[B:%.*]], 3 3984; CHECK-NEXT: [[MUL1:%.*]] = add i32 [[TWO_A_PLUS_B]], [[A:%.*]] 3985; CHECK-NEXT: [[ADD:%.*]] = mul i32 [[MUL1]], [[A]] 3986; CHECK-NEXT: ret i32 [[ADD]] 3987; 3988 %a_sq = mul nsw i32 %a, %a 3989 %not_two_a = shl i32 %b, 1 3990 %two_a_plus_b = add i32 %not_two_a, %b 3991 %mul = mul i32 %two_a_plus_b, %a 3992 %add = add i32 %mul, %a_sq 3993 ret i32 %add 3994} 3995 3996define i32 @add_reduce_sqr_sum_invalid4(i32 %a, i32 %b) { 3997; CHECK-LABEL: @add_reduce_sqr_sum_invalid4( 3998; CHECK-NEXT: [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]] 3999; CHECK-NEXT: [[TWO_A_PLUS_B:%.*]] = mul i32 [[B:%.*]], 3 4000; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TWO_A_PLUS_B]], [[B]] 4001; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]] 4002; CHECK-NEXT: ret i32 [[ADD]] 4003; 4004 %a_sq = mul nsw i32 %a, %a 4005 %not_two_a = shl i32 %b, 1 4006 %two_a_plus_b = add i32 %not_two_a, %b 4007 %mul = mul i32 %two_a_plus_b, %b 4008 %add = add i32 %mul, %a_sq 4009 ret i32 %add 4010} 4011 4012define i32 @add_reduce_sqr_sum_varB_invalid0(i32 %a, i32 %b) { 4013; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid0( 4014; CHECK-NEXT: [[NOT_A_B:%.*]] = mul nsw i32 [[A:%.*]], [[A]] 4015; CHECK-NEXT: [[TWOAB:%.*]] = shl nuw i32 [[NOT_A_B]], 1 4016; CHECK-NEXT: [[A_SQ:%.*]] = mul i32 [[A]], [[A]] 4017; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B:%.*]], [[B]] 4018; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]] 4019; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]] 4020; CHECK-NEXT: ret i32 [[AB2]] 4021; 4022 %not_a_b = mul nsw i32 %a, %a 4023 %twoab = mul i32 %not_a_b, 2 4024 %a_sq = mul i32 %a, %a 4025 %b_sq = mul i32 %b, %b 4026 %a2_b2 = add i32 %a_sq, %b_sq 4027 %ab2 = add i32 %twoab, %a2_b2 4028 ret i32 %ab2 4029} 4030 4031define i32 @add_reduce_sqr_sum_varB_invalid1(i32 %a, i32 %b) { 4032; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid1( 4033; CHECK-NEXT: [[NOT_A_B:%.*]] = mul nsw i32 [[B:%.*]], [[B]] 4034; CHECK-NEXT: [[TWOAB:%.*]] = shl nuw i32 [[NOT_A_B]], 1 4035; CHECK-NEXT: [[A_SQ:%.*]] = mul i32 [[A:%.*]], [[A]] 4036; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]] 4037; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]] 4038; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]] 4039; CHECK-NEXT: ret i32 [[AB2]] 4040; 4041 %not_a_b = mul nsw i32 %b, %b 4042 %twoab = mul i32 %not_a_b, 2 4043 %a_sq = mul i32 %a, %a 4044 %b_sq = mul i32 %b, %b 4045 %a2_b2 = add i32 %a_sq, %b_sq 4046 %ab2 = add i32 %twoab, %a2_b2 4047 ret i32 %ab2 4048} 4049 4050define i32 @add_reduce_sqr_sum_varB_invalid2(i32 %a, i32 %b) { 4051; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid2( 4052; CHECK-NEXT: [[A_B:%.*]] = mul nsw i32 [[A:%.*]], [[B:%.*]] 4053; CHECK-NEXT: [[NOT_TWOAB:%.*]] = shl i32 [[A_B]], 2 4054; CHECK-NEXT: [[A_SQ:%.*]] = mul i32 [[A]], [[A]] 4055; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]] 4056; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]] 4057; CHECK-NEXT: [[AB2:%.*]] = add i32 [[NOT_TWOAB]], [[A2_B2]] 4058; CHECK-NEXT: ret i32 [[AB2]] 4059; 4060 %a_b = mul nsw i32 %a, %b 4061 %not_twoab = mul i32 %a_b, 4 4062 %a_sq = mul i32 %a, %a 4063 %b_sq = mul i32 %b, %b 4064 %a2_b2 = add i32 %a_sq, %b_sq 4065 %ab2 = add i32 %not_twoab, %a2_b2 4066 ret i32 %ab2 4067} 4068 4069define i32 @add_reduce_sqr_sum_varB_invalid3(i32 %a, i32 %b) { 4070; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid3( 4071; CHECK-NEXT: [[A_B:%.*]] = mul nsw i32 [[A:%.*]], [[B:%.*]] 4072; CHECK-NEXT: [[TWOAB:%.*]] = shl i32 [[A_B]], 1 4073; CHECK-NEXT: [[B_SQ1:%.*]] = add i32 [[A]], [[B]] 4074; CHECK-NEXT: [[A2_B2:%.*]] = mul i32 [[B]], [[B_SQ1]] 4075; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]] 4076; CHECK-NEXT: ret i32 [[AB2]] 4077; 4078 %a_b = mul nsw i32 %a, %b 4079 %twoab = mul i32 %a_b, 2 4080 %not_a_sq = mul i32 %b, %a 4081 %b_sq = mul i32 %b, %b 4082 %a2_b2 = add i32 %not_a_sq, %b_sq 4083 %ab2 = add i32 %twoab, %a2_b2 4084 ret i32 %ab2 4085} 4086 4087define i32 @add_reduce_sqr_sum_varB_invalid4(i32 %a, i32 %b) { 4088; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid4( 4089; CHECK-NEXT: [[A_B:%.*]] = mul nsw i32 [[A:%.*]], [[B:%.*]] 4090; CHECK-NEXT: [[TWOAB:%.*]] = shl i32 [[A_B]], 1 4091; CHECK-NEXT: [[NOT_B_SQ1:%.*]] = add i32 [[A]], [[B]] 4092; CHECK-NEXT: [[A2_B2:%.*]] = mul i32 [[A]], [[NOT_B_SQ1]] 4093; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]] 4094; CHECK-NEXT: ret i32 [[AB2]] 4095; 4096 %a_b = mul nsw i32 %a, %b 4097 %twoab = mul i32 %a_b, 2 4098 %a_sq = mul i32 %a, %a 4099 %not_b_sq = mul i32 %b, %a 4100 %a2_b2 = add i32 %a_sq, %not_b_sq 4101 %ab2 = add i32 %twoab, %a2_b2 4102 ret i32 %ab2 4103} 4104 4105define i32 @add_reduce_sqr_sum_varC_invalid0(i32 %a, i32 %b) { 4106; CHECK-LABEL: @add_reduce_sqr_sum_varC_invalid0( 4107; CHECK-NEXT: [[NOT_TWOA:%.*]] = shl nsw i32 [[B:%.*]], 1 4108; CHECK-NEXT: [[TWOAB:%.*]] = mul i32 [[NOT_TWOA]], [[B]] 4109; CHECK-NEXT: [[A_SQ:%.*]] = mul i32 [[A:%.*]], [[A]] 4110; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]] 4111; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]] 4112; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]] 4113; CHECK-NEXT: ret i32 [[AB2]] 4114; 4115 %not_twoa = mul nsw i32 %b, 2 4116 %twoab = mul i32 %not_twoa, %b 4117 %a_sq = mul i32 %a, %a 4118 %b_sq = mul i32 %b, %b 4119 %a2_b2 = add i32 %a_sq, %b_sq 4120 %ab2 = add i32 %twoab, %a2_b2 4121 ret i32 %ab2 4122} 4123 4124define i32 @add_reduce_sqr_sum_varC_invalid1(i32 %a, i32 %b) { 4125; CHECK-LABEL: @add_reduce_sqr_sum_varC_invalid1( 4126; CHECK-NEXT: [[NOT_TWOA:%.*]] = shl nsw i32 [[A:%.*]], 2 4127; CHECK-NEXT: [[TWOAB:%.*]] = mul i32 [[NOT_TWOA]], [[B:%.*]] 4128; CHECK-NEXT: [[A_SQ:%.*]] = mul i32 [[A]], [[A]] 4129; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B]], [[B]] 4130; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]] 4131; CHECK-NEXT: [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]] 4132; CHECK-NEXT: ret i32 [[AB2]] 4133; 4134 %not_twoa = mul nsw i32 %a, 4 4135 %twoab = mul i32 %not_twoa, %b 4136 %a_sq = mul i32 %a, %a 4137 %b_sq = mul i32 %b, %b 4138 %a2_b2 = add i32 %a_sq, %b_sq 4139 %ab2 = add i32 %twoab, %a2_b2 4140 ret i32 %ab2 4141} 4142 4143define i32 @add_reduce_sqr_sum_varC_invalid2(i32 %a, i32 %b) { 4144; CHECK-LABEL: @add_reduce_sqr_sum_varC_invalid2( 4145; CHECK-NEXT: [[TWOA:%.*]] = shl nsw i32 [[A:%.*]], 1 4146; CHECK-NEXT: [[NOT_TWOAB:%.*]] = mul i32 [[TWOA]], [[A]] 4147; CHECK-NEXT: [[A_SQ:%.*]] = mul i32 [[A]], [[A]] 4148; CHECK-NEXT: [[B_SQ:%.*]] = mul i32 [[B:%.*]], [[B]] 4149; CHECK-NEXT: [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]] 4150; CHECK-NEXT: [[AB2:%.*]] = add i32 [[NOT_TWOAB]], [[A2_B2]] 4151; CHECK-NEXT: ret i32 [[AB2]] 4152; 4153 %twoa = mul nsw i32 %a, 2 4154 %not_twoab = mul i32 %twoa, %a 4155 %a_sq = mul i32 %a, %a 4156 %b_sq = mul i32 %b, %b 4157 %a2_b2 = add i32 %a_sq, %b_sq 4158 %ab2 = add i32 %not_twoab, %a2_b2 4159 ret i32 %ab2 4160} 4161 4162define i32 @fold_sext_addition_or_disjoint(i8 %x) { 4163; CHECK-LABEL: @fold_sext_addition_or_disjoint( 4164; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32 4165; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[TMP1]], 1246 4166; CHECK-NEXT: ret i32 [[R]] 4167; 4168 %xx = or disjoint i8 %x, 12 4169 %se = sext i8 %xx to i32 4170 %r = add i32 %se, 1234 4171 ret i32 %r 4172} 4173 4174define i32 @fold_sext_addition_fail(i8 %x) { 4175; CHECK-LABEL: @fold_sext_addition_fail( 4176; CHECK-NEXT: [[XX:%.*]] = or i8 [[X:%.*]], 12 4177; CHECK-NEXT: [[SE:%.*]] = sext i8 [[XX]] to i32 4178; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[SE]], 1234 4179; CHECK-NEXT: ret i32 [[R]] 4180; 4181 %xx = or i8 %x, 12 4182 %se = sext i8 %xx to i32 4183 %r = add i32 %se, 1234 4184 ret i32 %r 4185} 4186 4187define i32 @fold_zext_addition_or_disjoint(i8 %x) { 4188; CHECK-LABEL: @fold_zext_addition_or_disjoint( 4189; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32 4190; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[TMP1]], 1246 4191; CHECK-NEXT: ret i32 [[R]] 4192; 4193 %xx = or disjoint i8 %x, 12 4194 %se = zext i8 %xx to i32 4195 %r = add i32 %se, 1234 4196 ret i32 %r 4197} 4198 4199define i32 @fold_zext_addition_or_disjoint2(i8 %x) { 4200; CHECK-LABEL: @fold_zext_addition_or_disjoint2( 4201; CHECK-NEXT: [[TMP1:%.*]] = add nuw i8 [[X:%.*]], 4 4202; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP1]] to i32 4203; CHECK-NEXT: ret i32 [[R]] 4204; 4205 %xx = or disjoint i8 %x, 18 4206 %se = zext i8 %xx to i32 4207 %r = add i32 %se, -14 4208 ret i32 %r 4209} 4210 4211define i32 @fold_zext_addition_fail(i8 %x) { 4212; CHECK-LABEL: @fold_zext_addition_fail( 4213; CHECK-NEXT: [[XX:%.*]] = or i8 [[X:%.*]], 12 4214; CHECK-NEXT: [[SE:%.*]] = zext i8 [[XX]] to i32 4215; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[SE]], 1234 4216; CHECK-NEXT: ret i32 [[R]] 4217; 4218 %xx = or i8 %x, 12 4219 %se = zext i8 %xx to i32 4220 %r = add i32 %se, 1234 4221 ret i32 %r 4222} 4223 4224define i32 @fold_zext_addition_fail2(i8 %x) { 4225; CHECK-LABEL: @fold_zext_addition_fail2( 4226; CHECK-NEXT: [[XX:%.*]] = or i8 [[X:%.*]], 18 4227; CHECK-NEXT: [[SE:%.*]] = zext i8 [[XX]] to i32 4228; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[SE]], -14 4229; CHECK-NEXT: ret i32 [[R]] 4230; 4231 %xx = or i8 %x, 18 4232 %se = zext i8 %xx to i32 4233 %r = add i32 %se, -14 4234 ret i32 %r 4235} 4236 4237define i32 @fold_zext_nneg_add_const(i8 %x) { 4238; CHECK-LABEL: @fold_zext_nneg_add_const( 4239; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32 4240; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[TMP1]], 98 4241; CHECK-NEXT: ret i32 [[R]] 4242; 4243 %xx = add nsw i8 %x, 123 4244 %ze = zext nneg i8 %xx to i32 4245 %r = add nsw i32 %ze, -25 4246 ret i32 %r 4247} 4248 4249define i32 @fold_zext_nneg_add_const_fail1(i8 %x) { 4250; CHECK-LABEL: @fold_zext_nneg_add_const_fail1( 4251; CHECK-NEXT: [[XX:%.*]] = add nsw i8 [[X:%.*]], 123 4252; CHECK-NEXT: [[ZE:%.*]] = zext i8 [[XX]] to i32 4253; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[ZE]], -25 4254; CHECK-NEXT: ret i32 [[R]] 4255; 4256 %xx = add nsw i8 %x, 123 4257 %ze = zext i8 %xx to i32 4258 %r = add nsw i32 %ze, -25 4259 ret i32 %r 4260} 4261 4262define i32 @fold_zext_nneg_add_const_fail2(i8 %x) { 4263; CHECK-LABEL: @fold_zext_nneg_add_const_fail2( 4264; CHECK-NEXT: [[XX:%.*]] = add i8 [[X:%.*]], 123 4265; CHECK-NEXT: [[ZE:%.*]] = zext nneg i8 [[XX]] to i32 4266; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[ZE]], -25 4267; CHECK-NEXT: ret i32 [[R]] 4268; 4269 %xx = add i8 %x, 123 4270 %ze = zext nneg i8 %xx to i32 4271 %r = add nsw i32 %ze, -25 4272 ret i32 %r 4273} 4274 4275declare void @llvm.assume(i1) 4276declare void @fake_func(i32) 4277