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 43; (~X) - (~Y) --> Y - X 44; Also, show that we can handle extra uses and vectors. 45 46declare void @use8(i8) 47 48define i8 @notnotsub(i8 %x, i8 %y) { 49; CHECK-LABEL: @notnotsub( 50; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 51; CHECK-NEXT: [[NY:%.*]] = xor i8 [[Y:%.*]], -1 52; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[Y]], [[X]] 53; CHECK-NEXT: call void @use8(i8 [[NX]]) 54; CHECK-NEXT: call void @use8(i8 [[NY]]) 55; CHECK-NEXT: ret i8 [[SUB]] 56; 57 %nx = xor i8 %x, -1 58 %ny = xor i8 %y, -1 59 %sub = sub i8 %nx, %ny 60 call void @use8(i8 %nx) 61 call void @use8(i8 %ny) 62 ret i8 %sub 63} 64 65define <2 x i8> @notnotsub_vec(<2 x i8> %x, <2 x i8> %y) { 66; CHECK-LABEL: @notnotsub_vec( 67; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i8> [[Y:%.*]], [[X:%.*]] 68; CHECK-NEXT: ret <2 x i8> [[SUB]] 69; 70 %nx = xor <2 x i8> %x, <i8 -1, i8 -1> 71 %ny = xor <2 x i8> %y, <i8 -1, i8 -1> 72 %sub = sub <2 x i8> %nx, %ny 73 ret <2 x i8> %sub 74} 75 76define <2 x i8> @notnotsub_vec_undef_elts(<2 x i8> %x, <2 x i8> %y) { 77; CHECK-LABEL: @notnotsub_vec_undef_elts( 78; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i8> [[Y:%.*]], [[X:%.*]] 79; CHECK-NEXT: ret <2 x i8> [[SUB]] 80; 81 %nx = xor <2 x i8> %x, <i8 undef, i8 -1> 82 %ny = xor <2 x i8> %y, <i8 -1, i8 undef> 83 %sub = sub <2 x i8> %nx, %ny 84 ret <2 x i8> %sub 85} 86 87define i32 @test5(i32 %A, i32 %B, i32 %C) { 88; CHECK-LABEL: @test5( 89; CHECK-NEXT: [[D1:%.*]] = sub i32 [[C:%.*]], [[B:%.*]] 90; CHECK-NEXT: [[E:%.*]] = add i32 [[D1]], [[A:%.*]] 91; CHECK-NEXT: ret i32 [[E]] 92; 93 %D = sub i32 %B, %C 94 %E = sub i32 %A, %D 95 ret i32 %E 96} 97 98define i32 @test6(i32 %A, i32 %B) { 99; CHECK-LABEL: @test6( 100; CHECK-NEXT: [[B_NOT:%.*]] = xor i32 [[B:%.*]], -1 101; CHECK-NEXT: [[D:%.*]] = and i32 [[B_NOT]], [[A:%.*]] 102; CHECK-NEXT: ret i32 [[D]] 103; 104 %C = and i32 %A, %B 105 %D = sub i32 %A, %C 106 ret i32 %D 107} 108 109define i32 @test6commuted(i32 %A, i32 %B) { 110; CHECK-LABEL: @test6commuted( 111; CHECK-NEXT: [[B_NOT:%.*]] = xor i32 [[B:%.*]], -1 112; CHECK-NEXT: [[D:%.*]] = and i32 [[B_NOT]], [[A:%.*]] 113; CHECK-NEXT: ret i32 [[D]] 114; 115 %C = and i32 %B, %A 116 %D = sub i32 %A, %C 117 ret i32 %D 118} 119 120define i32 @test7(i32 %A) { 121; CHECK-LABEL: @test7( 122; CHECK-NEXT: [[B:%.*]] = xor i32 [[A:%.*]], -1 123; CHECK-NEXT: ret i32 [[B]] 124; 125 %B = sub i32 -1, %A 126 ret i32 %B 127} 128 129define i32 @test8(i32 %A) { 130; CHECK-LABEL: @test8( 131; CHECK-NEXT: [[C:%.*]] = shl i32 [[A:%.*]], 3 132; CHECK-NEXT: ret i32 [[C]] 133; 134 %B = mul i32 9, %A 135 %C = sub i32 %B, %A 136 ret i32 %C 137} 138 139define i32 @test9(i32 %A) { 140; CHECK-LABEL: @test9( 141; CHECK-NEXT: [[C:%.*]] = mul i32 [[A:%.*]], -2 142; CHECK-NEXT: ret i32 [[C]] 143; 144 %B = mul i32 3, %A 145 %C = sub i32 %A, %B 146 ret i32 %C 147} 148 149define i1 @test11(i8 %A, i8 %B) { 150; CHECK-LABEL: @test11( 151; CHECK-NEXT: [[D:%.*]] = icmp ne i8 [[A:%.*]], [[B:%.*]] 152; CHECK-NEXT: ret i1 [[D]] 153; 154 %C = sub i8 %A, %B 155 %D = icmp ne i8 %C, 0 156 ret i1 %D 157} 158 159define <2 x i1> @test11vec(<2 x i8> %A, <2 x i8> %B) { 160; CHECK-LABEL: @test11vec( 161; CHECK-NEXT: [[D:%.*]] = icmp ne <2 x i8> [[A:%.*]], [[B:%.*]] 162; CHECK-NEXT: ret <2 x i1> [[D]] 163; 164 %C = sub <2 x i8> %A, %B 165 %D = icmp ne <2 x i8> %C, zeroinitializer 166 ret <2 x i1> %D 167} 168 169define i32 @test12(i32 %A) { 170; CHECK-LABEL: @test12( 171; CHECK-NEXT: [[C:%.*]] = lshr i32 [[A:%.*]], 31 172; CHECK-NEXT: ret i32 [[C]] 173; 174 %B = ashr i32 %A, 31 175 %C = sub i32 0, %B 176 ret i32 %C 177} 178 179define i32 @test13(i32 %A) { 180; CHECK-LABEL: @test13( 181; CHECK-NEXT: [[C:%.*]] = ashr i32 [[A:%.*]], 31 182; CHECK-NEXT: ret i32 [[C]] 183; 184 %B = lshr i32 %A, 31 185 %C = sub i32 0, %B 186 ret i32 %C 187} 188 189define <2 x i32> @test12vec(<2 x i32> %A) { 190; CHECK-LABEL: @test12vec( 191; CHECK-NEXT: [[C:%.*]] = lshr <2 x i32> [[A:%.*]], <i32 31, i32 31> 192; CHECK-NEXT: ret <2 x i32> [[C]] 193; 194 %B = ashr <2 x i32> %A, <i32 31, i32 31> 195 %C = sub <2 x i32> zeroinitializer, %B 196 ret <2 x i32> %C 197} 198 199define <2 x i32> @test13vec(<2 x i32> %A) { 200; CHECK-LABEL: @test13vec( 201; CHECK-NEXT: [[C:%.*]] = ashr <2 x i32> [[A:%.*]], <i32 31, i32 31> 202; CHECK-NEXT: ret <2 x i32> [[C]] 203; 204 %B = lshr <2 x i32> %A, <i32 31, i32 31> 205 %C = sub <2 x i32> zeroinitializer, %B 206 ret <2 x i32> %C 207} 208 209define i32 @test15(i32 %A, i32 %B) { 210; CHECK-LABEL: @test15( 211; CHECK-NEXT: [[C:%.*]] = sub i32 0, [[A:%.*]] 212; CHECK-NEXT: [[D:%.*]] = srem i32 [[B:%.*]], [[C]] 213; CHECK-NEXT: ret i32 [[D]] 214; 215 %C = sub i32 0, %A 216 %D = srem i32 %B, %C 217 ret i32 %D 218} 219 220define i32 @test16(i32 %A) { 221; CHECK-LABEL: @test16( 222; CHECK-NEXT: [[Y:%.*]] = sdiv i32 [[A:%.*]], -1123 223; CHECK-NEXT: ret i32 [[Y]] 224; 225 %X = sdiv i32 %A, 1123 226 %Y = sub i32 0, %X 227 ret i32 %Y 228} 229 230; Can't fold subtract here because negation it might oveflow. 231; PR3142 232define i32 @test17(i32 %A) { 233; CHECK-LABEL: @test17( 234; CHECK-NEXT: [[B:%.*]] = sub i32 0, [[A:%.*]] 235; CHECK-NEXT: [[C:%.*]] = sdiv i32 [[B]], 1234 236; CHECK-NEXT: ret i32 [[C]] 237; 238 %B = sub i32 0, %A 239 %C = sdiv i32 %B, 1234 240 ret i32 %C 241} 242 243define i64 @test18(i64 %Y) { 244; CHECK-LABEL: @test18( 245; CHECK-NEXT: ret i64 0 246; 247 %tmp.4 = shl i64 %Y, 2 248 %tmp.12 = shl i64 %Y, 2 249 %tmp.8 = sub i64 %tmp.4, %tmp.12 250 ret i64 %tmp.8 251} 252 253define i1 @test20(i32 %g, i32 %h) { 254; CHECK-LABEL: @test20( 255; CHECK-NEXT: [[TMP_4:%.*]] = icmp ne i32 [[H:%.*]], 0 256; CHECK-NEXT: ret i1 [[TMP_4]] 257; 258 %tmp.2 = sub i32 %g, %h 259 %tmp.4 = icmp ne i32 %tmp.2, %g 260 ret i1 %tmp.4 261} 262 263define i1 @test21(i32 %g, i32 %h) { 264; CHECK-LABEL: @test21( 265; CHECK-NEXT: [[TMP_4:%.*]] = icmp ne i32 [[H:%.*]], 0 266; CHECK-NEXT: ret i1 [[TMP_4]] 267; 268 %tmp.2 = sub i32 %g, %h 269 %tmp.4 = icmp ne i32 %tmp.2, %g 270 ret i1 %tmp.4 271} 272 273; PR2298 274define zeroext i1 @test22(i32 %a, i32 %b) nounwind { 275; CHECK-LABEL: @test22( 276; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[B:%.*]], [[A:%.*]] 277; CHECK-NEXT: ret i1 [[TMP5]] 278; 279 %tmp2 = sub i32 0, %a 280 %tmp4 = sub i32 0, %b 281 %tmp5 = icmp eq i32 %tmp2, %tmp4 282 ret i1 %tmp5 283} 284 285; rdar://7362831 286define i32 @test23(i8* %P, i64 %A){ 287; CHECK-LABEL: @test23( 288; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[A:%.*]] to i32 289; CHECK-NEXT: ret i32 [[TMP1]] 290; 291 %B = getelementptr inbounds i8, i8* %P, i64 %A 292 %C = ptrtoint i8* %B to i64 293 %D = trunc i64 %C to i32 294 %E = ptrtoint i8* %P to i64 295 %F = trunc i64 %E to i32 296 %G = sub i32 %D, %F 297 ret i32 %G 298} 299 300define i8 @test23_as1(i8 addrspace(1)* %P, i16 %A) { 301; CHECK-LABEL: @test23_as1( 302; CHECK-NEXT: [[TMP1:%.*]] = trunc i16 [[A:%.*]] to i8 303; CHECK-NEXT: ret i8 [[TMP1]] 304; 305 %B = getelementptr inbounds i8, i8 addrspace(1)* %P, i16 %A 306 %C = ptrtoint i8 addrspace(1)* %B to i16 307 %D = trunc i16 %C to i8 308 %E = ptrtoint i8 addrspace(1)* %P to i16 309 %F = trunc i16 %E to i8 310 %G = sub i8 %D, %F 311 ret i8 %G 312} 313 314define i64 @test24(i8* %P, i64 %A){ 315; CHECK-LABEL: @test24( 316; CHECK-NEXT: ret i64 [[A:%.*]] 317; 318 %B = getelementptr inbounds i8, i8* %P, i64 %A 319 %C = ptrtoint i8* %B to i64 320 %E = ptrtoint i8* %P to i64 321 %G = sub i64 %C, %E 322 ret i64 %G 323} 324 325define i16 @test24_as1(i8 addrspace(1)* %P, i16 %A) { 326; CHECK-LABEL: @test24_as1( 327; CHECK-NEXT: ret i16 [[A:%.*]] 328; 329 %B = getelementptr inbounds i8, i8 addrspace(1)* %P, i16 %A 330 %C = ptrtoint i8 addrspace(1)* %B to i16 331 %E = ptrtoint i8 addrspace(1)* %P to i16 332 %G = sub i16 %C, %E 333 ret i16 %G 334} 335 336define i64 @test24a(i8* %P, i64 %A){ 337; CHECK-LABEL: @test24a( 338; CHECK-NEXT: [[DIFF_NEG:%.*]] = sub i64 0, [[A:%.*]] 339; CHECK-NEXT: ret i64 [[DIFF_NEG]] 340; 341 %B = getelementptr inbounds i8, i8* %P, i64 %A 342 %C = ptrtoint i8* %B to i64 343 %E = ptrtoint i8* %P to i64 344 %G = sub i64 %E, %C 345 ret i64 %G 346} 347 348define i16 @test24a_as1(i8 addrspace(1)* %P, i16 %A) { 349; CHECK-LABEL: @test24a_as1( 350; CHECK-NEXT: [[DIFF_NEG:%.*]] = sub i16 0, [[A:%.*]] 351; CHECK-NEXT: ret i16 [[DIFF_NEG]] 352; 353 %B = getelementptr inbounds i8, i8 addrspace(1)* %P, i16 %A 354 %C = ptrtoint i8 addrspace(1)* %B to i16 355 %E = ptrtoint i8 addrspace(1)* %P to i16 356 %G = sub i16 %E, %C 357 ret i16 %G 358} 359 360 361@Arr = external global [42 x i16] 362 363define i64 @test24b(i8* %P, i64 %A){ 364; CHECK-LABEL: @test24b( 365; CHECK-NEXT: [[B_IDX:%.*]] = shl nuw i64 [[A:%.*]], 1 366; CHECK-NEXT: ret i64 [[B_IDX]] 367; 368 %B = getelementptr inbounds [42 x i16], [42 x i16]* @Arr, i64 0, i64 %A 369 %C = ptrtoint i16* %B to i64 370 %G = sub i64 %C, ptrtoint ([42 x i16]* @Arr to i64) 371 ret i64 %G 372} 373 374 375define i64 @test25(i8* %P, i64 %A){ 376; CHECK-LABEL: @test25( 377; CHECK-NEXT: [[B_IDX:%.*]] = shl nuw i64 [[A:%.*]], 1 378; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B_IDX]], -84 379; CHECK-NEXT: ret i64 [[TMP1]] 380; 381 %B = getelementptr inbounds [42 x i16], [42 x i16]* @Arr, i64 0, i64 %A 382 %C = ptrtoint i16* %B to i64 383 %G = sub i64 %C, ptrtoint (i16* getelementptr ([42 x i16], [42 x i16]* @Arr, i64 1, i64 0) to i64) 384 ret i64 %G 385} 386 387@Arr_as1 = external addrspace(1) global [42 x i16] 388 389define i16 @test25_as1(i8 addrspace(1)* %P, i64 %A) { 390; CHECK-LABEL: @test25_as1( 391; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[A:%.*]] to i16 392; CHECK-NEXT: [[B_IDX:%.*]] = shl nuw i16 [[TMP1]], 1 393; CHECK-NEXT: [[TMP2:%.*]] = add i16 [[B_IDX]], -84 394; CHECK-NEXT: ret i16 [[TMP2]] 395; 396 %B = getelementptr inbounds [42 x i16], [42 x i16] addrspace(1)* @Arr_as1, i64 0, i64 %A 397 %C = ptrtoint i16 addrspace(1)* %B to i16 398 %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) 399 ret i16 %G 400} 401 402define i32 @test26(i32 %x) { 403; CHECK-LABEL: @test26( 404; CHECK-NEXT: [[NEG:%.*]] = shl i32 -3, [[X:%.*]] 405; CHECK-NEXT: ret i32 [[NEG]] 406; 407 %shl = shl i32 3, %x 408 %neg = sub i32 0, %shl 409 ret i32 %neg 410} 411 412define i32 @test27(i32 %x, i32 %y) { 413; CHECK-LABEL: @test27( 414; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[Y:%.*]], 3 415; CHECK-NEXT: [[SUB:%.*]] = add i32 [[TMP1]], [[X:%.*]] 416; CHECK-NEXT: ret i32 [[SUB]] 417; 418 %mul = mul i32 %y, -8 419 %sub = sub i32 %x, %mul 420 ret i32 %sub 421} 422 423define <2 x i32> @test27vec(<2 x i32> %x, <2 x i32> %y) { 424; CHECK-LABEL: @test27vec( 425; CHECK-NEXT: [[TMP1:%.*]] = mul <2 x i32> [[Y:%.*]], <i32 8, i32 6> 426; CHECK-NEXT: [[SUB:%.*]] = add <2 x i32> [[TMP1]], [[X:%.*]] 427; CHECK-NEXT: ret <2 x i32> [[SUB]] 428; 429 %mul = mul <2 x i32> %y, <i32 -8, i32 -6> 430 %sub = sub <2 x i32> %x, %mul 431 ret <2 x i32> %sub 432} 433 434define <2 x i32> @test27vecsplat(<2 x i32> %x, <2 x i32> %y) { 435; CHECK-LABEL: @test27vecsplat( 436; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[Y:%.*]], <i32 3, i32 3> 437; CHECK-NEXT: [[SUB:%.*]] = add <2 x i32> [[TMP1]], [[X:%.*]] 438; CHECK-NEXT: ret <2 x i32> [[SUB]] 439; 440 %mul = mul <2 x i32> %y, <i32 -8, i32 -8> 441 %sub = sub <2 x i32> %x, %mul 442 ret <2 x i32> %sub 443} 444 445define <2 x i32> @test27vecmixed(<2 x i32> %x, <2 x i32> %y) { 446; CHECK-LABEL: @test27vecmixed( 447; CHECK-NEXT: [[TMP1:%.*]] = mul <2 x i32> [[Y:%.*]], <i32 8, i32 -8> 448; CHECK-NEXT: [[SUB:%.*]] = add <2 x i32> [[TMP1]], [[X:%.*]] 449; CHECK-NEXT: ret <2 x i32> [[SUB]] 450; 451 %mul = mul <2 x i32> %y, <i32 -8, i32 8> 452 %sub = sub <2 x i32> %x, %mul 453 ret <2 x i32> %sub 454} 455 456define i32 @test27commuted(i32 %x, i32 %y) { 457; CHECK-LABEL: @test27commuted( 458; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[Y:%.*]], 3 459; CHECK-NEXT: [[SUB:%.*]] = add i32 [[TMP1]], [[X:%.*]] 460; CHECK-NEXT: ret i32 [[SUB]] 461; 462 %mul = mul i32 -8, %y 463 %sub = sub i32 %x, %mul 464 ret i32 %sub 465} 466 467define <2 x i32> @test27commutedvec(<2 x i32> %x, <2 x i32> %y) { 468; CHECK-LABEL: @test27commutedvec( 469; CHECK-NEXT: [[TMP1:%.*]] = mul <2 x i32> [[Y:%.*]], <i32 8, i32 6> 470; CHECK-NEXT: [[SUB:%.*]] = add <2 x i32> [[TMP1]], [[X:%.*]] 471; CHECK-NEXT: ret <2 x i32> [[SUB]] 472; 473 %mul = mul <2 x i32> <i32 -8, i32 -6>, %y 474 %sub = sub <2 x i32> %x, %mul 475 ret <2 x i32> %sub 476} 477 478define <2 x i32> @test27commutedvecsplat(<2 x i32> %x, <2 x i32> %y) { 479; CHECK-LABEL: @test27commutedvecsplat( 480; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[Y:%.*]], <i32 3, i32 3> 481; CHECK-NEXT: [[SUB:%.*]] = add <2 x i32> [[TMP1]], [[X:%.*]] 482; CHECK-NEXT: ret <2 x i32> [[SUB]] 483; 484 %mul = mul <2 x i32> <i32 -8, i32 -8>, %y 485 %sub = sub <2 x i32> %x, %mul 486 ret <2 x i32> %sub 487} 488 489define <2 x i32> @test27commutedvecmixed(<2 x i32> %x, <2 x i32> %y) { 490; CHECK-LABEL: @test27commutedvecmixed( 491; CHECK-NEXT: [[TMP1:%.*]] = mul <2 x i32> [[Y:%.*]], <i32 8, i32 -8> 492; CHECK-NEXT: [[SUB:%.*]] = add <2 x i32> [[TMP1]], [[X:%.*]] 493; CHECK-NEXT: ret <2 x i32> [[SUB]] 494; 495 %mul = mul <2 x i32> <i32 -8, i32 8>, %y 496 %sub = sub <2 x i32> %x, %mul 497 ret <2 x i32> %sub 498} 499 500define i32 @test28(i32 %x, i32 %y, i32 %z) { 501; CHECK-LABEL: @test28( 502; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[Z:%.*]], [[Y:%.*]] 503; CHECK-NEXT: [[SUB:%.*]] = add i32 [[TMP1]], [[X:%.*]] 504; CHECK-NEXT: ret i32 [[SUB]] 505; 506 %neg = sub i32 0, %z 507 %mul = mul i32 %neg, %y 508 %sub = sub i32 %x, %mul 509 ret i32 %sub 510} 511 512define i32 @test28commuted(i32 %x, i32 %y, i32 %z) { 513; CHECK-LABEL: @test28commuted( 514; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[Y:%.*]], [[Z:%.*]] 515; CHECK-NEXT: [[SUB:%.*]] = add i32 [[TMP1]], [[X:%.*]] 516; CHECK-NEXT: ret i32 [[SUB]] 517; 518 %neg = sub i32 0, %z 519 %mul = mul i32 %y, %neg 520 %sub = sub i32 %x, %mul 521 ret i32 %sub 522} 523 524define i64 @test29(i8* %foo, i64 %i, i64 %j) { 525; CHECK-LABEL: @test29( 526; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[I:%.*]], [[J:%.*]] 527; CHECK-NEXT: ret i64 [[TMP1]] 528; 529 %gep1 = getelementptr inbounds i8, i8* %foo, i64 %i 530 %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j 531 %cast1 = ptrtoint i8* %gep1 to i64 532 %cast2 = ptrtoint i8* %gep2 to i64 533 %sub = sub i64 %cast1, %cast2 534 ret i64 %sub 535} 536 537define i64 @test30(i8* %foo, i64 %i, i64 %j) { 538; CHECK-LABEL: @test30( 539; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nuw i64 [[I:%.*]], 2 540; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[GEP1_IDX]], [[J:%.*]] 541; CHECK-NEXT: ret i64 [[TMP1]] 542; 543 %bit = bitcast i8* %foo to i32* 544 %gep1 = getelementptr inbounds i32, i32* %bit, i64 %i 545 %gep2 = getelementptr inbounds i8, i8* %foo, i64 %j 546 %cast1 = ptrtoint i32* %gep1 to i64 547 %cast2 = ptrtoint i8* %gep2 to i64 548 %sub = sub i64 %cast1, %cast2 549 ret i64 %sub 550} 551 552define i16 @test30_as1(i8 addrspace(1)* %foo, i16 %i, i16 %j) { 553; CHECK-LABEL: @test30_as1( 554; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nuw i16 [[I:%.*]], 2 555; CHECK-NEXT: [[TMP1:%.*]] = sub i16 [[GEP1_IDX]], [[J:%.*]] 556; CHECK-NEXT: ret i16 [[TMP1]] 557; 558 %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)* 559 %gep1 = getelementptr inbounds i32, i32 addrspace(1)* %bit, i16 %i 560 %gep2 = getelementptr inbounds i8, i8 addrspace(1)* %foo, i16 %j 561 %cast1 = ptrtoint i32 addrspace(1)* %gep1 to i16 562 %cast2 = ptrtoint i8 addrspace(1)* %gep2 to i16 563 %sub = sub i16 %cast1, %cast2 564 ret i16 %sub 565} 566 567define <2 x i64> @test31(<2 x i64> %A) { 568; CHECK-LABEL: @test31( 569; CHECK-NEXT: [[SUB:%.*]] = add <2 x i64> [[A:%.*]], <i64 3, i64 4> 570; CHECK-NEXT: ret <2 x i64> [[SUB]] 571; 572 %xor = xor <2 x i64> %A, <i64 -1, i64 -1> 573 %sub = sub <2 x i64> <i64 2, i64 3>, %xor 574 ret <2 x i64> %sub 575} 576 577define <2 x i64> @test32(<2 x i64> %A) { 578; CHECK-LABEL: @test32( 579; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i64> <i64 3, i64 4>, [[A:%.*]] 580; CHECK-NEXT: ret <2 x i64> [[SUB]] 581; 582 %add = add <2 x i64> %A, <i64 -1, i64 -1> 583 %sub = sub <2 x i64> <i64 2, i64 3>, %add 584 ret <2 x i64> %sub 585} 586 587define <2 x i64> @test35(<2 x i64> %A) { 588; CHECK-LABEL: @test35( 589; CHECK-NEXT: [[SUB:%.*]] = mul <2 x i64> [[A:%.*]], <i64 -2, i64 -3> 590; CHECK-NEXT: ret <2 x i64> [[SUB]] 591; 592 %mul = mul <2 x i64> %A, <i64 3, i64 4> 593 %sub = sub <2 x i64> %A, %mul 594 ret <2 x i64> %sub 595} 596 597define <2 x i64> @test36(<2 x i64> %A) { 598; CHECK-LABEL: @test36( 599; CHECK-NEXT: [[SUB:%.*]] = mul <2 x i64> [[A:%.*]], <i64 7, i64 15> 600; CHECK-NEXT: ret <2 x i64> [[SUB]] 601; 602 %shl = shl <2 x i64> %A, <i64 3, i64 4> 603 %sub = sub <2 x i64> %shl, %A 604 ret <2 x i64> %sub 605} 606 607define <2 x i32> @test37(<2 x i32> %A) { 608; CHECK-LABEL: @test37( 609; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 -2147483648, i32 -2147483648> 610; CHECK-NEXT: [[SUB:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i32> 611; CHECK-NEXT: ret <2 x i32> [[SUB]] 612; 613 %div = sdiv <2 x i32> %A, <i32 -2147483648, i32 -2147483648> 614 %sub = sub nsw <2 x i32> zeroinitializer, %div 615 ret <2 x i32> %sub 616} 617 618define i32 @test38(i32 %A) { 619; CHECK-LABEL: @test38( 620; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[A:%.*]], -2147483648 621; CHECK-NEXT: [[SUB:%.*]] = sext i1 [[TMP1]] to i32 622; CHECK-NEXT: ret i32 [[SUB]] 623; 624 %div = sdiv i32 %A, -2147483648 625 %sub = sub nsw i32 0, %div 626 ret i32 %sub 627} 628 629define i32 @test39(i32 %A, i32 %x) { 630; CHECK-LABEL: @test39( 631; CHECK-NEXT: [[C:%.*]] = add i32 [[X:%.*]], [[A:%.*]] 632; CHECK-NEXT: ret i32 [[C]] 633; 634 %B = sub i32 0, %A 635 %C = sub nsw i32 %x, %B 636 ret i32 %C 637} 638 639define i16 @test40(i16 %a, i16 %b) { 640; CHECK-LABEL: @test40( 641; CHECK-NEXT: [[ASHR:%.*]] = ashr i16 [[A:%.*]], 1 642; CHECK-NEXT: [[ASHR1:%.*]] = ashr i16 [[B:%.*]], 1 643; CHECK-NEXT: [[SUB:%.*]] = sub nsw i16 [[ASHR]], [[ASHR1]] 644; CHECK-NEXT: ret i16 [[SUB]] 645; 646 %ashr = ashr i16 %a, 1 647 %ashr1 = ashr i16 %b, 1 648 %sub = sub i16 %ashr, %ashr1 649 ret i16 %sub 650} 651 652define i32 @test41(i16 %a, i16 %b) { 653; CHECK-LABEL: @test41( 654; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[A:%.*]] to i32 655; CHECK-NEXT: [[CONV1:%.*]] = sext i16 [[B:%.*]] to i32 656; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV1]] 657; CHECK-NEXT: ret i32 [[SUB]] 658; 659 %conv = sext i16 %a to i32 660 %conv1 = sext i16 %b to i32 661 %sub = sub i32 %conv, %conv1 662 ret i32 %sub 663} 664 665define i4 @test42(i4 %x, i4 %y) { 666; CHECK-LABEL: @test42( 667; CHECK-NEXT: [[A:%.*]] = and i4 [[Y:%.*]], 7 668; CHECK-NEXT: [[B:%.*]] = and i4 [[X:%.*]], 7 669; CHECK-NEXT: [[C:%.*]] = sub nsw i4 [[A]], [[B]] 670; CHECK-NEXT: ret i4 [[C]] 671; 672 %a = and i4 %y, 7 673 %b = and i4 %x, 7 674 %c = sub i4 %a, %b 675 ret i4 %c 676} 677 678define i4 @test43(i4 %x, i4 %y) { 679; CHECK-LABEL: @test43( 680; CHECK-NEXT: [[A:%.*]] = or i4 [[X:%.*]], -8 681; CHECK-NEXT: [[B:%.*]] = and i4 [[Y:%.*]], 7 682; CHECK-NEXT: [[C:%.*]] = sub nuw i4 [[A]], [[B]] 683; CHECK-NEXT: ret i4 [[C]] 684; 685 %a = or i4 %x, -8 686 %b = and i4 %y, 7 687 %c = sub i4 %a, %b 688 ret i4 %c 689} 690 691define i32 @test44(i32 %x) { 692; CHECK-LABEL: @test44( 693; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[X:%.*]], -32768 694; CHECK-NEXT: ret i32 [[SUB]] 695; 696 %sub = sub nsw i32 %x, 32768 697 ret i32 %sub 698} 699 700define i32 @test45(i32 %x, i32 %y) { 701; CHECK-LABEL: @test45( 702; CHECK-NEXT: [[SUB:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 703; CHECK-NEXT: ret i32 [[SUB]] 704; 705 %or = or i32 %x, %y 706 %xor = xor i32 %x, %y 707 %sub = sub i32 %or, %xor 708 ret i32 %sub 709} 710 711define i32 @test45commuted(i32 %x, i32 %y) { 712; CHECK-LABEL: @test45commuted( 713; CHECK-NEXT: [[SUB:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 714; CHECK-NEXT: ret i32 [[SUB]] 715; 716 %or = or i32 %x, %y 717 %xor = xor i32 %y, %x 718 %sub = sub i32 %or, %xor 719 ret i32 %sub 720} 721 722define i32 @test46(i32 %x, i32 %y) { 723; CHECK-LABEL: @test46( 724; CHECK-NEXT: [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1 725; CHECK-NEXT: [[SUB:%.*]] = and i32 [[X_NOT]], [[Y:%.*]] 726; CHECK-NEXT: ret i32 [[SUB]] 727; 728 %or = or i32 %x, %y 729 %sub = sub i32 %or, %x 730 ret i32 %sub 731} 732 733define i32 @test46commuted(i32 %x, i32 %y) { 734; CHECK-LABEL: @test46commuted( 735; CHECK-NEXT: [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1 736; CHECK-NEXT: [[SUB:%.*]] = and i32 [[X_NOT]], [[Y:%.*]] 737; CHECK-NEXT: ret i32 [[SUB]] 738; 739 %or = or i32 %y, %x 740 %sub = sub i32 %or, %x 741 ret i32 %sub 742} 743 744define i32 @test47(i1 %A, i32 %B, i32 %C, i32 %D) { 745; CHECK-LABEL: @test47( 746; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[D:%.*]], [[C:%.*]] 747; CHECK-NEXT: [[SUB:%.*]] = select i1 [[A:%.*]], i32 [[TMP1]], i32 0 748; CHECK-NEXT: ret i32 [[SUB]] 749; 750 %sel0 = select i1 %A, i32 %D, i32 %B 751 %sel1 = select i1 %A, i32 %C, i32 %B 752 %sub = sub i32 %sel0, %sel1 753 ret i32 %sub 754} 755 756define i32 @test48(i1 %A, i32 %B, i32 %C, i32 %D) { 757; CHECK-LABEL: @test48( 758; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[D:%.*]], [[C:%.*]] 759; CHECK-NEXT: [[SUB:%.*]] = select i1 [[A:%.*]], i32 0, i32 [[TMP1]] 760; CHECK-NEXT: ret i32 [[SUB]] 761; 762 %sel0 = select i1 %A, i32 %B, i32 %D 763 %sel1 = select i1 %A, i32 %B, i32 %C 764 %sub = sub i32 %sel0, %sel1 765 ret i32 %sub 766} 767 768define i32 @test49(i32 %X) { 769; CHECK-LABEL: @test49( 770; CHECK-NEXT: [[SUB:%.*]] = sub i32 1, [[X:%.*]] 771; CHECK-NEXT: [[RES:%.*]] = and i32 [[SUB]], 64 772; CHECK-NEXT: ret i32 [[RES]] 773; 774 %sub = sub i32 129, %X 775 %res = and i32 %sub, 64 776 ret i32 %res 777} 778 779define i32 @test50(i32 %X) { 780; CHECK-LABEL: @test50( 781; CHECK-NEXT: [[SUB:%.*]] = sub i32 1, [[X:%.*]] 782; CHECK-NEXT: [[RES:%.*]] = and i32 [[SUB]], 127 783; CHECK-NEXT: ret i32 [[RES]] 784; 785 %sub = sub i32 129, %X 786 %res = and i32 %sub, 127 787 ret i32 %res 788} 789 790define i32 @test51(i32 %X) { 791; CHECK-LABEL: @test51( 792; CHECK-NEXT: [[SUB:%.*]] = sub i32 126, [[X:%.*]] 793; CHECK-NEXT: [[RES:%.*]] = and i32 [[SUB]], 64 794; CHECK-NEXT: ret i32 [[RES]] 795; 796 %sub = sub i32 254, %X 797 %res = and i32 %sub, 64 798 ret i32 %res 799} 800 801define i32 @test52(i32 %X) { 802; CHECK-LABEL: @test52( 803; CHECK-NEXT: [[SUB:%.*]] = sub i32 126, [[X:%.*]] 804; CHECK-NEXT: [[RES:%.*]] = and i32 [[SUB]], 127 805; CHECK-NEXT: ret i32 [[RES]] 806; 807 %sub = sub i32 254, %X 808 %res = and i32 %sub, 127 809 ret i32 %res 810} 811 812define <2 x i1> @test53(<2 x i1> %A, <2 x i1> %B) { 813; CHECK-LABEL: @test53( 814; CHECK-NEXT: [[SUB:%.*]] = xor <2 x i1> [[A:%.*]], [[B:%.*]] 815; CHECK-NEXT: ret <2 x i1> [[SUB]] 816; 817 %sub = sub <2 x i1> %A, %B 818 ret <2 x i1> %sub 819} 820 821define i32 @test54(i1 %C) { 822; CHECK-LABEL: @test54( 823; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 -877, i32 113 824; CHECK-NEXT: ret i32 [[V]] 825; 826 %A = select i1 %C, i32 1000, i32 10 827 %V = sub i32 123, %A 828 ret i32 %V 829} 830 831define <2 x i32> @test54vec(i1 %C) { 832; CHECK-LABEL: @test54vec( 833; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 -877, i32 -877>, <2 x i32> <i32 113, i32 113> 834; CHECK-NEXT: ret <2 x i32> [[V]] 835; 836 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10> 837 %V = sub <2 x i32> <i32 123, i32 123>, %A 838 ret <2 x i32> %V 839} 840 841define <2 x i32> @test54vec2(i1 %C) { 842; CHECK-LABEL: @test54vec2( 843; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 -877, i32 -2167>, <2 x i32> <i32 113, i32 303> 844; CHECK-NEXT: ret <2 x i32> [[V]] 845; 846 %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30> 847 %V = sub <2 x i32> <i32 123, i32 333>, %A 848 ret <2 x i32> %V 849} 850 851define i32 @test55(i1 %which) { 852; CHECK-LABEL: @test55( 853; CHECK-NEXT: entry: 854; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 855; CHECK: delay: 856; CHECK-NEXT: br label [[FINAL]] 857; CHECK: final: 858; CHECK-NEXT: [[A:%.*]] = phi i32 [ -877, [[ENTRY:%.*]] ], [ 113, [[DELAY]] ] 859; CHECK-NEXT: ret i32 [[A]] 860; 861entry: 862 br i1 %which, label %final, label %delay 863 864delay: 865 br label %final 866 867final: 868 %A = phi i32 [ 1000, %entry ], [ 10, %delay ] 869 %value = sub i32 123, %A 870 ret i32 %value 871} 872 873define <2 x i32> @test55vec(i1 %which) { 874; CHECK-LABEL: @test55vec( 875; CHECK-NEXT: entry: 876; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 877; CHECK: delay: 878; CHECK-NEXT: br label [[FINAL]] 879; CHECK: final: 880; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 -877, i32 -877>, [[ENTRY:%.*]] ], [ <i32 113, i32 113>, [[DELAY]] ] 881; CHECK-NEXT: ret <2 x i32> [[A]] 882; 883entry: 884 br i1 %which, label %final, label %delay 885 886delay: 887 br label %final 888 889final: 890 %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ] 891 %value = sub <2 x i32> <i32 123, i32 123>, %A 892 ret <2 x i32> %value 893} 894 895define <2 x i32> @test55vec2(i1 %which) { 896; CHECK-LABEL: @test55vec2( 897; CHECK-NEXT: entry: 898; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 899; CHECK: delay: 900; CHECK-NEXT: br label [[FINAL]] 901; CHECK: final: 902; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 -877, i32 -2167>, [[ENTRY:%.*]] ], [ <i32 113, i32 303>, [[DELAY]] ] 903; CHECK-NEXT: ret <2 x i32> [[A]] 904; 905entry: 906 br i1 %which, label %final, label %delay 907 908delay: 909 br label %final 910 911final: 912 %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ] 913 %value = sub <2 x i32> <i32 123, i32 333>, %A 914 ret <2 x i32> %value 915} 916 917define i32 @test56(i32 %A, i32 %B) { 918; CHECK-LABEL: @test56( 919; CHECK-NEXT: [[Y:%.*]] = sub i32 0, [[B:%.*]] 920; CHECK-NEXT: ret i32 [[Y]] 921; 922 %X = add i32 %A, %B 923 %Y = sub i32 %A, %X 924 ret i32 %Y } 925 926define i32 @test57(i32 %A, i32 %B) { 927; CHECK-LABEL: @test57( 928; CHECK-NEXT: [[Y:%.*]] = sub i32 0, [[B:%.*]] 929; CHECK-NEXT: ret i32 [[Y]] 930; 931 %X = add i32 %B, %A 932 %Y = sub i32 %A, %X 933 ret i32 %Y } 934 935@dummy_global1 = external global i8* 936@dummy_global2 = external global i8* 937 938define i64 @test58([100 x [100 x i8]]* %foo, i64 %i, i64 %j) { 939; CHECK-LABEL: @test58( 940; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[J:%.*]], 4200 941; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[I:%.*]], 4200 942; CHECK-NEXT: [[TMP3:%.*]] = sub i64 [[TMP2:%.*]] [[TMP1:%.*]] 943; CHECK-NEXT: ret i64 [[TMP3]] 944; 945; Note the reassociate pass and another instcombine pass will further optimize this to 946; "%sub = i64 %i, %j, ret i64 %sub" 947; 948; gep1 and gep2 have only one use 949 %gep1 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 %i 950 %gep2 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 %j 951 %cast1 = ptrtoint i8* %gep1 to i64 952 %cast2 = ptrtoint i8* %gep2 to i64 953 %sub = sub i64 %cast1, %cast2 954 ret i64 %sub 955} 956 957define i64 @test59([100 x [100 x i8]]* %foo, i64 %i) { 958; CHECK-LABEL: @test59( 959; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 %i 960; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 0 961; CHECK-NEXT: store i8* [[GEP1]], i8** @dummy_global1, align 8 962; CHECK-NEXT: store i8* [[GEP2]], i8** @dummy_global2, align 8 963; CHECK-NEXT: ret i64 %i 964; 965; gep1 and gep2 have more than one uses 966 %gep1 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 %i 967 %gep2 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 0 968 %cast1 = ptrtoint i8* %gep1 to i64 969 %cast2 = ptrtoint i8* %gep2 to i64 970 %sub = sub i64 %cast1, %cast2 971 store i8* %gep1, i8** @dummy_global1 972 store i8* %gep2, i8** @dummy_global2 973 ret i64 %sub 974} 975 976define i64 @test60([100 x [100 x i8]]* %foo, i64 %i, i64 %j) { 977; CHECK-LABEL: @test60( 978; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 %j, i64 %i 979; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 0 980; CHECK-NEXT: [[CAST1:%.*]] = ptrtoint i8* [[GEP1]] to i64 981; CHECK-NEXT: [[CAST2:%.*]] = ptrtoint i8* [[GEP2]] to i64 982; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[CAST1]], [[CAST2]] 983; CHECK-NEXT: store i8* [[GEP1]], i8** @dummy_global1, align 8 984; CHECK-NEXT: ret i64 [[SUB]] 985; 986; gep1 has a non-constant index and more than one uses. Shouldn't duplicate the arithmetic. 987 %gep1 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 %j, i64 %i 988 %gep2 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 0 989 %cast1 = ptrtoint i8* %gep1 to i64 990 %cast2 = ptrtoint i8* %gep2 to i64 991 %sub = sub i64 %cast1, %cast2 992 store i8* %gep1, i8** @dummy_global1 993 ret i64 %sub 994} 995 996define i64 @test61([100 x [100 x i8]]* %foo, i64 %i, i64 %j) { 997; CHECK-LABEL: @test61( 998; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 0 999; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 %j, i64 %i 1000; CHECK-NEXT: [[CAST1:%.*]] = ptrtoint i8* [[GEP1]] to i64 1001; CHECK-NEXT: [[CAST2:%.*]] = ptrtoint i8* [[GEP2]] to i64 1002; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[CAST1]], [[CAST2]] 1003; CHECK-NEXT: store i8* [[GEP2]], i8** @dummy_global2, align 8 1004; CHECK-NEXT: ret i64 [[SUB]] 1005; 1006; gep2 has a non-constant index and more than one uses. Shouldn't duplicate the arithmetic. 1007 %gep1 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 0 1008 %gep2 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 %j, i64 %i 1009 %cast1 = ptrtoint i8* %gep1 to i64 1010 %cast2 = ptrtoint i8* %gep2 to i64 1011 %sub = sub i64 %cast1, %cast2 1012 store i8* %gep2, i8** @dummy_global2 1013 ret i64 %sub 1014} 1015 1016define i32 @test62(i32 %A) { 1017; CHECK-LABEL: @test62( 1018; CHECK-NEXT: [[B:%.*]] = shl i32 [[A:%.*]], 1 1019; CHECK-NEXT: [[C:%.*]] = sub i32 2, [[B]] 1020; CHECK-NEXT: ret i32 [[C]] 1021; 1022 %B = sub i32 1, %A 1023 %C = shl i32 %B, 1 1024 ret i32 %C 1025} 1026 1027define <2 x i32> @test62vec(<2 x i32> %A) { 1028; CHECK-LABEL: @test62vec( 1029; CHECK-NEXT: [[B:%.*]] = shl <2 x i32> [[A:%.*]], <i32 1, i32 1> 1030; CHECK-NEXT: [[C:%.*]] = sub <2 x i32> <i32 2, i32 2>, [[B]] 1031; CHECK-NEXT: ret <2 x i32> [[C]] 1032; 1033 %B = sub <2 x i32> <i32 1, i32 1>, %A 1034 %C = shl <2 x i32> %B, <i32 1, i32 1> 1035 ret <2 x i32> %C 1036} 1037 1038define i32 @test63(i32 %A) { 1039; CHECK-LABEL: @test63( 1040; CHECK-NEXT: [[B:%.*]] = shl i32 [[A:%.*]], 1 1041; CHECK-NEXT: ret i32 [[B]] 1042; 1043 %B = sub i32 1, %A 1044 %C = shl i32 %B, 1 1045 %D = sub i32 2, %C 1046 ret i32 %D 1047} 1048 1049define <2 x i32> @test63vec(<2 x i32> %A) { 1050; CHECK-LABEL: @test63vec( 1051; CHECK-NEXT: [[B:%.*]] = shl <2 x i32> [[A:%.*]], <i32 1, i32 1> 1052; CHECK-NEXT: ret <2 x i32> [[B]] 1053; 1054 %B = sub <2 x i32> <i32 1, i32 1>, %A 1055 %C = shl <2 x i32> %B, <i32 1, i32 1> 1056 %D = sub <2 x i32> <i32 2, i32 2>, %C 1057 ret <2 x i32> %D 1058} 1059