1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4target 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" 5 6define i32 @sub_constant(i32 %x) { 7; CHECK-LABEL: @sub_constant( 8; CHECK-NEXT: [[R:%.*]] = add i32 [[X:%.*]], -42 9; CHECK-NEXT: ret i32 [[R]] 10; 11 %r = sub i32 %x, 42 12 ret i32 %r 13} 14 15@g = global i32 0 16 17define i32 @sub_constant_expression(i32 %x) { 18; CHECK-LABEL: @sub_constant_expression( 19; CHECK-NEXT: [[R:%.*]] = sub i32 [[X:%.*]], ptrtoint (i32* @g to i32) 20; CHECK-NEXT: ret i32 [[R]] 21; 22 %r = sub i32 %x, ptrtoint (i32* @g to i32) 23 ret i32 %r 24} 25 26define <2 x i32> @sub_constant_vec(<2 x i32> %x) { 27; CHECK-LABEL: @sub_constant_vec( 28; CHECK-NEXT: [[R:%.*]] = add <2 x i32> [[X:%.*]], <i32 -42, i32 12> 29; CHECK-NEXT: ret <2 x i32> [[R]] 30; 31 %r = sub <2 x i32> %x, <i32 42, i32 -12> 32 ret <2 x i32> %r 33} 34 35define <3 x i33> @sub_constant_vec_weird_type(<3 x i33> %x) { 36; CHECK-LABEL: @sub_constant_vec_weird_type( 37; CHECK-NEXT: [[R:%.*]] = add <3 x i33> [[X:%.*]], <i33 42, i33 -42, i33 12> 38; CHECK-NEXT: ret <3 x i33> [[R]] 39; 40 %r = sub <3 x i33> %x, <i33 -42, i33 42, i33 -12> 41 ret <3 x i33> %r 42} 43 44define <4 x i32> @sub_constant_expression_vec(<4 x i32> %x) { 45; CHECK-LABEL: @sub_constant_expression_vec( 46; CHECK-NEXT: [[R:%.*]] = sub <4 x i32> [[X:%.*]], bitcast (i128 ptrtoint (i32* @g to i128) to <4 x i32>) 47; CHECK-NEXT: ret <4 x i32> [[R]] 48; 49 %r = sub <4 x i32> %x, bitcast (i128 ptrtoint (i32* @g to i128) to <4 x i32>) 50 ret <4 x i32> %r 51} 52 53define i32 @neg_sub(i32 %x, i32 %y) { 54; CHECK-LABEL: @neg_sub( 55; CHECK-NEXT: [[R:%.*]] = add i32 [[Y:%.*]], [[X:%.*]] 56; CHECK-NEXT: ret i32 [[R]] 57; 58 %neg = sub i32 0, %x 59 %r = sub i32 %y, %neg 60 ret i32 %r 61} 62 63define i32 @neg_nsw_sub(i32 %x, i32 %y) { 64; CHECK-LABEL: @neg_nsw_sub( 65; CHECK-NEXT: [[R:%.*]] = add i32 [[Y:%.*]], [[X:%.*]] 66; CHECK-NEXT: ret i32 [[R]] 67; 68 %neg = sub nsw i32 0, %x 69 %r = sub i32 %y, %neg 70 ret i32 %r 71} 72 73define i32 @neg_sub_nsw(i32 %x, i32 %y) { 74; CHECK-LABEL: @neg_sub_nsw( 75; CHECK-NEXT: [[R:%.*]] = add i32 [[Y:%.*]], [[X:%.*]] 76; CHECK-NEXT: ret i32 [[R]] 77; 78 %neg = sub i32 0, %x 79 %r = sub nsw i32 %y, %neg 80 ret i32 %r 81} 82 83define i32 @neg_nsw_sub_nsw(i32 %x, i32 %y) { 84; CHECK-LABEL: @neg_nsw_sub_nsw( 85; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[Y:%.*]], [[X:%.*]] 86; CHECK-NEXT: ret i32 [[R]] 87; 88 %neg = sub nsw i32 0, %x 89 %r = sub nsw i32 %y, %neg 90 ret i32 %r 91} 92 93define <2 x i32> @neg_sub_vec(<2 x i32> %x, <2 x i32> %y) { 94; CHECK-LABEL: @neg_sub_vec( 95; CHECK-NEXT: [[R:%.*]] = add <2 x i32> [[Y:%.*]], [[X:%.*]] 96; CHECK-NEXT: ret <2 x i32> [[R]] 97; 98 %neg = sub <2 x i32> zeroinitializer, %x 99 %r = sub <2 x i32> %y, %neg 100 ret <2 x i32> %r 101} 102 103define <2 x i32> @neg_nsw_sub_vec(<2 x i32> %x, <2 x i32> %y) { 104; CHECK-LABEL: @neg_nsw_sub_vec( 105; CHECK-NEXT: [[R:%.*]] = add <2 x i32> [[Y:%.*]], [[X:%.*]] 106; CHECK-NEXT: ret <2 x i32> [[R]] 107; 108 %neg = sub nsw <2 x i32> zeroinitializer, %x 109 %r = sub <2 x i32> %y, %neg 110 ret <2 x i32> %r 111} 112 113define <2 x i32> @neg_sub_nsw_vec(<2 x i32> %x, <2 x i32> %y) { 114; CHECK-LABEL: @neg_sub_nsw_vec( 115; CHECK-NEXT: [[R:%.*]] = add <2 x i32> [[Y:%.*]], [[X:%.*]] 116; CHECK-NEXT: ret <2 x i32> [[R]] 117; 118 %neg = sub <2 x i32> zeroinitializer, %x 119 %r = sub nsw <2 x i32> %y, %neg 120 ret <2 x i32> %r 121} 122 123define <2 x i32> @neg_nsw_sub_nsw_vec(<2 x i32> %x, <2 x i32> %y) { 124; CHECK-LABEL: @neg_nsw_sub_nsw_vec( 125; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i32> [[Y:%.*]], [[X:%.*]] 126; CHECK-NEXT: ret <2 x i32> [[R]] 127; 128 %neg = sub nsw <2 x i32> zeroinitializer, %x 129 %r = sub nsw <2 x i32> %y, %neg 130 ret <2 x i32> %r 131} 132 133define <2 x i32> @neg_sub_vec_undef(<2 x i32> %x, <2 x i32> %y) { 134; CHECK-LABEL: @neg_sub_vec_undef( 135; CHECK-NEXT: [[R:%.*]] = add <2 x i32> [[Y:%.*]], [[X:%.*]] 136; CHECK-NEXT: ret <2 x i32> [[R]] 137; 138 %neg = sub <2 x i32> <i32 0, i32 undef>, %x 139 %r = sub <2 x i32> %y, %neg 140 ret <2 x i32> %r 141} 142 143define <2 x i32> @neg_nsw_sub_vec_undef(<2 x i32> %x, <2 x i32> %y) { 144; CHECK-LABEL: @neg_nsw_sub_vec_undef( 145; CHECK-NEXT: [[R:%.*]] = add <2 x i32> [[Y:%.*]], [[X:%.*]] 146; CHECK-NEXT: ret <2 x i32> [[R]] 147; 148 %neg = sub nsw <2 x i32> <i32 undef, i32 0>, %x 149 %r = sub <2 x i32> %y, %neg 150 ret <2 x i32> %r 151} 152 153define <2 x i32> @neg_sub_nsw_vec_undef(<2 x i32> %x, <2 x i32> %y) { 154; CHECK-LABEL: @neg_sub_nsw_vec_undef( 155; CHECK-NEXT: [[R:%.*]] = add <2 x i32> [[Y:%.*]], [[X:%.*]] 156; CHECK-NEXT: ret <2 x i32> [[R]] 157; 158 %neg = sub <2 x i32> <i32 undef, i32 0>, %x 159 %r = sub nsw <2 x i32> %y, %neg 160 ret <2 x i32> %r 161} 162 163; This should not drop 'nsw'. 164 165define <2 x i32> @neg_nsw_sub_nsw_vec_undef(<2 x i32> %x, <2 x i32> %y) { 166; CHECK-LABEL: @neg_nsw_sub_nsw_vec_undef( 167; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i32> [[Y:%.*]], [[X:%.*]] 168; CHECK-NEXT: ret <2 x i32> [[R]] 169; 170 %neg = sub nsw <2 x i32> <i32 0, i32 undef>, %x 171 %r = sub nsw <2 x i32> %y, %neg 172 ret <2 x i32> %r 173} 174 175; (~X) - (~Y) --> Y - X 176; Also, show that we can handle extra uses and vectors. 177 178declare void @use8(i8) 179 180define i8 @notnotsub(i8 %x, i8 %y) { 181; CHECK-LABEL: @notnotsub( 182; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 183; CHECK-NEXT: [[NY:%.*]] = xor i8 [[Y:%.*]], -1 184; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[Y]], [[X]] 185; CHECK-NEXT: call void @use8(i8 [[NX]]) 186; CHECK-NEXT: call void @use8(i8 [[NY]]) 187; CHECK-NEXT: ret i8 [[SUB]] 188; 189 %nx = xor i8 %x, -1 190 %ny = xor i8 %y, -1 191 %sub = sub i8 %nx, %ny 192 call void @use8(i8 %nx) 193 call void @use8(i8 %ny) 194 ret i8 %sub 195} 196 197define <2 x i8> @notnotsub_vec(<2 x i8> %x, <2 x i8> %y) { 198; CHECK-LABEL: @notnotsub_vec( 199; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i8> [[Y:%.*]], [[X:%.*]] 200; CHECK-NEXT: ret <2 x i8> [[SUB]] 201; 202 %nx = xor <2 x i8> %x, <i8 -1, i8 -1> 203 %ny = xor <2 x i8> %y, <i8 -1, i8 -1> 204 %sub = sub <2 x i8> %nx, %ny 205 ret <2 x i8> %sub 206} 207 208define <2 x i8> @notnotsub_vec_undef_elts(<2 x i8> %x, <2 x i8> %y) { 209; CHECK-LABEL: @notnotsub_vec_undef_elts( 210; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i8> [[Y:%.*]], [[X:%.*]] 211; CHECK-NEXT: ret <2 x i8> [[SUB]] 212; 213 %nx = xor <2 x i8> %x, <i8 undef, i8 -1> 214 %ny = xor <2 x i8> %y, <i8 -1, i8 undef> 215 %sub = sub <2 x i8> %nx, %ny 216 ret <2 x i8> %sub 217} 218 219define i32 @test5(i32 %A, i32 %B, i32 %C) { 220; CHECK-LABEL: @test5( 221; CHECK-NEXT: [[D_NEG:%.*]] = sub i32 [[C:%.*]], [[B:%.*]] 222; CHECK-NEXT: [[E:%.*]] = add i32 [[D_NEG]], [[A:%.*]] 223; CHECK-NEXT: ret i32 [[E]] 224; 225 %D = sub i32 %B, %C 226 %E = sub i32 %A, %D 227 ret i32 %E 228} 229 230define i32 @test6(i32 %A, i32 %B) { 231; CHECK-LABEL: @test6( 232; CHECK-NEXT: [[B_NOT:%.*]] = xor i32 [[B:%.*]], -1 233; CHECK-NEXT: [[D:%.*]] = and i32 [[B_NOT]], [[A:%.*]] 234; CHECK-NEXT: ret i32 [[D]] 235; 236 %C = and i32 %A, %B 237 %D = sub i32 %A, %C 238 ret i32 %D 239} 240 241define i32 @test6commuted(i32 %A, i32 %B) { 242; CHECK-LABEL: @test6commuted( 243; CHECK-NEXT: [[B_NOT:%.*]] = xor i32 [[B:%.*]], -1 244; CHECK-NEXT: [[D:%.*]] = and i32 [[B_NOT]], [[A:%.*]] 245; CHECK-NEXT: ret i32 [[D]] 246; 247 %C = and i32 %B, %A 248 %D = sub i32 %A, %C 249 ret i32 %D 250} 251 252define i32 @test7(i32 %A) { 253; CHECK-LABEL: @test7( 254; CHECK-NEXT: [[B:%.*]] = xor i32 [[A:%.*]], -1 255; CHECK-NEXT: ret i32 [[B]] 256; 257 %B = sub i32 -1, %A 258 ret i32 %B 259} 260 261define i32 @test8(i32 %A) { 262; CHECK-LABEL: @test8( 263; CHECK-NEXT: [[C:%.*]] = shl i32 [[A:%.*]], 3 264; CHECK-NEXT: ret i32 [[C]] 265; 266 %B = mul i32 9, %A 267 %C = sub i32 %B, %A 268 ret i32 %C 269} 270 271define i32 @test9(i32 %A) { 272; CHECK-LABEL: @test9( 273; CHECK-NEXT: [[C:%.*]] = mul i32 [[A:%.*]], -2 274; CHECK-NEXT: ret i32 [[C]] 275; 276 %B = mul i32 3, %A 277 %C = sub i32 %A, %B 278 ret i32 %C 279} 280 281define i1 @test11(i8 %A, i8 %B) { 282; CHECK-LABEL: @test11( 283; CHECK-NEXT: [[D:%.*]] = icmp ne i8 [[A:%.*]], [[B:%.*]] 284; CHECK-NEXT: ret i1 [[D]] 285; 286 %C = sub i8 %A, %B 287 %D = icmp ne i8 %C, 0 288 ret i1 %D 289} 290 291define <2 x i1> @test11vec(<2 x i8> %A, <2 x i8> %B) { 292; CHECK-LABEL: @test11vec( 293; CHECK-NEXT: [[D:%.*]] = icmp ne <2 x i8> [[A:%.*]], [[B:%.*]] 294; CHECK-NEXT: ret <2 x i1> [[D]] 295; 296 %C = sub <2 x i8> %A, %B 297 %D = icmp ne <2 x i8> %C, zeroinitializer 298 ret <2 x i1> %D 299} 300 301define i32 @test12(i32 %A) { 302; CHECK-LABEL: @test12( 303; CHECK-NEXT: [[B_NEG:%.*]] = lshr i32 [[A:%.*]], 31 304; CHECK-NEXT: ret i32 [[B_NEG]] 305; 306 %B = ashr i32 %A, 31 307 %C = sub i32 0, %B 308 ret i32 %C 309} 310 311define i32 @test13(i32 %A) { 312; CHECK-LABEL: @test13( 313; CHECK-NEXT: [[B_NEG:%.*]] = ashr i32 [[A:%.*]], 31 314; CHECK-NEXT: ret i32 [[B_NEG]] 315; 316 %B = lshr i32 %A, 31 317 %C = sub i32 0, %B 318 ret i32 %C 319} 320 321define <2 x i32> @test12vec(<2 x i32> %A) { 322; CHECK-LABEL: @test12vec( 323; CHECK-NEXT: [[B_NEG:%.*]] = lshr <2 x i32> [[A:%.*]], <i32 31, i32 31> 324; CHECK-NEXT: ret <2 x i32> [[B_NEG]] 325; 326 %B = ashr <2 x i32> %A, <i32 31, i32 31> 327 %C = sub <2 x i32> zeroinitializer, %B 328 ret <2 x i32> %C 329} 330 331define <2 x i32> @test13vec(<2 x i32> %A) { 332; CHECK-LABEL: @test13vec( 333; CHECK-NEXT: [[B_NEG:%.*]] = ashr <2 x i32> [[A:%.*]], <i32 31, i32 31> 334; CHECK-NEXT: ret <2 x i32> [[B_NEG]] 335; 336 %B = lshr <2 x i32> %A, <i32 31, i32 31> 337 %C = sub <2 x i32> zeroinitializer, %B 338 ret <2 x i32> %C 339} 340 341define i32 @test15(i32 %A, i32 %B) { 342; CHECK-LABEL: @test15( 343; CHECK-NEXT: [[C:%.*]] = sub i32 0, [[A:%.*]] 344; CHECK-NEXT: [[D:%.*]] = srem i32 [[B:%.*]], [[C]] 345; CHECK-NEXT: ret i32 [[D]] 346; 347 %C = sub i32 0, %A 348 %D = srem i32 %B, %C 349 ret i32 %D 350} 351 352define i32 @test16(i32 %A) { 353; CHECK-LABEL: @test16( 354; CHECK-NEXT: [[X_NEG:%.*]] = sdiv i32 [[A:%.*]], -1123 355; CHECK-NEXT: ret i32 [[X_NEG]] 356; 357 %X = sdiv i32 %A, 1123 358 %Y = sub i32 0, %X 359 ret i32 %Y 360} 361 362; Can't fold subtract here because negation it might oveflow. 363; PR3142 364define i32 @test17(i32 %A) { 365; CHECK-LABEL: @test17( 366; CHECK-NEXT: [[B:%.*]] = sub i32 0, [[A:%.*]] 367; CHECK-NEXT: [[C:%.*]] = sdiv i32 [[B]], 1234 368; CHECK-NEXT: ret i32 [[C]] 369; 370 %B = sub i32 0, %A 371 %C = sdiv i32 %B, 1234 372 ret i32 %C 373} 374 375define i64 @test18(i64 %Y) { 376; CHECK-LABEL: @test18( 377; CHECK-NEXT: ret i64 0 378; 379 %i.4 = shl i64 %Y, 2 380 %i.12 = shl i64 %Y, 2 381 %i.8 = sub i64 %i.4, %i.12 382 ret i64 %i.8 383} 384 385define i1 @test20(i32 %g, i32 %h) { 386; CHECK-LABEL: @test20( 387; CHECK-NEXT: [[I_4:%.*]] = icmp ne i32 [[H:%.*]], 0 388; CHECK-NEXT: ret i1 [[I_4]] 389; 390 %i.2 = sub i32 %g, %h 391 %i.4 = icmp ne i32 %i.2, %g 392 ret i1 %i.4 393} 394 395define i1 @test21(i32 %g, i32 %h) { 396; CHECK-LABEL: @test21( 397; CHECK-NEXT: [[I_4:%.*]] = icmp ne i32 [[H:%.*]], 0 398; CHECK-NEXT: ret i1 [[I_4]] 399; 400 %i.2 = sub i32 %g, %h 401 %i.4 = icmp ne i32 %i.2, %g 402 ret i1 %i.4 403} 404 405; PR2298 406define zeroext i1 @test22(i32 %a, i32 %b) nounwind { 407; CHECK-LABEL: @test22( 408; CHECK-NEXT: [[I5:%.*]] = icmp eq i32 [[B:%.*]], [[A:%.*]] 409; CHECK-NEXT: ret i1 [[I5]] 410; 411 %i2 = sub i32 0, %a 412 %i4 = sub i32 0, %b 413 %i5 = icmp eq i32 %i2, %i4 414 ret i1 %i5 415} 416 417define i32 @test26(i32 %x) { 418; CHECK-LABEL: @test26( 419; CHECK-NEXT: [[SHL_NEG:%.*]] = shl i32 -3, [[X:%.*]] 420; CHECK-NEXT: ret i32 [[SHL_NEG]] 421; 422 %shl = shl i32 3, %x 423 %neg = sub i32 0, %shl 424 ret i32 %neg 425} 426 427define i64 @test_neg_shl_sub(i64 %a, i64 %b) { 428; CHECK-LABEL: @test_neg_shl_sub( 429; CHECK-NEXT: [[SUB_NEG:%.*]] = sub i64 [[B:%.*]], [[A:%.*]] 430; CHECK-NEXT: [[MUL_NEG:%.*]] = shl i64 [[SUB_NEG]], 2 431; CHECK-NEXT: ret i64 [[MUL_NEG]] 432; 433 %sub = sub i64 %a, %b 434 %mul = shl i64 %sub, 2 435 %neg = sub i64 0, %mul 436 ret i64 %neg 437} 438 439define i64 @test_neg_shl_sub_extra_use1(i64 %a, i64 %b, i64* %p) { 440; CHECK-LABEL: @test_neg_shl_sub_extra_use1( 441; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[A:%.*]], [[B:%.*]] 442; CHECK-NEXT: store i64 [[SUB]], i64* [[P:%.*]], align 8 443; CHECK-NEXT: [[MUL_NEG:%.*]] = mul i64 [[SUB]], -4 444; CHECK-NEXT: ret i64 [[MUL_NEG]] 445; 446 %sub = sub i64 %a, %b 447 store i64 %sub, i64* %p 448 %mul = shl i64 %sub, 2 449 %neg = sub i64 0, %mul 450 ret i64 %neg 451} 452 453define i64 @test_neg_shl_sub_extra_use2(i64 %a, i64 %b, i64* %p) { 454; CHECK-LABEL: @test_neg_shl_sub_extra_use2( 455; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[A:%.*]], [[B:%.*]] 456; CHECK-NEXT: [[MUL:%.*]] = shl i64 [[SUB]], 2 457; CHECK-NEXT: store i64 [[MUL]], i64* [[P:%.*]], align 8 458; CHECK-NEXT: [[NEG:%.*]] = sub i64 0, [[MUL]] 459; CHECK-NEXT: ret i64 [[NEG]] 460; 461 %sub = sub i64 %a, %b 462 %mul = shl i64 %sub, 2 463 store i64 %mul, i64* %p 464 %neg = sub i64 0, %mul 465 ret i64 %neg 466} 467 468define i64 @test_neg_shl_div(i64 %a) { 469; CHECK-LABEL: @test_neg_shl_div( 470; CHECK-NEXT: [[DIV_NEG:%.*]] = sdiv i64 [[A:%.*]], -3 471; CHECK-NEXT: [[SHL_NEG:%.*]] = shl i64 [[DIV_NEG]], 2 472; CHECK-NEXT: ret i64 [[SHL_NEG]] 473; 474 %div = sdiv i64 %a, 3 475 %shl = shl i64 %div, 2 476 %neg = sub i64 0, %shl 477 ret i64 %neg 478} 479 480define i64 @test_neg_shl_zext_i1(i1 %a, i64 %b) { 481; CHECK-LABEL: @test_neg_shl_zext_i1( 482; CHECK-NEXT: [[EXT_NEG:%.*]] = sext i1 [[A:%.*]] to i64 483; CHECK-NEXT: [[SHL_NEG:%.*]] = shl i64 [[EXT_NEG]], [[B:%.*]] 484; CHECK-NEXT: ret i64 [[SHL_NEG]] 485; 486 %ext = zext i1 %a to i64 487 %shl = shl i64 %ext, %b 488 %neg = sub i64 0, %shl 489 ret i64 %neg 490} 491 492define i64 @test_neg_shl_sext_i1(i1 %a, i64 %b) { 493; CHECK-LABEL: @test_neg_shl_sext_i1( 494; CHECK-NEXT: [[EXT_NEG:%.*]] = zext i1 [[A:%.*]] to i64 495; CHECK-NEXT: [[SHL_NEG:%.*]] = shl i64 [[EXT_NEG]], [[B:%.*]] 496; CHECK-NEXT: ret i64 [[SHL_NEG]] 497; 498 %ext = sext i1 %a to i64 499 %shl = shl i64 %ext, %b 500 %neg = sub i64 0, %shl 501 ret i64 %neg 502} 503 504define i64 @test_neg_zext_i1_extra_use(i1 %a, i64 %b, i64* %p) { 505; CHECK-LABEL: @test_neg_zext_i1_extra_use( 506; CHECK-NEXT: [[EXT_NEG:%.*]] = sext i1 [[A:%.*]] to i64 507; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[A]] to i64 508; CHECK-NEXT: store i64 [[EXT]], i64* [[P:%.*]], align 8 509; CHECK-NEXT: ret i64 [[EXT_NEG]] 510; 511 %ext = zext i1 %a to i64 512 %neg = sub i64 0, %ext 513 store i64 %ext, i64* %p 514 ret i64 %neg 515} 516 517define i64 @test_neg_sext_i1_extra_use(i1 %a, i64 %b, i64* %p) { 518; CHECK-LABEL: @test_neg_sext_i1_extra_use( 519; CHECK-NEXT: [[EXT_NEG:%.*]] = zext i1 [[A:%.*]] to i64 520; CHECK-NEXT: [[EXT:%.*]] = sext i1 [[A]] to i64 521; CHECK-NEXT: store i64 [[EXT]], i64* [[P:%.*]], align 8 522; CHECK-NEXT: ret i64 [[EXT_NEG]] 523; 524 %ext = sext i1 %a to i64 525 %neg = sub i64 0, %ext 526 store i64 %ext, i64* %p 527 ret i64 %neg 528} 529 530define i32 @test_neg_trunc_shl_sub(i64 %a, i64 %b) { 531; CHECK-LABEL: @test_neg_trunc_shl_sub( 532; CHECK-NEXT: [[SUB_NEG:%.*]] = sub i64 [[B:%.*]], [[A:%.*]] 533; CHECK-NEXT: [[SUB_TR_NEG:%.*]] = trunc i64 [[SUB_NEG]] to i32 534; CHECK-NEXT: [[TRUNC_NEG:%.*]] = shl i32 [[SUB_TR_NEG]], 2 535; CHECK-NEXT: ret i32 [[TRUNC_NEG]] 536; 537 %sub = sub i64 %a, %b 538 %shl = shl i64 %sub, 2 539 %trunc = trunc i64 %shl to i32 540 %neg = sub i32 0, %trunc 541 ret i32 %neg 542} 543 544define i32 @test_neg_trunc_shl_ashr(i64 %a, i64 %b) { 545; CHECK-LABEL: @test_neg_trunc_shl_ashr( 546; CHECK-NEXT: [[SHR_NEG:%.*]] = lshr i64 [[A:%.*]], 63 547; CHECK-NEXT: [[SHL_NEG:%.*]] = shl i64 [[SHR_NEG]], [[B:%.*]] 548; CHECK-NEXT: [[TRUNC_NEG:%.*]] = trunc i64 [[SHL_NEG]] to i32 549; CHECK-NEXT: ret i32 [[TRUNC_NEG]] 550; 551 %shr = ashr i64 %a, 63 552 %shl = shl i64 %shr, %b 553 %trunc = trunc i64 %shl to i32 554 %neg = sub i32 0, %trunc 555 ret i32 %neg 556} 557 558define i32 @test_neg_trunc_shl_lshr(i64 %a, i64 %b) { 559; CHECK-LABEL: @test_neg_trunc_shl_lshr( 560; CHECK-NEXT: [[SHR_NEG:%.*]] = ashr i64 [[A:%.*]], 63 561; CHECK-NEXT: [[SHL_NEG:%.*]] = shl i64 [[SHR_NEG]], [[B:%.*]] 562; CHECK-NEXT: [[TRUNC_NEG:%.*]] = trunc i64 [[SHL_NEG]] to i32 563; CHECK-NEXT: ret i32 [[TRUNC_NEG]] 564; 565 %shr = lshr i64 %a, 63 566 %shl = shl i64 %shr, %b 567 %trunc = trunc i64 %shl to i32 568 %neg = sub i32 0, %trunc 569 ret i32 %neg 570} 571 572define i64 @test_neg_mul_sub(i64 %a, i64 %b, i64 %c) { 573; CHECK-LABEL: @test_neg_mul_sub( 574; CHECK-NEXT: [[SUB_NEG:%.*]] = sub i64 [[B:%.*]], [[A:%.*]] 575; CHECK-NEXT: [[MUL_NEG:%.*]] = mul i64 [[SUB_NEG]], [[C:%.*]] 576; CHECK-NEXT: ret i64 [[MUL_NEG]] 577; 578 %sub = sub i64 %a, %b 579 %mul = mul i64 %sub, %c 580 %neg = sub i64 0, %mul 581 ret i64 %neg 582} 583 584define i64 @test_neg_mul_sub_commuted(i64 %a, i64 %b, i64 %c) { 585; CHECK-LABEL: @test_neg_mul_sub_commuted( 586; CHECK-NEXT: [[COMPLEX:%.*]] = mul i64 [[C:%.*]], [[C]] 587; CHECK-NEXT: [[SUB_NEG:%.*]] = sub i64 [[B:%.*]], [[A:%.*]] 588; CHECK-NEXT: [[MUL_NEG:%.*]] = mul i64 [[SUB_NEG]], [[COMPLEX]] 589; CHECK-NEXT: ret i64 [[MUL_NEG]] 590; 591 %complex = mul i64 %c, %c 592 %sub = sub i64 %a, %b 593 %mul = mul i64 %complex, %sub 594 %neg = sub i64 0, %mul 595 ret i64 %neg 596} 597 598define i32 @test27(i32 %x, i32 %y) { 599; CHECK-LABEL: @test27( 600; CHECK-NEXT: [[MUL_NEG:%.*]] = shl i32 [[Y:%.*]], 3 601; CHECK-NEXT: [[SUB:%.*]] = add i32 [[MUL_NEG]], [[X:%.*]] 602; CHECK-NEXT: ret i32 [[SUB]] 603; 604 %mul = mul i32 %y, -8 605 %sub = sub i32 %x, %mul 606 ret i32 %sub 607} 608 609define <2 x i32> @test27vec(<2 x i32> %x, <2 x i32> %y) { 610; CHECK-LABEL: @test27vec( 611; CHECK-NEXT: [[MUL_NEG:%.*]] = mul <2 x i32> [[Y:%.*]], <i32 8, i32 6> 612; CHECK-NEXT: [[SUB:%.*]] = add <2 x i32> [[MUL_NEG]], [[X:%.*]] 613; CHECK-NEXT: ret <2 x i32> [[SUB]] 614; 615 %mul = mul <2 x i32> %y, <i32 -8, i32 -6> 616 %sub = sub <2 x i32> %x, %mul 617 ret <2 x i32> %sub 618} 619 620define <2 x i32> @test27vecsplat(<2 x i32> %x, <2 x i32> %y) { 621; CHECK-LABEL: @test27vecsplat( 622; CHECK-NEXT: [[MUL_NEG:%.*]] = shl <2 x i32> [[Y:%.*]], <i32 3, i32 3> 623; CHECK-NEXT: [[SUB:%.*]] = add <2 x i32> [[MUL_NEG]], [[X:%.*]] 624; CHECK-NEXT: ret <2 x i32> [[SUB]] 625; 626 %mul = mul <2 x i32> %y, <i32 -8, i32 -8> 627 %sub = sub <2 x i32> %x, %mul 628 ret <2 x i32> %sub 629} 630 631define <2 x i32> @test27vecmixed(<2 x i32> %x, <2 x i32> %y) { 632; CHECK-LABEL: @test27vecmixed( 633; CHECK-NEXT: [[MUL_NEG:%.*]] = mul <2 x i32> [[Y:%.*]], <i32 8, i32 -8> 634; CHECK-NEXT: [[SUB:%.*]] = add <2 x i32> [[MUL_NEG]], [[X:%.*]] 635; CHECK-NEXT: ret <2 x i32> [[SUB]] 636; 637 %mul = mul <2 x i32> %y, <i32 -8, i32 8> 638 %sub = sub <2 x i32> %x, %mul 639 ret <2 x i32> %sub 640} 641 642define i32 @test27commuted(i32 %x, i32 %y) { 643; CHECK-LABEL: @test27commuted( 644; CHECK-NEXT: [[MUL_NEG:%.*]] = shl i32 [[Y:%.*]], 3 645; CHECK-NEXT: [[SUB:%.*]] = add i32 [[MUL_NEG]], [[X:%.*]] 646; CHECK-NEXT: ret i32 [[SUB]] 647; 648 %mul = mul i32 -8, %y 649 %sub = sub i32 %x, %mul 650 ret i32 %sub 651} 652 653define <2 x i32> @test27commutedvec(<2 x i32> %x, <2 x i32> %y) { 654; CHECK-LABEL: @test27commutedvec( 655; CHECK-NEXT: [[MUL_NEG:%.*]] = mul <2 x i32> [[Y:%.*]], <i32 8, i32 6> 656; CHECK-NEXT: [[SUB:%.*]] = add <2 x i32> [[MUL_NEG]], [[X:%.*]] 657; CHECK-NEXT: ret <2 x i32> [[SUB]] 658; 659 %mul = mul <2 x i32> <i32 -8, i32 -6>, %y 660 %sub = sub <2 x i32> %x, %mul 661 ret <2 x i32> %sub 662} 663 664define <2 x i32> @test27commutedvecsplat(<2 x i32> %x, <2 x i32> %y) { 665; CHECK-LABEL: @test27commutedvecsplat( 666; CHECK-NEXT: [[MUL_NEG:%.*]] = shl <2 x i32> [[Y:%.*]], <i32 3, i32 3> 667; CHECK-NEXT: [[SUB:%.*]] = add <2 x i32> [[MUL_NEG]], [[X:%.*]] 668; CHECK-NEXT: ret <2 x i32> [[SUB]] 669; 670 %mul = mul <2 x i32> <i32 -8, i32 -8>, %y 671 %sub = sub <2 x i32> %x, %mul 672 ret <2 x i32> %sub 673} 674 675define <2 x i32> @test27commutedvecmixed(<2 x i32> %x, <2 x i32> %y) { 676; CHECK-LABEL: @test27commutedvecmixed( 677; CHECK-NEXT: [[MUL_NEG:%.*]] = mul <2 x i32> [[Y:%.*]], <i32 8, i32 -8> 678; CHECK-NEXT: [[SUB:%.*]] = add <2 x i32> [[MUL_NEG]], [[X:%.*]] 679; CHECK-NEXT: ret <2 x i32> [[SUB]] 680; 681 %mul = mul <2 x i32> <i32 -8, i32 8>, %y 682 %sub = sub <2 x i32> %x, %mul 683 ret <2 x i32> %sub 684} 685 686define i32 @test28(i32 %x, i32 %y, i32 %z) { 687; CHECK-LABEL: @test28( 688; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[Z:%.*]], [[Y:%.*]] 689; CHECK-NEXT: [[SUB:%.*]] = add i32 [[TMP1]], [[X:%.*]] 690; CHECK-NEXT: ret i32 [[SUB]] 691; 692 %neg = sub i32 0, %z 693 %mul = mul i32 %neg, %y 694 %sub = sub i32 %x, %mul 695 ret i32 %sub 696} 697 698define i32 @test28commuted(i32 %x, i32 %y, i32 %z) { 699; CHECK-LABEL: @test28commuted( 700; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[Z:%.*]], [[Y:%.*]] 701; CHECK-NEXT: [[SUB:%.*]] = add i32 [[TMP1]], [[X:%.*]] 702; CHECK-NEXT: ret i32 [[SUB]] 703; 704 %neg = sub i32 0, %z 705 %mul = mul i32 %y, %neg 706 %sub = sub i32 %x, %mul 707 ret i32 %sub 708} 709 710define <2 x i64> @test31(<2 x i64> %A) { 711; CHECK-LABEL: @test31( 712; CHECK-NEXT: [[SUB:%.*]] = add <2 x i64> [[A:%.*]], <i64 3, i64 4> 713; CHECK-NEXT: ret <2 x i64> [[SUB]] 714; 715 %xor = xor <2 x i64> %A, <i64 -1, i64 -1> 716 %sub = sub <2 x i64> <i64 2, i64 3>, %xor 717 ret <2 x i64> %sub 718} 719 720define <2 x i64> @test32(<2 x i64> %A) { 721; CHECK-LABEL: @test32( 722; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i64> <i64 3, i64 4>, [[A:%.*]] 723; CHECK-NEXT: ret <2 x i64> [[SUB]] 724; 725 %add = add <2 x i64> %A, <i64 -1, i64 -1> 726 %sub = sub <2 x i64> <i64 2, i64 3>, %add 727 ret <2 x i64> %sub 728} 729 730define <2 x i64> @test35(<2 x i64> %A) { 731; CHECK-LABEL: @test35( 732; CHECK-NEXT: [[SUB:%.*]] = mul <2 x i64> [[A:%.*]], <i64 -2, i64 -3> 733; CHECK-NEXT: ret <2 x i64> [[SUB]] 734; 735 %mul = mul <2 x i64> %A, <i64 3, i64 4> 736 %sub = sub <2 x i64> %A, %mul 737 ret <2 x i64> %sub 738} 739 740define <2 x i64> @test36(<2 x i64> %A) { 741; CHECK-LABEL: @test36( 742; CHECK-NEXT: [[SUB:%.*]] = mul <2 x i64> [[A:%.*]], <i64 7, i64 15> 743; CHECK-NEXT: ret <2 x i64> [[SUB]] 744; 745 %shl = shl <2 x i64> %A, <i64 3, i64 4> 746 %sub = sub <2 x i64> %shl, %A 747 ret <2 x i64> %sub 748} 749 750define <2 x i32> @test37(<2 x i32> %A) { 751; CHECK-LABEL: @test37( 752; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 -2147483648, i32 -2147483648> 753; CHECK-NEXT: [[DIV_NEG:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i32> 754; CHECK-NEXT: ret <2 x i32> [[DIV_NEG]] 755; 756 %div = sdiv <2 x i32> %A, <i32 -2147483648, i32 -2147483648> 757 %sub = sub nsw <2 x i32> zeroinitializer, %div 758 ret <2 x i32> %sub 759} 760 761define i32 @test38(i32 %A) { 762; CHECK-LABEL: @test38( 763; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[A:%.*]], -2147483648 764; CHECK-NEXT: [[DIV_NEG:%.*]] = sext i1 [[TMP1]] to i32 765; CHECK-NEXT: ret i32 [[DIV_NEG]] 766; 767 %div = sdiv i32 %A, -2147483648 768 %sub = sub nsw i32 0, %div 769 ret i32 %sub 770} 771 772define i16 @test40(i16 %a, i16 %b) { 773; CHECK-LABEL: @test40( 774; CHECK-NEXT: [[ASHR:%.*]] = ashr i16 [[A:%.*]], 1 775; CHECK-NEXT: [[ASHR1:%.*]] = ashr i16 [[B:%.*]], 1 776; CHECK-NEXT: [[SUB:%.*]] = sub nsw i16 [[ASHR]], [[ASHR1]] 777; CHECK-NEXT: ret i16 [[SUB]] 778; 779 %ashr = ashr i16 %a, 1 780 %ashr1 = ashr i16 %b, 1 781 %sub = sub i16 %ashr, %ashr1 782 ret i16 %sub 783} 784 785define i32 @test41(i16 %a, i16 %b) { 786; CHECK-LABEL: @test41( 787; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[A:%.*]] to i32 788; CHECK-NEXT: [[CONV1:%.*]] = sext i16 [[B:%.*]] to i32 789; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV1]] 790; CHECK-NEXT: ret i32 [[SUB]] 791; 792 %conv = sext i16 %a to i32 793 %conv1 = sext i16 %b to i32 794 %sub = sub i32 %conv, %conv1 795 ret i32 %sub 796} 797 798define i4 @test42(i4 %x, i4 %y) { 799; CHECK-LABEL: @test42( 800; CHECK-NEXT: [[A:%.*]] = and i4 [[Y:%.*]], 7 801; CHECK-NEXT: [[B:%.*]] = and i4 [[X:%.*]], 7 802; CHECK-NEXT: [[C:%.*]] = sub nsw i4 [[A]], [[B]] 803; CHECK-NEXT: ret i4 [[C]] 804; 805 %a = and i4 %y, 7 806 %b = and i4 %x, 7 807 %c = sub i4 %a, %b 808 ret i4 %c 809} 810 811define i4 @test43(i4 %x, i4 %y) { 812; CHECK-LABEL: @test43( 813; CHECK-NEXT: [[A:%.*]] = or i4 [[X:%.*]], -8 814; CHECK-NEXT: [[B:%.*]] = and i4 [[Y:%.*]], 7 815; CHECK-NEXT: [[C:%.*]] = sub nuw i4 [[A]], [[B]] 816; CHECK-NEXT: ret i4 [[C]] 817; 818 %a = or i4 %x, -8 819 %b = and i4 %y, 7 820 %c = sub i4 %a, %b 821 ret i4 %c 822} 823 824define i32 @test44(i32 %x) { 825; CHECK-LABEL: @test44( 826; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[X:%.*]], -32768 827; CHECK-NEXT: ret i32 [[SUB]] 828; 829 %sub = sub nsw i32 %x, 32768 830 ret i32 %sub 831} 832 833define i32 @test45(i32 %x, i32 %y) { 834; CHECK-LABEL: @test45( 835; CHECK-NEXT: [[SUB:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 836; CHECK-NEXT: ret i32 [[SUB]] 837; 838 %or = or i32 %x, %y 839 %xor = xor i32 %x, %y 840 %sub = sub i32 %or, %xor 841 ret i32 %sub 842} 843 844define i32 @test45commuted(i32 %x, i32 %y) { 845; CHECK-LABEL: @test45commuted( 846; CHECK-NEXT: [[SUB:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 847; CHECK-NEXT: ret i32 [[SUB]] 848; 849 %or = or i32 %x, %y 850 %xor = xor i32 %y, %x 851 %sub = sub i32 %or, %xor 852 ret i32 %sub 853} 854 855define i32 @test46(i32 %x, i32 %y) { 856; CHECK-LABEL: @test46( 857; CHECK-NEXT: [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1 858; CHECK-NEXT: [[SUB:%.*]] = and i32 [[X_NOT]], [[Y:%.*]] 859; CHECK-NEXT: ret i32 [[SUB]] 860; 861 %or = or i32 %x, %y 862 %sub = sub i32 %or, %x 863 ret i32 %sub 864} 865 866define i32 @test46commuted(i32 %x, i32 %y) { 867; CHECK-LABEL: @test46commuted( 868; CHECK-NEXT: [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1 869; CHECK-NEXT: [[SUB:%.*]] = and i32 [[X_NOT]], [[Y:%.*]] 870; CHECK-NEXT: ret i32 [[SUB]] 871; 872 %or = or i32 %y, %x 873 %sub = sub i32 %or, %x 874 ret i32 %sub 875} 876 877define i32 @test47(i1 %A, i32 %B, i32 %C, i32 %D) { 878; CHECK-LABEL: @test47( 879; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[D:%.*]], [[C:%.*]] 880; CHECK-NEXT: [[SUB:%.*]] = select i1 [[A:%.*]], i32 [[TMP1]], i32 0 881; CHECK-NEXT: ret i32 [[SUB]] 882; 883 %sel0 = select i1 %A, i32 %D, i32 %B 884 %sel1 = select i1 %A, i32 %C, i32 %B 885 %sub = sub i32 %sel0, %sel1 886 ret i32 %sub 887} 888 889define i32 @test48(i1 %A, i32 %B, i32 %C, i32 %D) { 890; CHECK-LABEL: @test48( 891; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[D:%.*]], [[C:%.*]] 892; CHECK-NEXT: [[SUB:%.*]] = select i1 [[A:%.*]], i32 0, i32 [[TMP1]] 893; CHECK-NEXT: ret i32 [[SUB]] 894; 895 %sel0 = select i1 %A, i32 %B, i32 %D 896 %sel1 = select i1 %A, i32 %B, i32 %C 897 %sub = sub i32 %sel0, %sel1 898 ret i32 %sub 899} 900 901define i32 @test49(i32 %X) { 902; CHECK-LABEL: @test49( 903; CHECK-NEXT: [[SUB:%.*]] = sub i32 1, [[X:%.*]] 904; CHECK-NEXT: [[RES:%.*]] = and i32 [[SUB]], 64 905; CHECK-NEXT: ret i32 [[RES]] 906; 907 %sub = sub i32 129, %X 908 %res = and i32 %sub, 64 909 ret i32 %res 910} 911 912define i32 @test50(i32 %X) { 913; CHECK-LABEL: @test50( 914; CHECK-NEXT: [[SUB:%.*]] = sub i32 1, [[X:%.*]] 915; CHECK-NEXT: [[RES:%.*]] = and i32 [[SUB]], 127 916; CHECK-NEXT: ret i32 [[RES]] 917; 918 %sub = sub i32 129, %X 919 %res = and i32 %sub, 127 920 ret i32 %res 921} 922 923define i32 @test51(i32 %X) { 924; CHECK-LABEL: @test51( 925; CHECK-NEXT: [[SUB:%.*]] = sub i32 126, [[X:%.*]] 926; CHECK-NEXT: [[RES:%.*]] = and i32 [[SUB]], 64 927; CHECK-NEXT: ret i32 [[RES]] 928; 929 %sub = sub i32 254, %X 930 %res = and i32 %sub, 64 931 ret i32 %res 932} 933 934define i32 @test52(i32 %X) { 935; CHECK-LABEL: @test52( 936; CHECK-NEXT: [[SUB:%.*]] = sub i32 126, [[X:%.*]] 937; CHECK-NEXT: [[RES:%.*]] = and i32 [[SUB]], 127 938; CHECK-NEXT: ret i32 [[RES]] 939; 940 %sub = sub i32 254, %X 941 %res = and i32 %sub, 127 942 ret i32 %res 943} 944 945define <2 x i1> @test53(<2 x i1> %A, <2 x i1> %B) { 946; CHECK-LABEL: @test53( 947; CHECK-NEXT: [[SUB:%.*]] = xor <2 x i1> [[B:%.*]], [[A:%.*]] 948; CHECK-NEXT: ret <2 x i1> [[SUB]] 949; 950 %sub = sub <2 x i1> %A, %B 951 ret <2 x i1> %sub 952} 953 954define i32 @test54(i1 %C) { 955; CHECK-LABEL: @test54( 956; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 -877, i32 113 957; CHECK-NEXT: ret i32 [[V]] 958; 959 %A = select i1 %C, i32 1000, i32 10 960 %V = sub i32 123, %A 961 ret i32 %V 962} 963 964define <2 x i32> @test54vec(i1 %C) { 965; CHECK-LABEL: @test54vec( 966; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 -877, i32 -877>, <2 x i32> <i32 113, i32 113> 967; CHECK-NEXT: ret <2 x i32> [[V]] 968; 969 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10> 970 %V = sub <2 x i32> <i32 123, i32 123>, %A 971 ret <2 x i32> %V 972} 973 974define <2 x i32> @test54vec2(i1 %C) { 975; CHECK-LABEL: @test54vec2( 976; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 -877, i32 -2167>, <2 x i32> <i32 113, i32 303> 977; CHECK-NEXT: ret <2 x i32> [[V]] 978; 979 %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30> 980 %V = sub <2 x i32> <i32 123, i32 333>, %A 981 ret <2 x i32> %V 982} 983 984define i32 @test55(i1 %which) { 985; CHECK-LABEL: @test55( 986; CHECK-NEXT: entry: 987; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 988; CHECK: delay: 989; CHECK-NEXT: br label [[FINAL]] 990; CHECK: final: 991; CHECK-NEXT: [[A_NEG:%.*]] = phi i32 [ -877, [[ENTRY:%.*]] ], [ 113, [[DELAY]] ] 992; CHECK-NEXT: ret i32 [[A_NEG]] 993; 994entry: 995 br i1 %which, label %final, label %delay 996 997delay: 998 br label %final 999 1000final: 1001 %A = phi i32 [ 1000, %entry ], [ 10, %delay ] 1002 %value = sub i32 123, %A 1003 ret i32 %value 1004} 1005 1006define <2 x i32> @test55vec(i1 %which) { 1007; CHECK-LABEL: @test55vec( 1008; CHECK-NEXT: entry: 1009; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 1010; CHECK: delay: 1011; CHECK-NEXT: br label [[FINAL]] 1012; CHECK: final: 1013; CHECK-NEXT: [[A_NEG:%.*]] = phi <2 x i32> [ <i32 -877, i32 -877>, [[ENTRY:%.*]] ], [ <i32 113, i32 113>, [[DELAY]] ] 1014; CHECK-NEXT: ret <2 x i32> [[A_NEG]] 1015; 1016entry: 1017 br i1 %which, label %final, label %delay 1018 1019delay: 1020 br label %final 1021 1022final: 1023 %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ] 1024 %value = sub <2 x i32> <i32 123, i32 123>, %A 1025 ret <2 x i32> %value 1026} 1027 1028define <2 x i32> @test55vec2(i1 %which) { 1029; CHECK-LABEL: @test55vec2( 1030; CHECK-NEXT: entry: 1031; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 1032; CHECK: delay: 1033; CHECK-NEXT: br label [[FINAL]] 1034; CHECK: final: 1035; CHECK-NEXT: [[A_NEG:%.*]] = phi <2 x i32> [ <i32 -877, i32 -2167>, [[ENTRY:%.*]] ], [ <i32 113, i32 303>, [[DELAY]] ] 1036; CHECK-NEXT: ret <2 x i32> [[A_NEG]] 1037; 1038entry: 1039 br i1 %which, label %final, label %delay 1040 1041delay: 1042 br label %final 1043 1044final: 1045 %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ] 1046 %value = sub <2 x i32> <i32 123, i32 333>, %A 1047 ret <2 x i32> %value 1048} 1049 1050define i32 @test56(i32 %A, i32 %B) { 1051; CHECK-LABEL: @test56( 1052; CHECK-NEXT: [[Y:%.*]] = sub i32 0, [[B:%.*]] 1053; CHECK-NEXT: ret i32 [[Y]] 1054; 1055 %X = add i32 %A, %B 1056 %Y = sub i32 %A, %X 1057 ret i32 %Y 1058} 1059 1060define i32 @test57(i32 %A, i32 %B) { 1061; CHECK-LABEL: @test57( 1062; CHECK-NEXT: [[Y:%.*]] = sub i32 0, [[B:%.*]] 1063; CHECK-NEXT: ret i32 [[Y]] 1064; 1065 %X = add i32 %B, %A 1066 %Y = sub i32 %A, %X 1067 ret i32 %Y 1068} 1069 1070@dummy_global1 = external global i8* 1071@dummy_global2 = external global i8* 1072 1073define i64 @test58([100 x [100 x i8]]* %foo, i64 %i, i64 %j) { 1074; Note the reassociate pass and another instcombine pass will further optimize this to 1075; "%sub = i64 %i, %j, ret i64 %sub" 1076; gep1 and gep2 have only one use 1077; CHECK-LABEL: @test58( 1078; CHECK-NEXT: [[GEP1_OFFS:%.*]] = add nsw i64 [[I:%.*]], 4200 1079; CHECK-NEXT: [[GEP2_OFFS:%.*]] = add nsw i64 [[J:%.*]], 4200 1080; CHECK-NEXT: [[GEPDIFF:%.*]] = sub nsw i64 [[GEP1_OFFS]], [[GEP2_OFFS]] 1081; CHECK-NEXT: ret i64 [[GEPDIFF]] 1082; 1083 %gep1 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 %i 1084 %gep2 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 %j 1085 %cast1 = ptrtoint i8* %gep1 to i64 1086 %cast2 = ptrtoint i8* %gep2 to i64 1087 %sub = sub i64 %cast1, %cast2 1088 ret i64 %sub 1089} 1090 1091define i64 @test59([100 x [100 x i8]]* %foo, i64 %i) { 1092; CHECK-LABEL: @test59( 1093; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* [[FOO:%.*]], i64 0, i64 42, i64 [[I:%.*]] 1094; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* [[FOO]], i64 0, i64 42, i64 0 1095; CHECK-NEXT: store i8* [[GEP1]], i8** @dummy_global1, align 8 1096; CHECK-NEXT: store i8* [[GEP2]], i8** @dummy_global2, align 8 1097; CHECK-NEXT: ret i64 [[I]] 1098; 1099; gep1 and gep2 have more than one uses 1100 %gep1 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 %i 1101 %gep2 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 0 1102 %cast1 = ptrtoint i8* %gep1 to i64 1103 %cast2 = ptrtoint i8* %gep2 to i64 1104 %sub = sub i64 %cast1, %cast2 1105 store i8* %gep1, i8** @dummy_global1 1106 store i8* %gep2, i8** @dummy_global2 1107 ret i64 %sub 1108} 1109 1110define i64 @test60([100 x [100 x i8]]* %foo, i64 %i, i64 %j) { 1111; CHECK-LABEL: @test60( 1112; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* [[FOO:%.*]], i64 0, i64 [[J:%.*]], i64 [[I:%.*]] 1113; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* [[FOO]], i64 0, i64 42, i64 0 1114; CHECK-NEXT: [[CAST1:%.*]] = ptrtoint i8* [[GEP1]] to i64 1115; CHECK-NEXT: [[CAST2:%.*]] = ptrtoint i8* [[GEP2]] to i64 1116; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[CAST1]], [[CAST2]] 1117; CHECK-NEXT: store i8* [[GEP1]], i8** @dummy_global1, align 8 1118; CHECK-NEXT: ret i64 [[SUB]] 1119; 1120; gep1 has a non-constant index and more than one uses. Shouldn't duplicate the arithmetic. 1121 %gep1 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 %j, i64 %i 1122 %gep2 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 0 1123 %cast1 = ptrtoint i8* %gep1 to i64 1124 %cast2 = ptrtoint i8* %gep2 to i64 1125 %sub = sub i64 %cast1, %cast2 1126 store i8* %gep1, i8** @dummy_global1 1127 ret i64 %sub 1128} 1129 1130define i64 @test61([100 x [100 x i8]]* %foo, i64 %i, i64 %j) { 1131; CHECK-LABEL: @test61( 1132; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* [[FOO:%.*]], i64 0, i64 42, i64 0 1133; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* [[FOO]], i64 0, i64 [[J:%.*]], i64 [[I:%.*]] 1134; CHECK-NEXT: [[CAST1:%.*]] = ptrtoint i8* [[GEP1]] to i64 1135; CHECK-NEXT: [[CAST2:%.*]] = ptrtoint i8* [[GEP2]] to i64 1136; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[CAST1]], [[CAST2]] 1137; CHECK-NEXT: store i8* [[GEP2]], i8** @dummy_global2, align 8 1138; CHECK-NEXT: ret i64 [[SUB]] 1139; 1140; gep2 has a non-constant index and more than one uses. Shouldn't duplicate the arithmetic. 1141 %gep1 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 0 1142 %gep2 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 %j, i64 %i 1143 %cast1 = ptrtoint i8* %gep1 to i64 1144 %cast2 = ptrtoint i8* %gep2 to i64 1145 %sub = sub i64 %cast1, %cast2 1146 store i8* %gep2, i8** @dummy_global2 1147 ret i64 %sub 1148} 1149 1150define i32 @test62(i32 %A) { 1151; CHECK-LABEL: @test62( 1152; CHECK-NEXT: [[B_NEG:%.*]] = mul i32 [[A:%.*]], -2 1153; CHECK-NEXT: [[C:%.*]] = add i32 [[B_NEG]], 2 1154; CHECK-NEXT: ret i32 [[C]] 1155; 1156 %B = sub i32 1, %A 1157 %C = shl i32 %B, 1 1158 ret i32 %C 1159} 1160 1161define <2 x i32> @test62vec(<2 x i32> %A) { 1162; CHECK-LABEL: @test62vec( 1163; CHECK-NEXT: [[B_NEG:%.*]] = mul <2 x i32> [[A:%.*]], <i32 -2, i32 -2> 1164; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[B_NEG]], <i32 2, i32 2> 1165; CHECK-NEXT: ret <2 x i32> [[C]] 1166; 1167 %B = sub <2 x i32> <i32 1, i32 1>, %A 1168 %C = shl <2 x i32> %B, <i32 1, i32 1> 1169 ret <2 x i32> %C 1170} 1171 1172define i32 @test63(i32 %A) { 1173; CHECK-LABEL: @test63( 1174; CHECK-NEXT: [[B_NEG_NEG:%.*]] = shl i32 [[A:%.*]], 1 1175; CHECK-NEXT: ret i32 [[B_NEG_NEG]] 1176; 1177 %B = sub i32 1, %A 1178 %C = shl i32 %B, 1 1179 %D = sub i32 2, %C 1180 ret i32 %D 1181} 1182 1183define <2 x i32> @test63vec(<2 x i32> %A) { 1184; CHECK-LABEL: @test63vec( 1185; CHECK-NEXT: [[B_NEG_NEG:%.*]] = shl <2 x i32> [[A:%.*]], <i32 1, i32 1> 1186; CHECK-NEXT: ret <2 x i32> [[B_NEG_NEG]] 1187; 1188 %B = sub <2 x i32> <i32 1, i32 1>, %A 1189 %C = shl <2 x i32> %B, <i32 1, i32 1> 1190 %D = sub <2 x i32> <i32 2, i32 2>, %C 1191 ret <2 x i32> %D 1192} 1193 1194define i32 @test64(i32 %x) { 1195; CHECK-LABEL: @test64( 1196; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 255 1197; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 255 1198; CHECK-NEXT: [[DOTNEG:%.*]] = add nsw i32 [[TMP2]], 1 1199; CHECK-NEXT: ret i32 [[DOTNEG]] 1200; 1201 %1 = xor i32 %x, -1 1202 %2 = icmp sgt i32 %1, -256 1203 %3 = select i1 %2, i32 %1, i32 -256 1204 %res = sub i32 0, %3 1205 ret i32 %res 1206} 1207 1208define i32 @test65(i32 %x) { 1209; CHECK-LABEL: @test65( 1210; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], -256 1211; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 -256 1212; CHECK-NEXT: [[DOTNEG:%.*]] = add i32 [[TMP2]], 1 1213; CHECK-NEXT: ret i32 [[DOTNEG]] 1214; 1215 %1 = xor i32 %x, -1 1216 %2 = icmp slt i32 %1, 255 1217 %3 = select i1 %2, i32 %1, i32 255 1218 %res = sub i32 0, %3 1219 ret i32 %res 1220} 1221 1222define i32 @test66(i32 %x) { 1223; CHECK-LABEL: @test66( 1224; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[X:%.*]], -101 1225; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 -101 1226; CHECK-NEXT: [[DOTNEG:%.*]] = add nuw i32 [[TMP2]], 1 1227; CHECK-NEXT: ret i32 [[DOTNEG]] 1228; 1229 %1 = xor i32 %x, -1 1230 %2 = icmp ugt i32 %1, 100 1231 %3 = select i1 %2, i32 %1, i32 100 1232 %res = sub i32 0, %3 1233 ret i32 %res 1234} 1235 1236define i32 @test67(i32 %x) { 1237; CHECK-LABEL: @test67( 1238; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[X:%.*]], 100 1239; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 100 1240; CHECK-NEXT: [[DOTNEG:%.*]] = add i32 [[TMP2]], 1 1241; CHECK-NEXT: ret i32 [[DOTNEG]] 1242; 1243 %1 = xor i32 %x, -1 1244 %2 = icmp ult i32 %1, -101 1245 %3 = select i1 %2, i32 %1, i32 -101 1246 %res = sub i32 0, %3 1247 ret i32 %res 1248} 1249 1250; Check splat vectors too 1251define <2 x i32> @test68(<2 x i32> %x) { 1252; CHECK-LABEL: @test68( 1253; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 255, i32 255> 1254; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[X]], <2 x i32> <i32 255, i32 255> 1255; CHECK-NEXT: [[DOTNEG:%.*]] = add nsw <2 x i32> [[TMP2]], <i32 1, i32 1> 1256; CHECK-NEXT: ret <2 x i32> [[DOTNEG]] 1257; 1258 %1 = xor <2 x i32> %x, <i32 -1, i32 -1> 1259 %2 = icmp sgt <2 x i32> %1, <i32 -256, i32 -256> 1260 %3 = select <2 x i1> %2, <2 x i32> %1, <2 x i32> <i32 -256, i32 -256> 1261 %res = sub <2 x i32> zeroinitializer, %3 1262 ret <2 x i32> %res 1263} 1264 1265; And non-splat constant vectors. 1266define <2 x i32> @test69(<2 x i32> %x) { 1267; CHECK-LABEL: @test69( 1268; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 255, i32 127> 1269; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[X]], <2 x i32> <i32 255, i32 127> 1270; CHECK-NEXT: [[DOTNEG:%.*]] = add <2 x i32> [[TMP2]], <i32 1, i32 1> 1271; CHECK-NEXT: ret <2 x i32> [[DOTNEG]] 1272; 1273 %1 = xor <2 x i32> %x, <i32 -1, i32 -1> 1274 %2 = icmp sgt <2 x i32> %1, <i32 -256, i32 -128> 1275 %3 = select <2 x i1> %2, <2 x i32> %1, <2 x i32> <i32 -256, i32 -128> 1276 %res = sub <2 x i32> zeroinitializer, %3 1277 ret <2 x i32> %res 1278} 1279 1280; Check (X | Y) - Y --> X & ~Y when Y is a constant 1281define i32 @test70(i32 %A) { 1282; CHECK-LABEL: @test70( 1283; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], -124 1284; CHECK-NEXT: ret i32 [[TMP1]] 1285; 1286 %B = or i32 %A, 123 1287 %C = sub i32 %B, 123 1288 ret i32 %C 1289} 1290 1291; Check (X | Y) - Y --> (X | Y) ^ Y doesn't happen where (X | Y) has multiple uses 1292define i32 @test71(i32 %A, i32 %B) { 1293; CHECK-LABEL: @test71( 1294; CHECK-NEXT: [[C:%.*]] = or i32 [[A:%.*]], [[B:%.*]] 1295; CHECK-NEXT: [[D:%.*]] = sub i32 [[C]], [[B]] 1296; CHECK-NEXT: [[E:%.*]] = mul i32 [[C]], [[D]] 1297; CHECK-NEXT: ret i32 [[E]] 1298; 1299 %C = or i32 %A, %B 1300 %D = sub i32 %C, %B 1301 %E = mul i32 %C, %D 1302 ret i32 %E 1303} 1304 1305; Check (X | Y) - Y --> X & ~Y where X and Y are vectors 1306define <2 x i32> @test72(<2 x i32> %A, <2 x i32> %B) { 1307; CHECK-LABEL: @test72( 1308; CHECK-NEXT: [[B_NOT:%.*]] = xor <2 x i32> [[B:%.*]], <i32 -1, i32 -1> 1309; CHECK-NEXT: [[D:%.*]] = and <2 x i32> [[B_NOT]], [[A:%.*]] 1310; CHECK-NEXT: ret <2 x i32> [[D]] 1311; 1312 %C = or <2 x i32> %A, %B 1313 %D = sub <2 x i32> %C, %B 1314 ret <2 x i32> %D 1315} 1316 1317; Check reversing sub operands won't trigger (X | Y) - Y --> X & ~Y 1318define i32 @test73(i32 %A, i32 %B) { 1319; CHECK-LABEL: @test73( 1320; CHECK-NEXT: [[C:%.*]] = or i32 [[A:%.*]], [[B:%.*]] 1321; CHECK-NEXT: [[D:%.*]] = sub i32 [[B]], [[C]] 1322; CHECK-NEXT: ret i32 [[D]] 1323; 1324 %C = or i32 %A, %B 1325 %D = sub i32 %B, %C 1326 ret i32 %D 1327} 1328 1329define i32 @nsw_inference1(i32 %x, i32 %y) { 1330; CHECK-LABEL: @nsw_inference1( 1331; CHECK-NEXT: [[X2:%.*]] = or i32 [[X:%.*]], 1024 1332; CHECK-NEXT: [[Y2:%.*]] = and i32 [[Y:%.*]], 1 1333; CHECK-NEXT: [[Z:%.*]] = sub nuw nsw i32 [[X2]], [[Y2]] 1334; CHECK-NEXT: ret i32 [[Z]] 1335; 1336 %x2 = or i32 %x, 1024 1337 %y2 = and i32 %y, 1 1338 %z = sub i32 %x2, %y2 1339 ret i32 %z 1340} 1341 1342define i32 @nsw_inference2(i32 %x, i32 %y) { 1343; CHECK-LABEL: @nsw_inference2( 1344; CHECK-NEXT: [[X2:%.*]] = and i32 [[X:%.*]], -1025 1345; CHECK-NEXT: [[Y2:%.*]] = or i32 [[Y:%.*]], -2 1346; CHECK-NEXT: [[Z:%.*]] = sub nsw i32 [[X2]], [[Y2]] 1347; CHECK-NEXT: ret i32 [[Z]] 1348; 1349 %x2 = and i32 %x, -1025 1350 %y2 = or i32 %y, -2 1351 %z = sub i32 %x2, %y2 1352 ret i32 %z 1353} 1354 1355define i8 @test74(i8 %x, i8 %y) { 1356; CHECK-LABEL: @test74( 1357; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], [[Y:%.*]] 1358; CHECK-NEXT: call void @use8(i8 [[T0]]) 1359; CHECK-NEXT: [[T1:%.*]] = sub i8 [[X]], [[T0]] 1360; CHECK-NEXT: ret i8 [[T1]] 1361; 1362 %t0 = and i8 %x, %y 1363 call void @use8(i8 %t0) 1364 %t1 = sub i8 %x, %t0 1365 ret i8 %t1 1366} 1367 1368define i8 @test75(i8 %x) { 1369; CHECK-LABEL: @test75( 1370; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], -8 1371; CHECK-NEXT: call void @use8(i8 [[T0]]) 1372; CHECK-NEXT: [[T1:%.*]] = and i8 [[X]], 7 1373; CHECK-NEXT: ret i8 [[T1]] 1374; 1375 %t0 = and i8 %x, -8 1376 call void @use8(i8 %t0) 1377 %t1 = sub i8 %x, %t0 1378 ret i8 %t1 1379} 1380 1381; ((w-x) + y) - z --> (w+y) - (x+z) 1382 1383define i8 @sub_add_sub_reassoc(i8 %w, i8 %x, i8 %y, i8 %z) { 1384; CHECK-LABEL: @sub_add_sub_reassoc( 1385; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[W:%.*]], [[Y:%.*]] 1386; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[X:%.*]], [[Z:%.*]] 1387; CHECK-NEXT: [[S2:%.*]] = sub i8 [[TMP1]], [[TMP2]] 1388; CHECK-NEXT: ret i8 [[S2]] 1389; 1390 %s1 = sub i8 %w, %x 1391 %a = add i8 %s1, %y 1392 %s2 = sub i8 %a, %z 1393 ret i8 %s2 1394} 1395 1396; vectors work too. 1397 1398define <2 x i8> @sub_add_sub_reassoc_commute(<2 x i8> %w, <2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 1399; CHECK-LABEL: @sub_add_sub_reassoc_commute( 1400; CHECK-NEXT: [[D:%.*]] = sdiv <2 x i8> [[Y:%.*]], <i8 42, i8 -42> 1401; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[D]], [[W:%.*]] 1402; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i8> [[X:%.*]], [[Z:%.*]] 1403; CHECK-NEXT: [[S2:%.*]] = sub <2 x i8> [[TMP1]], [[TMP2]] 1404; CHECK-NEXT: ret <2 x i8> [[S2]] 1405; 1406 %d = sdiv <2 x i8> %y, <i8 42, i8 -42> ; thwart complexity-based canonicalization 1407 %s1 = sub <2 x i8> %w, %x 1408 %a = add <2 x i8> %d, %s1 1409 %s2 = sub <2 x i8> %a, %z 1410 ret <2 x i8> %s2 1411} 1412 1413; (v-w) + (x-y) - z --> (v+x) - (w+y+z) 1414 1415define i8 @sub_add_sub_reassoc_twice(i8 %v, i8 %w, i8 %x, i8 %y, i8 %z) { 1416; CHECK-LABEL: @sub_add_sub_reassoc_twice( 1417; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[W:%.*]], [[Z:%.*]] 1418; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[X:%.*]], [[V:%.*]] 1419; CHECK-NEXT: [[TMP3:%.*]] = add i8 [[TMP1]], [[Y:%.*]] 1420; CHECK-NEXT: [[S3:%.*]] = sub i8 [[TMP2]], [[TMP3]] 1421; CHECK-NEXT: ret i8 [[S3]] 1422; 1423 %s1 = sub i8 %v, %w 1424 %s2 = sub i8 %x, %y 1425 %a = add i8 %s1, %s2 1426 %s3 = sub i8 %a, %z 1427 ret i8 %s3 1428} 1429 1430; negative test - uses 1431 1432define i8 @sub_add_sub_reassoc_use1(i8 %w, i8 %x, i8 %y, i8 %z) { 1433; CHECK-LABEL: @sub_add_sub_reassoc_use1( 1434; CHECK-NEXT: [[S1:%.*]] = sub i8 [[W:%.*]], [[X:%.*]] 1435; CHECK-NEXT: call void @use8(i8 [[S1]]) 1436; CHECK-NEXT: [[A:%.*]] = add i8 [[S1]], [[Y:%.*]] 1437; CHECK-NEXT: [[S2:%.*]] = sub i8 [[A]], [[Z:%.*]] 1438; CHECK-NEXT: ret i8 [[S2]] 1439; 1440 %s1 = sub i8 %w, %x 1441 call void @use8(i8 %s1) 1442 %a = add i8 %s1, %y 1443 %s2 = sub i8 %a, %z 1444 ret i8 %s2 1445} 1446 1447; negative test - uses 1448 1449define i8 @sub_add_sub_reassoc_use2(i8 %w, i8 %x, i8 %y, i8 %z) { 1450; CHECK-LABEL: @sub_add_sub_reassoc_use2( 1451; CHECK-NEXT: [[S1:%.*]] = sub i8 [[W:%.*]], [[X:%.*]] 1452; CHECK-NEXT: [[A:%.*]] = add i8 [[S1]], [[Y:%.*]] 1453; CHECK-NEXT: call void @use8(i8 [[A]]) 1454; CHECK-NEXT: [[S2:%.*]] = sub i8 [[A]], [[Z:%.*]] 1455; CHECK-NEXT: ret i8 [[S2]] 1456; 1457 %s1 = sub i8 %w, %x 1458 %a = add i8 %s1, %y 1459 call void @use8(i8 %a) 1460 %s2 = sub i8 %a, %z 1461 ret i8 %s2 1462} 1463 1464define i8 @sub_mask_lowbits(i8 %x) { 1465; CHECK-LABEL: @sub_mask_lowbits( 1466; CHECK-NEXT: [[A1:%.*]] = add i8 [[X:%.*]], -108 1467; CHECK-NEXT: [[R:%.*]] = and i8 [[A1]], -4 1468; CHECK-NEXT: ret i8 [[R]] 1469; 1470 %a1 = add i8 %x, 148 ; 0x94 1471 %a2 = and i8 %x, 3 1472 %r = sub i8 %a1, %a2 1473 ret i8 %r 1474} 1475 1476; Negative test - low-bit mask must not overlap with offset 1477 1478define i8 @sub_not_mask_lowbits(i8 %x) { 1479; CHECK-LABEL: @sub_not_mask_lowbits( 1480; CHECK-NEXT: [[A1:%.*]] = add i8 [[X:%.*]], 4 1481; CHECK-NEXT: [[A2:%.*]] = and i8 [[X]], 7 1482; CHECK-NEXT: [[R:%.*]] = sub i8 [[A1]], [[A2]] 1483; CHECK-NEXT: ret i8 [[R]] 1484; 1485 %a1 = add i8 %x, 4 1486 %a2 = and i8 %x, 7 1487 %r = sub i8 %a1, %a2 1488 ret i8 %r 1489} 1490 1491define <2 x i8> @sub_mask_lowbits_splat_extra_use(<2 x i8> %x, <2 x i8>* %p) { 1492; CHECK-LABEL: @sub_mask_lowbits_splat_extra_use( 1493; CHECK-NEXT: [[A1:%.*]] = add <2 x i8> [[X:%.*]], <i8 -64, i8 -64> 1494; CHECK-NEXT: [[A2:%.*]] = and <2 x i8> [[X]], <i8 10, i8 10> 1495; CHECK-NEXT: store <2 x i8> [[A2]], <2 x i8>* [[P:%.*]], align 2 1496; CHECK-NEXT: [[R:%.*]] = and <2 x i8> [[A1]], <i8 -11, i8 -11> 1497; CHECK-NEXT: ret <2 x i8> [[R]] 1498; 1499 %a1 = add <2 x i8> %x, <i8 192, i8 192> ; 0xc0 1500 %a2 = and <2 x i8> %x, <i8 10, i8 10> ; 0x0a 1501 store <2 x i8> %a2, <2 x i8>* %p 1502 %r = sub <2 x i8> %a1, %a2 1503 ret <2 x i8> %r 1504} 1505 1506define i16 @sub_nsw_mul_nsw(i16 %x, i16 %y) { 1507; CHECK-LABEL: @sub_nsw_mul_nsw( 1508; CHECK-NEXT: [[TMP1:%.*]] = sub nsw i16 [[X:%.*]], [[Y:%.*]] 1509; CHECK-NEXT: [[R:%.*]] = shl nsw i16 [[TMP1]], 3 1510; CHECK-NEXT: ret i16 [[R]] 1511; 1512 %x8 = mul nsw i16 %x, 8 1513 %y8 = mul nsw i16 %y, 8 1514 %r = sub nsw i16 %x8, %y8 1515 ret i16 %r 1516} 1517 1518define i16 @sub_nuw_mul_nsw(i16 %x, i16 %y) { 1519; CHECK-LABEL: @sub_nuw_mul_nsw( 1520; CHECK-NEXT: [[TMP1:%.*]] = sub i16 [[X:%.*]], [[Y:%.*]] 1521; CHECK-NEXT: [[R:%.*]] = shl i16 [[TMP1]], 2 1522; CHECK-NEXT: ret i16 [[R]] 1523; 1524 %x8 = mul nsw i16 %x, 4 1525 %y8 = mul nsw i16 %y, 4 1526 %r = sub nuw i16 %x8, %y8 1527 ret i16 %r 1528} 1529 1530define i16 @sub_mul_nsw(i16 %x, i16 %y) { 1531; CHECK-LABEL: @sub_mul_nsw( 1532; CHECK-NEXT: [[TMP1:%.*]] = sub i16 [[X:%.*]], [[Y:%.*]] 1533; CHECK-NEXT: [[R:%.*]] = shl i16 [[TMP1]], 4 1534; CHECK-NEXT: ret i16 [[R]] 1535; 1536 %x8 = mul nsw i16 %x, 16 1537 %y8 = mul nsw i16 %y, 16 1538 %r = sub i16 %x8, %y8 1539 ret i16 %r 1540} 1541 1542define i16 @sub_nsw_mul_nuw(i16 %x, i16 %y) { 1543; CHECK-LABEL: @sub_nsw_mul_nuw( 1544; CHECK-NEXT: [[TMP1:%.*]] = sub i16 [[X:%.*]], [[Y:%.*]] 1545; CHECK-NEXT: [[R:%.*]] = shl i16 [[TMP1]], 3 1546; CHECK-NEXT: ret i16 [[R]] 1547; 1548 %x8 = mul nuw i16 %x, 8 1549 %y8 = mul nuw i16 %y, 8 1550 %r = sub nsw i16 %x8, %y8 1551 ret i16 %r 1552} 1553 1554define i16 @sub_nuw_mul_nuw(i16 %x, i16 %y) { 1555; CHECK-LABEL: @sub_nuw_mul_nuw( 1556; CHECK-NEXT: [[TMP1:%.*]] = sub nuw i16 [[X:%.*]], [[Y:%.*]] 1557; CHECK-NEXT: [[R:%.*]] = shl nuw i16 [[TMP1]], 4 1558; CHECK-NEXT: ret i16 [[R]] 1559; 1560 %x8 = mul nuw i16 %x, 16 1561 %y8 = mul nuw i16 %y, 16 1562 %r = sub nuw i16 %x8, %y8 1563 ret i16 %r 1564} 1565 1566define i16 @sub_mul_nuw(i16 %x, i16 %y) { 1567; CHECK-LABEL: @sub_mul_nuw( 1568; CHECK-NEXT: [[TMP1:%.*]] = sub i16 [[X:%.*]], [[Y:%.*]] 1569; CHECK-NEXT: [[R:%.*]] = shl i16 [[TMP1]], 5 1570; CHECK-NEXT: ret i16 [[R]] 1571; 1572 %x8 = mul nuw i16 %x, 32 1573 %y8 = mul nuw i16 %y, 32 1574 %r = sub i16 %x8, %y8 1575 ret i16 %r 1576} 1577