1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" 3 4; Optimize subtracts. 5; 6; RUN: opt < %s -instcombine -S | FileCheck %s 7 8define i32 @test1(i32 %A) { 9; CHECK-LABEL: @test1( 10; CHECK-NEXT: ret i32 0 11; 12 %B = sub i32 %A, %A 13 ret i32 %B 14} 15 16define i32 @test2(i32 %A) { 17; CHECK-LABEL: @test2( 18; CHECK-NEXT: ret i32 %A 19; 20 %B = sub i32 %A, 0 21 ret i32 %B 22} 23 24define i32 @test3(i32 %A) { 25; CHECK-LABEL: @test3( 26; CHECK-NEXT: ret i32 %A 27; 28 %B = sub i32 0, %A 29 %C = sub i32 0, %B 30 ret i32 %C 31} 32 33define i32 @test4(i32 %A, i32 %x) { 34; CHECK-LABEL: @test4( 35; CHECK-NEXT: [[C:%.*]] = add i32 %x, %A 36; CHECK-NEXT: ret i32 [[C]] 37; 38 %B = sub i32 0, %A 39 %C = sub i32 %x, %B 40 ret i32 %C 41} 42 43define i32 @test5(i32 %A, i32 %B, i32 %C) { 44; CHECK-LABEL: @test5( 45; CHECK-NEXT: [[D1:%.*]] = sub i32 %C, %B 46; CHECK-NEXT: [[E:%.*]] = add i32 [[D1]], %A 47; CHECK-NEXT: ret i32 [[E]] 48; 49 %D = sub i32 %B, %C 50 %E = sub i32 %A, %D 51 ret i32 %E 52} 53 54define i32 @test6(i32 %A, i32 %B) { 55; CHECK-LABEL: @test6( 56; CHECK-NEXT: [[B_NOT:%.*]] = xor i32 %B, -1 57; CHECK-NEXT: [[D:%.*]] = and i32 %A, [[B_NOT]] 58; CHECK-NEXT: ret i32 [[D]] 59; 60 %C = and i32 %A, %B 61 %D = sub i32 %A, %C 62 ret i32 %D 63} 64 65define i32 @test7(i32 %A) { 66; CHECK-LABEL: @test7( 67; CHECK-NEXT: [[B:%.*]] = xor i32 %A, -1 68; CHECK-NEXT: ret i32 [[B]] 69; 70 %B = sub i32 -1, %A 71 ret i32 %B 72} 73 74define i32 @test8(i32 %A) { 75; CHECK-LABEL: @test8( 76; CHECK-NEXT: [[C:%.*]] = shl i32 %A, 3 77; CHECK-NEXT: ret i32 [[C]] 78; 79 %B = mul i32 9, %A 80 %C = sub i32 %B, %A 81 ret i32 %C 82} 83 84define i32 @test9(i32 %A) { 85; CHECK-LABEL: @test9( 86; CHECK-NEXT: [[C:%.*]] = mul i32 %A, -2 87; CHECK-NEXT: ret i32 [[C]] 88; 89 %B = mul i32 3, %A 90 %C = sub i32 %A, %B 91 ret i32 %C 92} 93 94define i32 @test10(i32 %A, i32 %B) { 95; CHECK-LABEL: @test10( 96; CHECK-NEXT: [[E:%.*]] = mul i32 %A, %B 97; CHECK-NEXT: ret i32 [[E]] 98; 99 %C = sub i32 0, %A 100 %D = sub i32 0, %B 101 %E = mul i32 %C, %D 102 ret i32 %E 103} 104 105define i32 @test10a(i32 %A) { 106; CHECK-LABEL: @test10a( 107; CHECK-NEXT: [[E:%.*]] = mul i32 %A, -7 108; CHECK-NEXT: ret i32 [[E]] 109; 110 %C = sub i32 0, %A 111 %E = mul i32 %C, 7 112 ret i32 %E 113} 114 115define i1 @test11(i8 %A, i8 %B) { 116; CHECK-LABEL: @test11( 117; CHECK-NEXT: [[D:%.*]] = icmp ne i8 %A, %B 118; CHECK-NEXT: ret i1 [[D]] 119; 120 %C = sub i8 %A, %B 121 %D = icmp ne i8 %C, 0 122 ret i1 %D 123} 124 125define <2 x i1> @test11vec(<2 x i8> %A, <2 x i8> %B) { 126; CHECK-LABEL: @test11vec( 127; CHECK-NEXT: [[D:%.*]] = icmp ne <2 x i8> %A, %B 128; CHECK-NEXT: ret <2 x i1> [[D]] 129; 130 %C = sub <2 x i8> %A, %B 131 %D = icmp ne <2 x i8> %C, zeroinitializer 132 ret <2 x i1> %D 133} 134 135define i32 @test12(i32 %A) { 136; CHECK-LABEL: @test12( 137; CHECK-NEXT: [[C:%.*]] = lshr i32 %A, 31 138; CHECK-NEXT: ret i32 [[C]] 139; 140 %B = ashr i32 %A, 31 141 %C = sub i32 0, %B 142 ret i32 %C 143} 144 145define i32 @test13(i32 %A) { 146; CHECK-LABEL: @test13( 147; CHECK-NEXT: [[C:%.*]] = ashr i32 %A, 31 148; CHECK-NEXT: ret i32 [[C]] 149; 150 %B = lshr i32 %A, 31 151 %C = sub i32 0, %B 152 ret i32 %C 153} 154 155define <2 x i32> @test12vec(<2 x i32> %A) { 156; CHECK-LABEL: @test12vec( 157; CHECK-NEXT: [[C:%.*]] = lshr <2 x i32> %A, <i32 31, i32 31> 158; CHECK-NEXT: ret <2 x i32> [[C]] 159; 160 %B = ashr <2 x i32> %A, <i32 31, i32 31> 161 %C = sub <2 x i32> zeroinitializer, %B 162 ret <2 x i32> %C 163} 164 165define <2 x i32> @test13vec(<2 x i32> %A) { 166; CHECK-LABEL: @test13vec( 167; CHECK-NEXT: [[C:%.*]] = ashr <2 x i32> %A, <i32 31, i32 31> 168; CHECK-NEXT: ret <2 x i32> [[C]] 169; 170 %B = lshr <2 x i32> %A, <i32 31, i32 31> 171 %C = sub <2 x i32> zeroinitializer, %B 172 ret <2 x i32> %C 173} 174 175define i32 @test15(i32 %A, i32 %B) { 176; CHECK-LABEL: @test15( 177; CHECK-NEXT: [[C:%.*]] = sub i32 0, %A 178; CHECK-NEXT: [[D:%.*]] = srem i32 %B, [[C]] 179; CHECK-NEXT: ret i32 [[D]] 180; 181 %C = sub i32 0, %A 182 %D = srem i32 %B, %C 183 ret i32 %D 184} 185 186define i32 @test16(i32 %A) { 187; CHECK-LABEL: @test16( 188; CHECK-NEXT: [[Y:%.*]] = sdiv i32 %A, -1123 189; CHECK-NEXT: ret i32 [[Y]] 190; 191 %X = sdiv i32 %A, 1123 192 %Y = sub i32 0, %X 193 ret i32 %Y 194} 195 196; Can't fold subtract here because negation it might oveflow. 197; PR3142 198define i32 @test17(i32 %A) { 199; CHECK-LABEL: @test17( 200; CHECK-NEXT: [[B:%.*]] = sub i32 0, %A 201; CHECK-NEXT: [[C:%.*]] = sdiv i32 [[B]], 1234 202; CHECK-NEXT: ret i32 [[C]] 203; 204 %B = sub i32 0, %A 205 %C = sdiv i32 %B, 1234 206 ret i32 %C 207} 208 209define i64 @test18(i64 %Y) { 210; CHECK-LABEL: @test18( 211; CHECK-NEXT: ret i64 0 212; 213 %tmp.4 = shl i64 %Y, 2 214 %tmp.12 = shl i64 %Y, 2 215 %tmp.8 = sub i64 %tmp.4, %tmp.12 216 ret i64 %tmp.8 217} 218 219define i32 @test19(i32 %X, i32 %Y) { 220; CHECK-LABEL: @test19( 221; CHECK-NEXT: ret i32 %X 222; 223 %Z = sub i32 %X, %Y 224 %Q = add i32 %Z, %Y 225 ret i32 %Q 226} 227 228define i1 @test20(i32 %g, i32 %h) { 229; CHECK-LABEL: @test20( 230; CHECK-NEXT: [[TMP_4:%.*]] = icmp ne i32 %h, 0 231; CHECK-NEXT: ret i1 [[TMP_4]] 232; 233 %tmp.2 = sub i32 %g, %h 234 %tmp.4 = icmp ne i32 %tmp.2, %g 235 ret i1 %tmp.4 236} 237 238define i1 @test21(i32 %g, i32 %h) { 239; CHECK-LABEL: @test21( 240; CHECK-NEXT: [[TMP_4:%.*]] = icmp ne i32 %h, 0 241; CHECK-NEXT: ret i1 [[TMP_4]] 242; 243 %tmp.2 = sub i32 %g, %h 244 %tmp.4 = icmp ne i32 %tmp.2, %g 245 ret i1 %tmp.4 246} 247 248; PR2298 249define zeroext i1 @test22(i32 %a, i32 %b) nounwind { 250; CHECK-LABEL: @test22( 251; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 %b, %a 252; CHECK-NEXT: ret i1 [[TMP5]] 253; 254 %tmp2 = sub i32 0, %a 255 %tmp4 = sub i32 0, %b 256 %tmp5 = icmp eq i32 %tmp2, %tmp4 257 ret i1 %tmp5 258} 259 260; rdar://7362831 261define i32 @test23(i8* %P, i64 %A){ 262; CHECK-LABEL: @test23( 263; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 %A to i32 264; CHECK-NEXT: ret i32 [[TMP1]] 265; 266 %B = getelementptr inbounds i8, i8* %P, i64 %A 267 %C = ptrtoint i8* %B to i64 268 %D = trunc i64 %C to i32 269 %E = ptrtoint i8* %P to i64 270 %F = trunc i64 %E to i32 271 %G = sub i32 %D, %F 272 ret i32 %G 273} 274 275define i8 @test23_as1(i8 addrspace(1)* %P, i16 %A) { 276; CHECK-LABEL: @test23_as1( 277; CHECK-NEXT: [[TMP1:%.*]] = trunc i16 %A to i8 278; CHECK-NEXT: ret i8 [[TMP1]] 279; 280 %B = getelementptr inbounds i8, i8 addrspace(1)* %P, i16 %A 281 %C = ptrtoint i8 addrspace(1)* %B to i16 282 %D = trunc i16 %C to i8 283 %E = ptrtoint i8 addrspace(1)* %P to i16 284 %F = trunc i16 %E to i8 285 %G = sub i8 %D, %F 286 ret i8 %G 287} 288 289define i64 @test24(i8* %P, i64 %A){ 290; CHECK-LABEL: @test24( 291; CHECK-NEXT: ret i64 %A 292; 293 %B = getelementptr inbounds i8, i8* %P, i64 %A 294 %C = ptrtoint i8* %B to i64 295 %E = ptrtoint i8* %P to i64 296 %G = sub i64 %C, %E 297 ret i64 %G 298} 299 300define i16 @test24_as1(i8 addrspace(1)* %P, i16 %A) { 301; CHECK-LABEL: @test24_as1( 302; CHECK-NEXT: ret i16 %A 303; 304 %B = getelementptr inbounds i8, i8 addrspace(1)* %P, i16 %A 305 %C = ptrtoint i8 addrspace(1)* %B to i16 306 %E = ptrtoint i8 addrspace(1)* %P to i16 307 %G = sub i16 %C, %E 308 ret i16 %G 309} 310 311define i64 @test24a(i8* %P, i64 %A){ 312; CHECK-LABEL: @test24a( 313; CHECK-NEXT: [[DIFF_NEG:%.*]] = sub i64 0, %A 314; CHECK-NEXT: ret i64 [[DIFF_NEG]] 315; 316 %B = getelementptr inbounds i8, i8* %P, i64 %A 317 %C = ptrtoint i8* %B to i64 318 %E = ptrtoint i8* %P to i64 319 %G = sub i64 %E, %C 320 ret i64 %G 321} 322 323define i16 @test24a_as1(i8 addrspace(1)* %P, i16 %A) { 324; CHECK-LABEL: @test24a_as1( 325; CHECK-NEXT: [[DIFF_NEG:%.*]] = sub i16 0, %A 326; CHECK-NEXT: ret i16 [[DIFF_NEG]] 327; 328 %B = getelementptr inbounds i8, i8 addrspace(1)* %P, i16 %A 329 %C = ptrtoint i8 addrspace(1)* %B to i16 330 %E = ptrtoint i8 addrspace(1)* %P to i16 331 %G = sub i16 %E, %C 332 ret i16 %G 333} 334 335 336@Arr = external global [42 x i16] 337 338define i64 @test24b(i8* %P, i64 %A){ 339; CHECK-LABEL: @test24b( 340; CHECK-NEXT: [[B_IDX:%.*]] = shl nuw i64 %A, 1 341; CHECK-NEXT: ret i64 [[B_IDX]] 342; 343 %B = getelementptr inbounds [42 x i16], [42 x i16]* @Arr, i64 0, i64 %A 344 %C = ptrtoint i16* %B to i64 345 %G = sub i64 %C, ptrtoint ([42 x i16]* @Arr to i64) 346 ret i64 %G 347} 348 349 350define i64 @test25(i8* %P, i64 %A){ 351; CHECK-LABEL: @test25( 352; CHECK-NEXT: [[B_IDX:%.*]] = shl nuw i64 %A, 1 353; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B_IDX]], -84 354; CHECK-NEXT: ret i64 [[TMP1]] 355; 356 %B = getelementptr inbounds [42 x i16], [42 x i16]* @Arr, i64 0, i64 %A 357 %C = ptrtoint i16* %B to i64 358 %G = sub i64 %C, ptrtoint (i16* getelementptr ([42 x i16], [42 x i16]* @Arr, i64 1, i64 0) to i64) 359 ret i64 %G 360} 361 362@Arr_as1 = external addrspace(1) global [42 x i16] 363 364define i16 @test25_as1(i8 addrspace(1)* %P, i64 %A) { 365; CHECK-LABEL: @test25_as1( 366; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 %A to i16 367; CHECK-NEXT: [[B_IDX:%.*]] = shl nuw i16 [[TMP1]], 1 368; CHECK-NEXT: [[TMP2:%.*]] = add i16 [[B_IDX]], -84 369; CHECK-NEXT: ret i16 [[TMP2]] 370; 371 %B = getelementptr inbounds [42 x i16], [42 x i16] addrspace(1)* @Arr_as1, i64 0, i64 %A 372 %C = ptrtoint i16 addrspace(1)* %B to i16 373 %G = sub i16 %C, ptrtoint (i16 addrspace(1)* getelementptr ([42 x i16], [42 x i16] addrspace(1)* @Arr_as1, i64 1, i64 0) to i16) 374 ret i16 %G 375} 376 377define i32 @test26(i32 %x) { 378; CHECK-LABEL: @test26( 379; CHECK-NEXT: [[NEG:%.*]] = shl i32 -3, %x 380; CHECK-NEXT: ret i32 [[NEG]] 381; 382 %shl = shl i32 3, %x 383 %neg = sub i32 0, %shl 384 ret i32 %neg 385} 386 387define i32 @test27(i32 %x, i32 %y) { 388; CHECK-LABEL: @test27( 389; CHECK-NEXT: [[TMP1:%.*]] = shl i32 %y, 3 390; CHECK-NEXT: [[SUB:%.*]] = add i32 [[TMP1]], %x 391; CHECK-NEXT: ret i32 [[SUB]] 392; 393 %mul = mul i32 %y, -8 394 %sub = sub i32 %x, %mul 395 ret i32 %sub 396} 397 398define i32 @test28(i32 %x, i32 %y, i32 %z) { 399; CHECK-LABEL: @test28( 400; CHECK-NEXT: [[TMP1:%.*]] = mul i32 %z, %y 401; CHECK-NEXT: [[SUB:%.*]] = add i32 [[TMP1]], %x 402; CHECK-NEXT: ret i32 [[SUB]] 403; 404 %neg = sub i32 0, %z 405 %mul = mul i32 %neg, %y 406 %sub = sub i32 %x, %mul 407 ret i32 %sub 408} 409 410define i64 @test29(i8* %foo, i64 %i, i64 %j) { 411; CHECK-LABEL: @test29( 412; CHECK-NEXT: [[TMP1:%.*]] = sub i64 %i, %j 413; CHECK-NEXT: ret i64 [[TMP1]] 414; 415 %gep1 = getelementptr inbounds i8, i8* %foo, i64 %i 416 %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j 417 %cast1 = ptrtoint i8* %gep1 to i64 418 %cast2 = ptrtoint i8* %gep2 to i64 419 %sub = sub i64 %cast1, %cast2 420 ret i64 %sub 421} 422 423define i64 @test30(i8* %foo, i64 %i, i64 %j) { 424; CHECK-LABEL: @test30( 425; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nuw i64 %i, 2 426; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[GEP1_IDX]], %j 427; CHECK-NEXT: ret i64 [[TMP1]] 428; 429 %bit = bitcast i8* %foo to i32* 430 %gep1 = getelementptr inbounds i32, i32* %bit, i64 %i 431 %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j 432 %cast1 = ptrtoint i32* %gep1 to i64 433 %cast2 = ptrtoint i8* %gep2 to i64 434 %sub = sub i64 %cast1, %cast2 435 ret i64 %sub 436} 437 438define i16 @test30_as1(i8 addrspace(1)* %foo, i16 %i, i16 %j) { 439; CHECK-LABEL: @test30_as1( 440; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nuw i16 %i, 2 441; CHECK-NEXT: [[TMP1:%.*]] = sub i16 [[GEP1_IDX]], %j 442; CHECK-NEXT: ret i16 [[TMP1]] 443; 444 %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)* 445 %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i16 %i 446 %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i16 %j 447 %cast1 = ptrtoint i32 addrspace(1)* %gep1 to i16 448 %cast2 = ptrtoint i8 addrspace(1)* %gep2 to i16 449 %sub = sub i16 %cast1, %cast2 450 ret i16 %sub 451} 452 453define <2 x i64> @test31(<2 x i64> %A) { 454; CHECK-LABEL: @test31( 455; CHECK-NEXT: [[SUB:%.*]] = add <2 x i64> %A, <i64 3, i64 4> 456; CHECK-NEXT: ret <2 x i64> [[SUB]] 457; 458 %xor = xor <2 x i64> %A, <i64 -1, i64 -1> 459 %sub = sub <2 x i64> <i64 2, i64 3>, %xor 460 ret <2 x i64> %sub 461} 462 463define <2 x i64> @test32(<2 x i64> %A) { 464; CHECK-LABEL: @test32( 465; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i64> <i64 3, i64 4>, %A 466; CHECK-NEXT: ret <2 x i64> [[SUB]] 467; 468 %add = add <2 x i64> %A, <i64 -1, i64 -1> 469 %sub = sub <2 x i64> <i64 2, i64 3>, %add 470 ret <2 x i64> %sub 471} 472 473define <2 x i64> @test33(<2 x i1> %A) { 474; CHECK-LABEL: @test33( 475; CHECK-NEXT: [[SUB:%.*]] = sext <2 x i1> %A to <2 x i64> 476; CHECK-NEXT: ret <2 x i64> [[SUB]] 477; 478 %ext = zext <2 x i1> %A to <2 x i64> 479 %sub = sub <2 x i64> zeroinitializer, %ext 480 ret <2 x i64> %sub 481} 482 483define <2 x i64> @test34(<2 x i1> %A) { 484; CHECK-LABEL: @test34( 485; CHECK-NEXT: [[SUB:%.*]] = zext <2 x i1> %A to <2 x i64> 486; CHECK-NEXT: ret <2 x i64> [[SUB]] 487; 488 %ext = sext <2 x i1> %A to <2 x i64> 489 %sub = sub <2 x i64> zeroinitializer, %ext 490 ret <2 x i64> %sub 491} 492 493define <2 x i64> @test35(<2 x i64> %A) { 494; CHECK-LABEL: @test35( 495; CHECK-NEXT: [[SUB:%.*]] = mul <2 x i64> %A, <i64 -2, i64 -3> 496; CHECK-NEXT: ret <2 x i64> [[SUB]] 497; 498 %mul = mul <2 x i64> %A, <i64 3, i64 4> 499 %sub = sub <2 x i64> %A, %mul 500 ret <2 x i64> %sub 501} 502 503define <2 x i64> @test36(<2 x i64> %A) { 504; CHECK-LABEL: @test36( 505; CHECK-NEXT: [[SUB:%.*]] = mul <2 x i64> %A, <i64 7, i64 15> 506; CHECK-NEXT: ret <2 x i64> [[SUB]] 507; 508 %shl = shl <2 x i64> %A, <i64 3, i64 4> 509 %sub = sub <2 x i64> %shl, %A 510 ret <2 x i64> %sub 511} 512 513define <2 x i32> @test37(<2 x i32> %A) { 514; CHECK-LABEL: @test37( 515; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> %A, <i32 -2147483648, i32 -2147483648> 516; CHECK-NEXT: [[SUB:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i32> 517; CHECK-NEXT: ret <2 x i32> [[SUB]] 518; 519 %div = sdiv <2 x i32> %A, <i32 -2147483648, i32 -2147483648> 520 %sub = sub nsw <2 x i32> zeroinitializer, %div 521 ret <2 x i32> %sub 522} 523 524define i32 @test38(i32 %A) { 525; CHECK-LABEL: @test38( 526; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 %A, -2147483648 527; CHECK-NEXT: [[SUB:%.*]] = sext i1 [[TMP1]] to i32 528; CHECK-NEXT: ret i32 [[SUB]] 529; 530 %div = sdiv i32 %A, -2147483648 531 %sub = sub nsw i32 0, %div 532 ret i32 %sub 533} 534 535define i32 @test39(i32 %A, i32 %x) { 536; CHECK-LABEL: @test39( 537; CHECK-NEXT: [[C:%.*]] = add i32 %x, %A 538; CHECK-NEXT: ret i32 [[C]] 539; 540 %B = sub i32 0, %A 541 %C = sub nsw i32 %x, %B 542 ret i32 %C 543} 544 545define i16 @test40(i16 %a, i16 %b) { 546; CHECK-LABEL: @test40( 547; CHECK-NEXT: [[ASHR:%.*]] = ashr i16 %a, 1 548; CHECK-NEXT: [[ASHR1:%.*]] = ashr i16 %b, 1 549; CHECK-NEXT: [[SUB:%.*]] = sub nsw i16 [[ASHR]], [[ASHR1]] 550; CHECK-NEXT: ret i16 [[SUB]] 551; 552 %ashr = ashr i16 %a, 1 553 %ashr1 = ashr i16 %b, 1 554 %sub = sub i16 %ashr, %ashr1 555 ret i16 %sub 556} 557 558define i32 @test41(i16 %a, i16 %b) { 559; CHECK-LABEL: @test41( 560; CHECK-NEXT: [[CONV:%.*]] = sext i16 %a to i32 561; CHECK-NEXT: [[CONV1:%.*]] = sext i16 %b to i32 562; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV1]] 563; CHECK-NEXT: ret i32 [[SUB]] 564; 565 %conv = sext i16 %a to i32 566 %conv1 = sext i16 %b to i32 567 %sub = sub i32 %conv, %conv1 568 ret i32 %sub 569} 570 571define i4 @test42(i4 %x, i4 %y) { 572; CHECK-LABEL: @test42( 573; CHECK-NEXT: [[A:%.*]] = and i4 %y, 7 574; CHECK-NEXT: [[B:%.*]] = and i4 %x, 7 575; CHECK-NEXT: [[C:%.*]] = sub nsw i4 [[A]], [[B]] 576; CHECK-NEXT: ret i4 [[C]] 577; 578 %a = and i4 %y, 7 579 %b = and i4 %x, 7 580 %c = sub i4 %a, %b 581 ret i4 %c 582} 583 584define i4 @test43(i4 %x, i4 %y) { 585; CHECK-LABEL: @test43( 586; CHECK-NEXT: [[A:%.*]] = or i4 %x, -8 587; CHECK-NEXT: [[B:%.*]] = and i4 %y, 7 588; CHECK-NEXT: [[C:%.*]] = sub nuw i4 [[A]], [[B]] 589; CHECK-NEXT: ret i4 [[C]] 590; 591 %a = or i4 %x, -8 592 %b = and i4 %y, 7 593 %c = sub i4 %a, %b 594 ret i4 %c 595} 596 597define i32 @test44(i32 %x) { 598; CHECK-LABEL: @test44( 599; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 %x, -32768 600; CHECK-NEXT: ret i32 [[SUB]] 601; 602 %sub = sub nsw i32 %x, 32768 603 ret i32 %sub 604} 605 606define i32 @test45(i32 %x, i32 %y) { 607; CHECK-LABEL: @test45( 608; CHECK-NEXT: [[SUB:%.*]] = and i32 %x, %y 609; CHECK-NEXT: ret i32 [[SUB]] 610; 611 %or = or i32 %x, %y 612 %xor = xor i32 %x, %y 613 %sub = sub i32 %or, %xor 614 ret i32 %sub 615} 616 617define i32 @test46(i32 %x, i32 %y) { 618; CHECK-LABEL: @test46( 619; CHECK-NEXT: [[X_NOT:%.*]] = xor i32 %x, -1 620; CHECK-NEXT: [[SUB:%.*]] = and i32 %y, [[X_NOT]] 621; CHECK-NEXT: ret i32 [[SUB]] 622; 623 %or = or i32 %x, %y 624 %sub = sub i32 %or, %x 625 ret i32 %sub 626} 627 628define i32 @test47(i1 %A, i32 %B, i32 %C, i32 %D) { 629; CHECK-LABEL: @test47( 630; CHECK-NEXT: [[TMP1:%.*]] = sub i32 %D, %C 631; CHECK-NEXT: [[SUB:%.*]] = select i1 %A, i32 [[TMP1]], i32 0 632; CHECK-NEXT: ret i32 [[SUB]] 633; 634 %sel0 = select i1 %A, i32 %D, i32 %B 635 %sel1 = select i1 %A, i32 %C, i32 %B 636 %sub = sub i32 %sel0, %sel1 637 ret i32 %sub 638} 639 640define i32 @test48(i1 %A, i32 %B, i32 %C, i32 %D) { 641; CHECK-LABEL: @test48( 642; CHECK-NEXT: [[TMP1:%.*]] = sub i32 %D, %C 643; CHECK-NEXT: [[SUB:%.*]] = select i1 %A, i32 0, i32 [[TMP1]] 644; CHECK-NEXT: ret i32 [[SUB]] 645; 646 %sel0 = select i1 %A, i32 %B, i32 %D 647 %sel1 = select i1 %A, i32 %B, i32 %C 648 %sub = sub i32 %sel0, %sel1 649 ret i32 %sub 650} 651 652; Zext+add is more canonical than sext+sub. 653 654define i8 @bool_sext_sub(i8 %x, i1 %y) { 655; CHECK-LABEL: @bool_sext_sub( 656; CHECK-NEXT: [[TMP1:%.*]] = zext i1 %y to i8 657; CHECK-NEXT: [[SUB:%.*]] = add i8 [[TMP1]], %x 658; CHECK-NEXT: ret i8 [[SUB]] 659; 660 %sext = sext i1 %y to i8 661 %sub = sub i8 %x, %sext 662 ret i8 %sub 663} 664 665; Vectors get the same transform. 666 667define <2 x i8> @bool_sext_sub_vec(<2 x i8> %x, <2 x i1> %y) { 668; CHECK-LABEL: @bool_sext_sub_vec( 669; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i1> %y to <2 x i8> 670; CHECK-NEXT: [[SUB:%.*]] = add <2 x i8> [[TMP1]], %x 671; CHECK-NEXT: ret <2 x i8> [[SUB]] 672; 673 %sext = sext <2 x i1> %y to <2 x i8> 674 %sub = sub <2 x i8> %x, %sext 675 ret <2 x i8> %sub 676} 677 678; NSW is preserved. 679 680define <2 x i8> @bool_sext_sub_vec_nsw(<2 x i8> %x, <2 x i1> %y) { 681; CHECK-LABEL: @bool_sext_sub_vec_nsw( 682; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i1> %y to <2 x i8> 683; CHECK-NEXT: [[SUB:%.*]] = add nsw <2 x i8> [[TMP1]], %x 684; CHECK-NEXT: ret <2 x i8> [[SUB]] 685; 686 %sext = sext <2 x i1> %y to <2 x i8> 687 %sub = sub nsw <2 x i8> %x, %sext 688 ret <2 x i8> %sub 689} 690 691; We favor the canonical zext+add over keeping the NUW. 692 693define i8 @bool_sext_sub_nuw(i8 %x, i1 %y) { 694; CHECK-LABEL: @bool_sext_sub_nuw( 695; CHECK-NEXT: [[TMP1:%.*]] = zext i1 %y to i8 696; CHECK-NEXT: [[SUB:%.*]] = add i8 [[TMP1]], %x 697; CHECK-NEXT: ret i8 [[SUB]] 698; 699 %sext = sext i1 %y to i8 700 %sub = sub nuw i8 %x, %sext 701 ret i8 %sub 702} 703 704