1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=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 (ptr @g to i32) 20; CHECK-NEXT: ret i32 [[R]] 21; 22 %r = sub i32 %x, ptrtoint (ptr @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 (ptr @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 (ptr @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_poison(<2 x i32> %x, <2 x i32> %y) { 134; CHECK-LABEL: @neg_sub_vec_poison( 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 poison>, %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_poison(<2 x i32> %x, <2 x i32> %y) { 144; CHECK-LABEL: @neg_nsw_sub_vec_poison( 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 poison, 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_poison(<2 x i32> %x, <2 x i32> %y) { 154; CHECK-LABEL: @neg_sub_nsw_vec_poison( 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 poison, 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_poison(<2 x i32> %x, <2 x i32> %y) { 166; CHECK-LABEL: @neg_nsw_sub_nsw_vec_poison( 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 poison>, %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_poison_elts(<2 x i8> %x, <2 x i8> %y) { 209; CHECK-LABEL: @notnotsub_vec_poison_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 poison, i8 -1> 214 %ny = xor <2 x i8> %y, <i8 -1, i8 poison> 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 [[A:%.*]], [[B_NOT]] 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 [[A:%.*]], [[B_NOT]] 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:%.*]], splat (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:%.*]], splat (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, ptr %p) { 440; CHECK-LABEL: @test_neg_shl_sub_extra_use1( 441; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[A:%.*]], [[B:%.*]] 442; CHECK-NEXT: store i64 [[SUB]], ptr [[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, ptr %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, ptr %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]], ptr [[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, ptr %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 nsw 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 nuw 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, ptr %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]], ptr [[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, ptr %p 514 ret i64 %neg 515} 516 517define i64 @test_neg_sext_i1_extra_use(i1 %a, i64 %b, ptr %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]], ptr [[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, ptr %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 nuw 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 nsw 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:%.*]], splat (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:%.*]], splat (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 [[X:%.*]], [[TMP1]] 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 [[X:%.*]], [[TMP1]] 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:%.*]], splat (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 <2 x i32> @test44vec(<2 x i32> %x) { 834; CHECK-LABEL: @test44vec( 835; CHECK-NEXT: [[SUB:%.*]] = add nsw <2 x i32> [[X:%.*]], splat (i32 -32768) 836; CHECK-NEXT: ret <2 x i32> [[SUB]] 837; 838 %sub = sub nsw <2 x i32> %x, <i32 32768, i32 32768> 839 ret <2 x i32> %sub 840} 841 842define <vscale x 2 x i32> @test44scalablevec(<vscale x 2 x i32> %x) { 843; CHECK-LABEL: @test44scalablevec( 844; CHECK-NEXT: [[SUB:%.*]] = add nsw <vscale x 2 x i32> [[X:%.*]], splat (i32 -32768) 845; CHECK-NEXT: ret <vscale x 2 x i32> [[SUB]] 846; 847 %sub = sub nsw <vscale x 2 x i32> %x, splat (i32 32768) 848 ret <vscale x 2 x i32> %sub 849} 850 851define <2 x i16> @test44vecminval(<2 x i16> %x) { 852; CHECK-LABEL: @test44vecminval( 853; CHECK-NEXT: [[SUB:%.*]] = xor <2 x i16> [[X:%.*]], splat (i16 -32768) 854; CHECK-NEXT: ret <2 x i16> [[SUB]] 855; 856 %sub = sub nsw <2 x i16> %x, <i16 -32768, i16 -32768> 857 ret <2 x i16> %sub 858} 859 860; FIXME: This isn't combined to xor as above because the pattern in visitSub 861; uses m_ImmConstant which matches Constant but (explicitly) not ConstantExpr. 862define <vscale x 2 x i16> @test44scalablevecminval(<vscale x 2 x i16> %x) { 863; CHECK-LABEL: @test44scalablevecminval( 864; CHECK-NEXT: [[SUB:%.*]] = add <vscale x 2 x i16> [[X:%.*]], splat (i16 -32768) 865; CHECK-NEXT: ret <vscale x 2 x i16> [[SUB]] 866; 867 %sub = sub nsw <vscale x 2 x i16> %x, splat (i16 -32768) 868 ret <vscale x 2 x i16> %sub 869} 870 871define i32 @test45(i32 %x, i32 %y) { 872; CHECK-LABEL: @test45( 873; CHECK-NEXT: [[SUB:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 874; CHECK-NEXT: ret i32 [[SUB]] 875; 876 %or = or i32 %x, %y 877 %xor = xor i32 %x, %y 878 %sub = sub i32 %or, %xor 879 ret i32 %sub 880} 881 882define i32 @test45commuted(i32 %x, i32 %y) { 883; CHECK-LABEL: @test45commuted( 884; CHECK-NEXT: [[SUB:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 885; CHECK-NEXT: ret i32 [[SUB]] 886; 887 %or = or i32 %x, %y 888 %xor = xor i32 %y, %x 889 %sub = sub i32 %or, %xor 890 ret i32 %sub 891} 892 893define i32 @test46(i32 %x, i32 %y) { 894; CHECK-LABEL: @test46( 895; CHECK-NEXT: [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1 896; CHECK-NEXT: [[SUB:%.*]] = and i32 [[Y:%.*]], [[X_NOT]] 897; CHECK-NEXT: ret i32 [[SUB]] 898; 899 %or = or i32 %x, %y 900 %sub = sub i32 %or, %x 901 ret i32 %sub 902} 903 904define i32 @test46commuted(i32 %x, i32 %y) { 905; CHECK-LABEL: @test46commuted( 906; CHECK-NEXT: [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1 907; CHECK-NEXT: [[SUB:%.*]] = and i32 [[Y:%.*]], [[X_NOT]] 908; CHECK-NEXT: ret i32 [[SUB]] 909; 910 %or = or i32 %y, %x 911 %sub = sub i32 %or, %x 912 ret i32 %sub 913} 914 915define i32 @test47(i1 %A, i32 %B, i32 %C, i32 %D) { 916; CHECK-LABEL: @test47( 917; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[D:%.*]], [[C:%.*]] 918; CHECK-NEXT: [[SUB:%.*]] = select i1 [[A:%.*]], i32 [[TMP1]], i32 0 919; CHECK-NEXT: ret i32 [[SUB]] 920; 921 %sel0 = select i1 %A, i32 %D, i32 %B 922 %sel1 = select i1 %A, i32 %C, i32 %B 923 %sub = sub i32 %sel0, %sel1 924 ret i32 %sub 925} 926 927define i32 @test48(i1 %A, i32 %B, i32 %C, i32 %D) { 928; CHECK-LABEL: @test48( 929; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[D:%.*]], [[C:%.*]] 930; CHECK-NEXT: [[SUB:%.*]] = select i1 [[A:%.*]], i32 0, i32 [[TMP1]] 931; CHECK-NEXT: ret i32 [[SUB]] 932; 933 %sel0 = select i1 %A, i32 %B, i32 %D 934 %sel1 = select i1 %A, i32 %B, i32 %C 935 %sub = sub i32 %sel0, %sel1 936 ret i32 %sub 937} 938 939define i32 @test49(i32 %X) { 940; CHECK-LABEL: @test49( 941; CHECK-NEXT: [[SUB:%.*]] = sub i32 1, [[X:%.*]] 942; CHECK-NEXT: [[RES:%.*]] = and i32 [[SUB]], 64 943; CHECK-NEXT: ret i32 [[RES]] 944; 945 %sub = sub i32 129, %X 946 %res = and i32 %sub, 64 947 ret i32 %res 948} 949 950define i32 @test50(i32 %X) { 951; CHECK-LABEL: @test50( 952; CHECK-NEXT: [[SUB:%.*]] = sub i32 1, [[X:%.*]] 953; CHECK-NEXT: [[RES:%.*]] = and i32 [[SUB]], 127 954; CHECK-NEXT: ret i32 [[RES]] 955; 956 %sub = sub i32 129, %X 957 %res = and i32 %sub, 127 958 ret i32 %res 959} 960 961define i32 @test51(i32 %X) { 962; CHECK-LABEL: @test51( 963; CHECK-NEXT: [[SUB:%.*]] = sub i32 126, [[X:%.*]] 964; CHECK-NEXT: [[RES:%.*]] = and i32 [[SUB]], 64 965; CHECK-NEXT: ret i32 [[RES]] 966; 967 %sub = sub i32 254, %X 968 %res = and i32 %sub, 64 969 ret i32 %res 970} 971 972define i32 @test52(i32 %X) { 973; CHECK-LABEL: @test52( 974; CHECK-NEXT: [[SUB:%.*]] = sub i32 126, [[X:%.*]] 975; CHECK-NEXT: [[RES:%.*]] = and i32 [[SUB]], 127 976; CHECK-NEXT: ret i32 [[RES]] 977; 978 %sub = sub i32 254, %X 979 %res = and i32 %sub, 127 980 ret i32 %res 981} 982 983define <2 x i1> @test53(<2 x i1> %A, <2 x i1> %B) { 984; CHECK-LABEL: @test53( 985; CHECK-NEXT: [[SUB:%.*]] = xor <2 x i1> [[B:%.*]], [[A:%.*]] 986; CHECK-NEXT: ret <2 x i1> [[SUB]] 987; 988 %sub = sub <2 x i1> %A, %B 989 ret <2 x i1> %sub 990} 991 992define i32 @test54(i1 %C) { 993; CHECK-LABEL: @test54( 994; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 -877, i32 113 995; CHECK-NEXT: ret i32 [[V]] 996; 997 %A = select i1 %C, i32 1000, i32 10 998 %V = sub i32 123, %A 999 ret i32 %V 1000} 1001 1002define <2 x i32> @test54vec(i1 %C) { 1003; CHECK-LABEL: @test54vec( 1004; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> splat (i32 -877), <2 x i32> splat (i32 113) 1005; CHECK-NEXT: ret <2 x i32> [[V]] 1006; 1007 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10> 1008 %V = sub <2 x i32> <i32 123, i32 123>, %A 1009 ret <2 x i32> %V 1010} 1011 1012define <2 x i32> @test54vec2(i1 %C) { 1013; CHECK-LABEL: @test54vec2( 1014; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 -877, i32 -2167>, <2 x i32> <i32 113, i32 303> 1015; CHECK-NEXT: ret <2 x i32> [[V]] 1016; 1017 %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30> 1018 %V = sub <2 x i32> <i32 123, i32 333>, %A 1019 ret <2 x i32> %V 1020} 1021 1022define i32 @test55(i1 %which) { 1023; CHECK-LABEL: @test55( 1024; CHECK-NEXT: entry: 1025; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 1026; CHECK: delay: 1027; CHECK-NEXT: br label [[FINAL]] 1028; CHECK: final: 1029; CHECK-NEXT: [[A_NEG:%.*]] = phi i32 [ -877, [[ENTRY:%.*]] ], [ 113, [[DELAY]] ] 1030; CHECK-NEXT: ret i32 [[A_NEG]] 1031; 1032entry: 1033 br i1 %which, label %final, label %delay 1034 1035delay: 1036 br label %final 1037 1038final: 1039 %A = phi i32 [ 1000, %entry ], [ 10, %delay ] 1040 %value = sub i32 123, %A 1041 ret i32 %value 1042} 1043 1044define <2 x i32> @test55vec(i1 %which) { 1045; CHECK-LABEL: @test55vec( 1046; CHECK-NEXT: entry: 1047; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 1048; CHECK: delay: 1049; CHECK-NEXT: br label [[FINAL]] 1050; CHECK: final: 1051; CHECK-NEXT: [[A_NEG:%.*]] = phi <2 x i32> [ splat (i32 -877), [[ENTRY:%.*]] ], [ splat (i32 113), [[DELAY]] ] 1052; CHECK-NEXT: ret <2 x i32> [[A_NEG]] 1053; 1054entry: 1055 br i1 %which, label %final, label %delay 1056 1057delay: 1058 br label %final 1059 1060final: 1061 %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ] 1062 %value = sub <2 x i32> <i32 123, i32 123>, %A 1063 ret <2 x i32> %value 1064} 1065 1066define <2 x i32> @test55vec2(i1 %which) { 1067; CHECK-LABEL: @test55vec2( 1068; CHECK-NEXT: entry: 1069; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 1070; CHECK: delay: 1071; CHECK-NEXT: br label [[FINAL]] 1072; CHECK: final: 1073; CHECK-NEXT: [[A_NEG:%.*]] = phi <2 x i32> [ <i32 -877, i32 -2167>, [[ENTRY:%.*]] ], [ <i32 113, i32 303>, [[DELAY]] ] 1074; CHECK-NEXT: ret <2 x i32> [[A_NEG]] 1075; 1076entry: 1077 br i1 %which, label %final, label %delay 1078 1079delay: 1080 br label %final 1081 1082final: 1083 %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ] 1084 %value = sub <2 x i32> <i32 123, i32 333>, %A 1085 ret <2 x i32> %value 1086} 1087 1088define i32 @test56(i32 %A, i32 %B) { 1089; CHECK-LABEL: @test56( 1090; CHECK-NEXT: [[Y:%.*]] = sub i32 0, [[B:%.*]] 1091; CHECK-NEXT: ret i32 [[Y]] 1092; 1093 %X = add i32 %A, %B 1094 %Y = sub i32 %A, %X 1095 ret i32 %Y 1096} 1097 1098define i32 @test57(i32 %A, i32 %B) { 1099; CHECK-LABEL: @test57( 1100; CHECK-NEXT: [[Y:%.*]] = sub i32 0, [[B:%.*]] 1101; CHECK-NEXT: ret i32 [[Y]] 1102; 1103 %X = add i32 %B, %A 1104 %Y = sub i32 %A, %X 1105 ret i32 %Y 1106} 1107 1108@dummy_global1 = external global ptr 1109@dummy_global2 = external global ptr 1110 1111define i64 @test58(ptr %foo, i64 %i, i64 %j) { 1112; CHECK-LABEL: @test58( 1113; CHECK-NEXT: [[GEPDIFF:%.*]] = sub i64 [[I:%.*]], [[J:%.*]] 1114; CHECK-NEXT: ret i64 [[GEPDIFF]] 1115; 1116 %gep1 = getelementptr inbounds [100 x [100 x i8]], ptr %foo, i64 0, i64 42, i64 %i 1117 %gep2 = getelementptr inbounds [100 x [100 x i8]], ptr %foo, i64 0, i64 42, i64 %j 1118 %cast1 = ptrtoint ptr %gep1 to i64 1119 %cast2 = ptrtoint ptr %gep2 to i64 1120 %sub = sub i64 %cast1, %cast2 1121 ret i64 %sub 1122} 1123 1124define i64 @test59(ptr %foo, i64 %i) { 1125; CHECK-LABEL: @test59( 1126; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[FOO:%.*]], i64 [[I:%.*]] 1127; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[TMP1]], i64 4200 1128; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 4200 1129; CHECK-NEXT: store ptr [[GEP1]], ptr @dummy_global1, align 8 1130; CHECK-NEXT: store ptr [[GEP2]], ptr @dummy_global2, align 8 1131; CHECK-NEXT: ret i64 [[I]] 1132; 1133; gep1 and gep2 have more than one uses 1134 %gep1 = getelementptr inbounds [100 x [100 x i8]], ptr %foo, i64 0, i64 42, i64 %i 1135 %gep2 = getelementptr inbounds [100 x [100 x i8]], ptr %foo, i64 0, i64 42, i64 0 1136 %cast1 = ptrtoint ptr %gep1 to i64 1137 %cast2 = ptrtoint ptr %gep2 to i64 1138 %sub = sub i64 %cast1, %cast2 1139 store ptr %gep1, ptr @dummy_global1 1140 store ptr %gep2, ptr @dummy_global2 1141 ret i64 %sub 1142} 1143 1144define i64 @test60(ptr %foo, i64 %i, i64 %j) { 1145; CHECK-LABEL: @test60( 1146; CHECK-NEXT: [[GEP1_IDX:%.*]] = mul nsw i64 [[J:%.*]], 100 1147; CHECK-NEXT: [[GEP1_OFFS:%.*]] = add nsw i64 [[GEP1_IDX]], [[I:%.*]] 1148; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, ptr [[FOO:%.*]], i64 [[GEP1_OFFS]] 1149; CHECK-NEXT: [[GEPDIFF:%.*]] = add nsw i64 [[GEP1_OFFS]], -4200 1150; CHECK-NEXT: store ptr [[GEP1]], ptr @dummy_global1, align 8 1151; CHECK-NEXT: ret i64 [[GEPDIFF]] 1152; 1153; gep1 has a non-constant index and more than one uses. Shouldn't duplicate the arithmetic. 1154 %gep1 = getelementptr inbounds [100 x [100 x i8]], ptr %foo, i64 0, i64 %j, i64 %i 1155 %gep2 = getelementptr inbounds [100 x [100 x i8]], ptr %foo, i64 0, i64 42, i64 0 1156 %cast1 = ptrtoint ptr %gep1 to i64 1157 %cast2 = ptrtoint ptr %gep2 to i64 1158 %sub = sub i64 %cast1, %cast2 1159 store ptr %gep1, ptr @dummy_global1 1160 ret i64 %sub 1161} 1162 1163define i64 @test60_nuw(ptr %foo, i64 %i, i64 %j) { 1164; CHECK-LABEL: @test60_nuw( 1165; CHECK-NEXT: [[GEP1_IDX:%.*]] = mul nuw i64 [[J:%.*]], 100 1166; CHECK-NEXT: [[GEP1_OFFS:%.*]] = add nuw i64 [[GEP1_IDX]], [[I:%.*]] 1167; CHECK-NEXT: [[GEP1:%.*]] = getelementptr nuw i8, ptr [[FOO:%.*]], i64 [[GEP1_OFFS]] 1168; CHECK-NEXT: [[GEPDIFF:%.*]] = add i64 [[GEP1_OFFS]], -4200 1169; CHECK-NEXT: store ptr [[GEP1]], ptr @dummy_global1, align 8 1170; CHECK-NEXT: ret i64 [[GEPDIFF]] 1171; 1172 %gep1 = getelementptr nuw [100 x [100 x i8]], ptr %foo, i64 0, i64 %j, i64 %i 1173 %gep2 = getelementptr nuw [100 x [100 x i8]], ptr %foo, i64 0, i64 42, i64 0 1174 %cast1 = ptrtoint ptr %gep1 to i64 1175 %cast2 = ptrtoint ptr %gep2 to i64 1176 %sub = sub i64 %cast1, %cast2 1177 store ptr %gep1, ptr @dummy_global1 1178 ret i64 %sub 1179} 1180 1181define i64 @test61(ptr %foo, i64 %i, i64 %j) { 1182; CHECK-LABEL: @test61( 1183; CHECK-NEXT: [[GEP2_IDX:%.*]] = mul nsw i64 [[J:%.*]], 100 1184; CHECK-NEXT: [[GEP2_OFFS:%.*]] = add nsw i64 [[GEP2_IDX]], [[I:%.*]] 1185; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i8, ptr [[FOO:%.*]], i64 [[GEP2_OFFS]] 1186; CHECK-NEXT: [[GEPDIFF:%.*]] = sub nsw i64 4200, [[GEP2_OFFS]] 1187; CHECK-NEXT: store ptr [[GEP2]], ptr @dummy_global2, align 8 1188; CHECK-NEXT: ret i64 [[GEPDIFF]] 1189; 1190; gep2 has a non-constant index and more than one uses. Shouldn't duplicate the arithmetic. 1191 %gep1 = getelementptr inbounds [100 x [100 x i8]], ptr %foo, i64 0, i64 42, i64 0 1192 %gep2 = getelementptr inbounds [100 x [100 x i8]], ptr %foo, i64 0, i64 %j, i64 %i 1193 %cast1 = ptrtoint ptr %gep1 to i64 1194 %cast2 = ptrtoint ptr %gep2 to i64 1195 %sub = sub i64 %cast1, %cast2 1196 store ptr %gep2, ptr @dummy_global2 1197 ret i64 %sub 1198} 1199 1200declare void @use.ptr(ptr) 1201 1202define i64 @test_sub_ptradd_multiuse(ptr %p, i64 %idx1, i64 %idx2) { 1203; CHECK-LABEL: @test_sub_ptradd_multiuse( 1204; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[IDX1:%.*]] 1205; CHECK-NEXT: call void @use.ptr(ptr [[P1]]) 1206; CHECK-NEXT: [[GEPDIFF:%.*]] = sub nsw i64 [[IDX1]], [[IDX2:%.*]] 1207; CHECK-NEXT: ret i64 [[GEPDIFF]] 1208; 1209 %p1 = getelementptr inbounds i8, ptr %p, i64 %idx1 1210 call void @use.ptr(ptr %p1) 1211 %p2 = getelementptr inbounds i8, ptr %p, i64 %idx2 1212 %p1.int = ptrtoint ptr %p1 to i64 1213 %p2.int = ptrtoint ptr %p2 to i64 1214 %sub = sub i64 %p1.int, %p2.int 1215 ret i64 %sub 1216} 1217 1218define i32 @test62(i32 %A) { 1219; CHECK-LABEL: @test62( 1220; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[A:%.*]], 1 1221; CHECK-NEXT: [[C:%.*]] = sub i32 2, [[TMP1]] 1222; CHECK-NEXT: ret i32 [[C]] 1223; 1224 %B = sub i32 1, %A 1225 %C = shl i32 %B, 1 1226 ret i32 %C 1227} 1228 1229define <2 x i32> @test62vec(<2 x i32> %A) { 1230; CHECK-LABEL: @test62vec( 1231; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[A:%.*]], splat (i32 1) 1232; CHECK-NEXT: [[C:%.*]] = sub <2 x i32> splat (i32 2), [[TMP1]] 1233; CHECK-NEXT: ret <2 x i32> [[C]] 1234; 1235 %B = sub <2 x i32> <i32 1, i32 1>, %A 1236 %C = shl <2 x i32> %B, <i32 1, i32 1> 1237 ret <2 x i32> %C 1238} 1239 1240define i32 @test63(i32 %A) { 1241; CHECK-LABEL: @test63( 1242; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[A:%.*]], 1 1243; CHECK-NEXT: ret i32 [[TMP1]] 1244; 1245 %B = sub i32 1, %A 1246 %C = shl i32 %B, 1 1247 %D = sub i32 2, %C 1248 ret i32 %D 1249} 1250 1251define <2 x i32> @test63vec(<2 x i32> %A) { 1252; CHECK-LABEL: @test63vec( 1253; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[A:%.*]], splat (i32 1) 1254; CHECK-NEXT: ret <2 x i32> [[TMP1]] 1255; 1256 %B = sub <2 x i32> <i32 1, i32 1>, %A 1257 %C = shl <2 x i32> %B, <i32 1, i32 1> 1258 %D = sub <2 x i32> <i32 2, i32 2>, %C 1259 ret <2 x i32> %D 1260} 1261 1262define i32 @test64(i32 %x) { 1263; CHECK-LABEL: @test64( 1264; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 255) 1265; CHECK-NEXT: [[DOTNEG:%.*]] = add nsw i32 [[TMP1]], 1 1266; CHECK-NEXT: ret i32 [[DOTNEG]] 1267; 1268 %1 = xor i32 %x, -1 1269 %2 = icmp sgt i32 %1, -256 1270 %3 = select i1 %2, i32 %1, i32 -256 1271 %res = sub i32 0, %3 1272 ret i32 %res 1273} 1274 1275define i32 @test65(i32 %x) { 1276; CHECK-LABEL: @test65( 1277; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 -256) 1278; CHECK-NEXT: [[DOTNEG:%.*]] = add i32 [[TMP1]], 1 1279; CHECK-NEXT: ret i32 [[DOTNEG]] 1280; 1281 %1 = xor i32 %x, -1 1282 %2 = icmp slt i32 %1, 255 1283 %3 = select i1 %2, i32 %1, i32 255 1284 %res = sub i32 0, %3 1285 ret i32 %res 1286} 1287 1288define i32 @test66(i32 %x) { 1289; CHECK-LABEL: @test66( 1290; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 -101) 1291; CHECK-NEXT: [[DOTNEG:%.*]] = add nuw i32 [[TMP1]], 1 1292; CHECK-NEXT: ret i32 [[DOTNEG]] 1293; 1294 %1 = xor i32 %x, -1 1295 %2 = icmp ugt i32 %1, 100 1296 %3 = select i1 %2, i32 %1, i32 100 1297 %res = sub i32 0, %3 1298 ret i32 %res 1299} 1300 1301define i32 @test67(i32 %x) { 1302; CHECK-LABEL: @test67( 1303; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 100) 1304; CHECK-NEXT: [[DOTNEG:%.*]] = add i32 [[TMP1]], 1 1305; CHECK-NEXT: ret i32 [[DOTNEG]] 1306; 1307 %1 = xor i32 %x, -1 1308 %2 = icmp ult i32 %1, -101 1309 %3 = select i1 %2, i32 %1, i32 -101 1310 %res = sub i32 0, %3 1311 ret i32 %res 1312} 1313 1314; Check splat vectors too 1315define <2 x i32> @test68(<2 x i32> %x) { 1316; CHECK-LABEL: @test68( 1317; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> splat (i32 255)) 1318; CHECK-NEXT: [[DOTNEG:%.*]] = add nsw <2 x i32> [[TMP1]], splat (i32 1) 1319; CHECK-NEXT: ret <2 x i32> [[DOTNEG]] 1320; 1321 %1 = xor <2 x i32> %x, <i32 -1, i32 -1> 1322 %2 = icmp sgt <2 x i32> %1, <i32 -256, i32 -256> 1323 %3 = select <2 x i1> %2, <2 x i32> %1, <2 x i32> <i32 -256, i32 -256> 1324 %res = sub <2 x i32> zeroinitializer, %3 1325 ret <2 x i32> %res 1326} 1327 1328; And non-splat constant vectors. 1329define <2 x i32> @test69(<2 x i32> %x) { 1330; CHECK-LABEL: @test69( 1331; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 255, i32 127>) 1332; CHECK-NEXT: [[DOTNEG:%.*]] = add <2 x i32> [[TMP1]], splat (i32 1) 1333; CHECK-NEXT: ret <2 x i32> [[DOTNEG]] 1334; 1335 %1 = xor <2 x i32> %x, <i32 -1, i32 -1> 1336 %2 = icmp sgt <2 x i32> %1, <i32 -256, i32 -128> 1337 %3 = select <2 x i1> %2, <2 x i32> %1, <2 x i32> <i32 -256, i32 -128> 1338 %res = sub <2 x i32> zeroinitializer, %3 1339 ret <2 x i32> %res 1340} 1341 1342; Check (X | Y) - Y --> X & ~Y when Y is a constant 1343define i32 @test70(i32 %A) { 1344; CHECK-LABEL: @test70( 1345; CHECK-NEXT: [[C:%.*]] = and i32 [[A:%.*]], -124 1346; CHECK-NEXT: ret i32 [[C]] 1347; 1348 %B = or i32 %A, 123 1349 %C = sub i32 %B, 123 1350 ret i32 %C 1351} 1352 1353; Check (X | Y) - Y --> (X | Y) ^ Y doesn't happen where (X | Y) has multiple uses 1354define i32 @test71(i32 %A, i32 %B) { 1355; CHECK-LABEL: @test71( 1356; CHECK-NEXT: [[C:%.*]] = or i32 [[A:%.*]], [[B:%.*]] 1357; CHECK-NEXT: [[D:%.*]] = sub i32 [[C]], [[B]] 1358; CHECK-NEXT: [[E:%.*]] = mul i32 [[C]], [[D]] 1359; CHECK-NEXT: ret i32 [[E]] 1360; 1361 %C = or i32 %A, %B 1362 %D = sub i32 %C, %B 1363 %E = mul i32 %C, %D 1364 ret i32 %E 1365} 1366 1367; Check (X | Y) - Y --> X & ~Y where X and Y are vectors 1368define <2 x i32> @test72(<2 x i32> %A, <2 x i32> %B) { 1369; CHECK-LABEL: @test72( 1370; CHECK-NEXT: [[B_NOT:%.*]] = xor <2 x i32> [[B:%.*]], splat (i32 -1) 1371; CHECK-NEXT: [[D:%.*]] = and <2 x i32> [[A:%.*]], [[B_NOT]] 1372; CHECK-NEXT: ret <2 x i32> [[D]] 1373; 1374 %C = or <2 x i32> %A, %B 1375 %D = sub <2 x i32> %C, %B 1376 ret <2 x i32> %D 1377} 1378 1379; Check reversing sub operands won't trigger (X | Y) - Y --> X & ~Y 1380define i32 @test73(i32 %A, i32 %B) { 1381; CHECK-LABEL: @test73( 1382; CHECK-NEXT: [[C:%.*]] = or i32 [[A:%.*]], [[B:%.*]] 1383; CHECK-NEXT: [[D:%.*]] = sub i32 [[B]], [[C]] 1384; CHECK-NEXT: ret i32 [[D]] 1385; 1386 %C = or i32 %A, %B 1387 %D = sub i32 %B, %C 1388 ret i32 %D 1389} 1390 1391define i32 @nsw_inference1(i32 %x, i32 %y) { 1392; CHECK-LABEL: @nsw_inference1( 1393; CHECK-NEXT: [[X2:%.*]] = or i32 [[X:%.*]], 1024 1394; CHECK-NEXT: [[Y2:%.*]] = and i32 [[Y:%.*]], 1 1395; CHECK-NEXT: [[Z:%.*]] = sub nuw nsw i32 [[X2]], [[Y2]] 1396; CHECK-NEXT: ret i32 [[Z]] 1397; 1398 %x2 = or i32 %x, 1024 1399 %y2 = and i32 %y, 1 1400 %z = sub i32 %x2, %y2 1401 ret i32 %z 1402} 1403 1404define i32 @nsw_inference2(i32 %x, i32 %y) { 1405; CHECK-LABEL: @nsw_inference2( 1406; CHECK-NEXT: [[X2:%.*]] = and i32 [[X:%.*]], -1025 1407; CHECK-NEXT: [[Y2:%.*]] = or i32 [[Y:%.*]], -2 1408; CHECK-NEXT: [[Z:%.*]] = sub nsw i32 [[X2]], [[Y2]] 1409; CHECK-NEXT: ret i32 [[Z]] 1410; 1411 %x2 = and i32 %x, -1025 1412 %y2 = or i32 %y, -2 1413 %z = sub i32 %x2, %y2 1414 ret i32 %z 1415} 1416 1417define i8 @test74(i8 %x, i8 %y) { 1418; CHECK-LABEL: @test74( 1419; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], [[Y:%.*]] 1420; CHECK-NEXT: call void @use8(i8 [[T0]]) 1421; CHECK-NEXT: [[T1:%.*]] = sub i8 [[X]], [[T0]] 1422; CHECK-NEXT: ret i8 [[T1]] 1423; 1424 %t0 = and i8 %x, %y 1425 call void @use8(i8 %t0) 1426 %t1 = sub i8 %x, %t0 1427 ret i8 %t1 1428} 1429 1430define i8 @test75(i8 %x) { 1431; CHECK-LABEL: @test75( 1432; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], -8 1433; CHECK-NEXT: call void @use8(i8 [[T0]]) 1434; CHECK-NEXT: [[T1:%.*]] = and i8 [[X]], 7 1435; CHECK-NEXT: ret i8 [[T1]] 1436; 1437 %t0 = and i8 %x, -8 1438 call void @use8(i8 %t0) 1439 %t1 = sub i8 %x, %t0 1440 ret i8 %t1 1441} 1442 1443; ((w-x) + y) - z --> (w+y) - (x+z) 1444 1445define i8 @sub_add_sub_reassoc(i8 %w, i8 %x, i8 %y, i8 %z) { 1446; CHECK-LABEL: @sub_add_sub_reassoc( 1447; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[W:%.*]], [[Y:%.*]] 1448; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[X:%.*]], [[Z:%.*]] 1449; CHECK-NEXT: [[S2:%.*]] = sub i8 [[TMP1]], [[TMP2]] 1450; CHECK-NEXT: ret i8 [[S2]] 1451; 1452 %s1 = sub i8 %w, %x 1453 %a = add i8 %s1, %y 1454 %s2 = sub i8 %a, %z 1455 ret i8 %s2 1456} 1457 1458; vectors work too. 1459 1460define <2 x i8> @sub_add_sub_reassoc_commute(<2 x i8> %w, <2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 1461; CHECK-LABEL: @sub_add_sub_reassoc_commute( 1462; CHECK-NEXT: [[D:%.*]] = sdiv <2 x i8> [[Y:%.*]], <i8 42, i8 -42> 1463; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[W:%.*]], [[D]] 1464; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i8> [[X:%.*]], [[Z:%.*]] 1465; CHECK-NEXT: [[S2:%.*]] = sub <2 x i8> [[TMP1]], [[TMP2]] 1466; CHECK-NEXT: ret <2 x i8> [[S2]] 1467; 1468 %d = sdiv <2 x i8> %y, <i8 42, i8 -42> ; thwart complexity-based canonicalization 1469 %s1 = sub <2 x i8> %w, %x 1470 %a = add <2 x i8> %d, %s1 1471 %s2 = sub <2 x i8> %a, %z 1472 ret <2 x i8> %s2 1473} 1474 1475; (v-w) + (x-y) - z --> (v+x) - (w+y+z) 1476 1477define i8 @sub_add_sub_reassoc_twice(i8 %v, i8 %w, i8 %x, i8 %y, i8 %z) { 1478; CHECK-LABEL: @sub_add_sub_reassoc_twice( 1479; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[W:%.*]], [[Z:%.*]] 1480; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[X:%.*]], [[V:%.*]] 1481; CHECK-NEXT: [[TMP3:%.*]] = add i8 [[Y:%.*]], [[TMP1]] 1482; CHECK-NEXT: [[S3:%.*]] = sub i8 [[TMP2]], [[TMP3]] 1483; CHECK-NEXT: ret i8 [[S3]] 1484; 1485 %s1 = sub i8 %v, %w 1486 %s2 = sub i8 %x, %y 1487 %a = add i8 %s1, %s2 1488 %s3 = sub i8 %a, %z 1489 ret i8 %s3 1490} 1491 1492; negative test - uses 1493 1494define i8 @sub_add_sub_reassoc_use1(i8 %w, i8 %x, i8 %y, i8 %z) { 1495; CHECK-LABEL: @sub_add_sub_reassoc_use1( 1496; CHECK-NEXT: [[S1:%.*]] = sub i8 [[W:%.*]], [[X:%.*]] 1497; CHECK-NEXT: call void @use8(i8 [[S1]]) 1498; CHECK-NEXT: [[A:%.*]] = add i8 [[S1]], [[Y:%.*]] 1499; CHECK-NEXT: [[S2:%.*]] = sub i8 [[A]], [[Z:%.*]] 1500; CHECK-NEXT: ret i8 [[S2]] 1501; 1502 %s1 = sub i8 %w, %x 1503 call void @use8(i8 %s1) 1504 %a = add i8 %s1, %y 1505 %s2 = sub i8 %a, %z 1506 ret i8 %s2 1507} 1508 1509; negative test - uses 1510 1511define i8 @sub_add_sub_reassoc_use2(i8 %w, i8 %x, i8 %y, i8 %z) { 1512; CHECK-LABEL: @sub_add_sub_reassoc_use2( 1513; CHECK-NEXT: [[S1:%.*]] = sub i8 [[W:%.*]], [[X:%.*]] 1514; CHECK-NEXT: [[A:%.*]] = add i8 [[S1]], [[Y:%.*]] 1515; CHECK-NEXT: call void @use8(i8 [[A]]) 1516; CHECK-NEXT: [[S2:%.*]] = sub i8 [[A]], [[Z:%.*]] 1517; CHECK-NEXT: ret i8 [[S2]] 1518; 1519 %s1 = sub i8 %w, %x 1520 %a = add i8 %s1, %y 1521 call void @use8(i8 %a) 1522 %s2 = sub i8 %a, %z 1523 ret i8 %s2 1524} 1525 1526define i8 @sub_mask_lowbits(i8 %x) { 1527; CHECK-LABEL: @sub_mask_lowbits( 1528; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -4 1529; CHECK-NEXT: [[R:%.*]] = add i8 [[TMP1]], -108 1530; CHECK-NEXT: ret i8 [[R]] 1531; 1532 %a1 = add i8 %x, 148 ; 0x94 1533 %a2 = and i8 %x, 3 1534 %r = sub i8 %a1, %a2 1535 ret i8 %r 1536} 1537 1538; Negative test - low-bit mask must not overlap with offset 1539 1540define i8 @sub_not_mask_lowbits(i8 %x) { 1541; CHECK-LABEL: @sub_not_mask_lowbits( 1542; CHECK-NEXT: [[A1:%.*]] = add i8 [[X:%.*]], 4 1543; CHECK-NEXT: [[A2:%.*]] = and i8 [[X]], 7 1544; CHECK-NEXT: [[R:%.*]] = sub i8 [[A1]], [[A2]] 1545; CHECK-NEXT: ret i8 [[R]] 1546; 1547 %a1 = add i8 %x, 4 1548 %a2 = and i8 %x, 7 1549 %r = sub i8 %a1, %a2 1550 ret i8 %r 1551} 1552 1553define <2 x i8> @sub_mask_lowbits_splat_extra_use(<2 x i8> %x, ptr %p) { 1554; CHECK-LABEL: @sub_mask_lowbits_splat_extra_use( 1555; CHECK-NEXT: [[A2:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 10) 1556; CHECK-NEXT: store <2 x i8> [[A2]], ptr [[P:%.*]], align 2 1557; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X]], splat (i8 -11) 1558; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[TMP1]], splat (i8 -64) 1559; CHECK-NEXT: ret <2 x i8> [[R]] 1560; 1561 %a1 = add <2 x i8> %x, <i8 192, i8 192> ; 0xc0 1562 %a2 = and <2 x i8> %x, <i8 10, i8 10> ; 0x0a 1563 store <2 x i8> %a2, ptr %p 1564 %r = sub <2 x i8> %a1, %a2 1565 ret <2 x i8> %r 1566} 1567 1568define i16 @sub_nsw_mul_nsw(i16 %x, i16 %y) { 1569; CHECK-LABEL: @sub_nsw_mul_nsw( 1570; CHECK-NEXT: [[TMP1:%.*]] = sub nsw i16 [[X:%.*]], [[Y:%.*]] 1571; CHECK-NEXT: [[R:%.*]] = shl nsw i16 [[TMP1]], 3 1572; CHECK-NEXT: ret i16 [[R]] 1573; 1574 %x8 = mul nsw i16 %x, 8 1575 %y8 = mul nsw i16 %y, 8 1576 %r = sub nsw i16 %x8, %y8 1577 ret i16 %r 1578} 1579 1580define i16 @sub_nuw_mul_nsw(i16 %x, i16 %y) { 1581; CHECK-LABEL: @sub_nuw_mul_nsw( 1582; CHECK-NEXT: [[TMP1:%.*]] = sub i16 [[X:%.*]], [[Y:%.*]] 1583; CHECK-NEXT: [[R:%.*]] = shl i16 [[TMP1]], 2 1584; CHECK-NEXT: ret i16 [[R]] 1585; 1586 %x8 = mul nsw i16 %x, 4 1587 %y8 = mul nsw i16 %y, 4 1588 %r = sub nuw i16 %x8, %y8 1589 ret i16 %r 1590} 1591 1592define i16 @sub_mul_nsw(i16 %x, i16 %y) { 1593; CHECK-LABEL: @sub_mul_nsw( 1594; CHECK-NEXT: [[TMP1:%.*]] = sub i16 [[X:%.*]], [[Y:%.*]] 1595; CHECK-NEXT: [[R:%.*]] = shl i16 [[TMP1]], 4 1596; CHECK-NEXT: ret i16 [[R]] 1597; 1598 %x8 = mul nsw i16 %x, 16 1599 %y8 = mul nsw i16 %y, 16 1600 %r = sub i16 %x8, %y8 1601 ret i16 %r 1602} 1603 1604define i16 @sub_nsw_mul_nuw(i16 %x, i16 %y) { 1605; CHECK-LABEL: @sub_nsw_mul_nuw( 1606; CHECK-NEXT: [[TMP1:%.*]] = sub i16 [[X:%.*]], [[Y:%.*]] 1607; CHECK-NEXT: [[R:%.*]] = shl i16 [[TMP1]], 3 1608; CHECK-NEXT: ret i16 [[R]] 1609; 1610 %x8 = mul nuw i16 %x, 8 1611 %y8 = mul nuw i16 %y, 8 1612 %r = sub nsw i16 %x8, %y8 1613 ret i16 %r 1614} 1615 1616define i16 @sub_nuw_mul_nuw(i16 %x, i16 %y) { 1617; CHECK-LABEL: @sub_nuw_mul_nuw( 1618; CHECK-NEXT: [[TMP1:%.*]] = sub nuw i16 [[X:%.*]], [[Y:%.*]] 1619; CHECK-NEXT: [[R:%.*]] = shl nuw i16 [[TMP1]], 4 1620; CHECK-NEXT: ret i16 [[R]] 1621; 1622 %x8 = mul nuw i16 %x, 16 1623 %y8 = mul nuw i16 %y, 16 1624 %r = sub nuw i16 %x8, %y8 1625 ret i16 %r 1626} 1627 1628define i16 @sub_mul_nuw(i16 %x, i16 %y) { 1629; CHECK-LABEL: @sub_mul_nuw( 1630; CHECK-NEXT: [[TMP1:%.*]] = sub i16 [[X:%.*]], [[Y:%.*]] 1631; CHECK-NEXT: [[R:%.*]] = shl i16 [[TMP1]], 5 1632; CHECK-NEXT: ret i16 [[R]] 1633; 1634 %x8 = mul nuw i16 %x, 32 1635 %y8 = mul nuw i16 %y, 32 1636 %r = sub i16 %x8, %y8 1637 ret i16 %r 1638} 1639define i32 @and_test(i32 %x, i32 %y) { 1640; CHECK-LABEL: @and_test( 1641; CHECK-NEXT: [[R:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 1642; CHECK-NEXT: ret i32 [[R]] 1643; 1644 %a = add i32 %x, %y 1645 %o = or i32 %x, %y 1646 %r = sub i32 %a, %o 1647 ret i32 %r 1648} 1649 1650define i32 @and_test2(i32 %x, i32 %y) { 1651; CHECK-LABEL: @and_test2( 1652; CHECK-NEXT: [[R:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 1653; CHECK-NEXT: ret i32 [[R]] 1654; 1655 %a = add i32 %x, %y 1656 %o = or i32 %y, %x 1657 %r = sub i32 %a, %o 1658 ret i32 %r 1659} 1660 1661define i32 @and_test3(i32 %x, i32 %y) { 1662; CHECK-LABEL: @and_test3( 1663; CHECK-NEXT: [[R:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 1664; CHECK-NEXT: ret i32 [[R]] 1665; 1666 %a = add i32 %y, %x 1667 %o = or i32 %x, %y 1668 %r = sub i32 %a, %o 1669 ret i32 %r 1670} 1671 1672 1673define <2 x i8> @and_vec(<2 x i8> %X, <2 x i8> %Y) { 1674; CHECK-LABEL: @and_vec( 1675; CHECK-NEXT: [[R:%.*]] = and <2 x i8> [[X:%.*]], [[Y:%.*]] 1676; CHECK-NEXT: ret <2 x i8> [[R]] 1677; 1678 %a = add <2 x i8> %X, %Y 1679 %o = or <2 x i8> %X, %Y 1680 %r = sub <2 x i8> %a, %o 1681 ret <2 x i8> %r 1682} 1683 1684define i32 @or_test(i32 %x, i32 %y) { 1685; CHECK-LABEL: @or_test( 1686; CHECK-NEXT: [[R:%.*]] = or i32 [[X:%.*]], [[Y:%.*]] 1687; CHECK-NEXT: ret i32 [[R]] 1688; 1689 %a = add i32 %x, %y 1690 %b = and i32 %x, %y 1691 %r = sub i32 %a, %b 1692 ret i32 %r 1693} 1694 1695define i32 @or_test2(i32 %x, i32 %y) { 1696; CHECK-LABEL: @or_test2( 1697; CHECK-NEXT: [[R:%.*]] = or i32 [[X:%.*]], [[Y:%.*]] 1698; CHECK-NEXT: ret i32 [[R]] 1699; 1700 %a = add i32 %x, %y 1701 %b = and i32 %y, %x 1702 %r = sub i32 %a, %b 1703 ret i32 %r 1704} 1705 1706define i32 @or_test3(i32 %x, i32 %y) { 1707; CHECK-LABEL: @or_test3( 1708; CHECK-NEXT: [[R:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] 1709; CHECK-NEXT: ret i32 [[R]] 1710; 1711 %a = add i32 %y, %x 1712 %b = and i32 %x, %y 1713 %r = sub i32 %a, %b 1714 ret i32 %r 1715} 1716 1717define <2 x i8> @or_vec(<2 x i8> %X, <2 x i8> %Y) { 1718; CHECK-LABEL: @or_vec( 1719; CHECK-NEXT: [[R:%.*]] = or <2 x i8> [[X:%.*]], [[Y:%.*]] 1720; CHECK-NEXT: ret <2 x i8> [[R]] 1721; 1722 %a = add <2 x i8> %X, %Y 1723 %b = and <2 x i8> %X, %Y 1724 %r = sub <2 x i8> %a, %b 1725 ret <2 x i8> %r 1726} 1727 1728define i32 @pr51584(i32 %a, i32 %b) { 1729; CHECK-LABEL: @pr51584( 1730; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]] 1731; CHECK-NEXT: [[DOTNEG:%.*]] = sub i32 -11, [[TMP1]] 1732; CHECK-NEXT: ret i32 [[DOTNEG]] 1733; 1734 %sub = sub i32 0, %a 1735 %add = add nsw i32 11, %b 1736 %sub1 = sub i32 %sub, %add 1737 ret i32 %sub1 1738} 1739 1740define i8 @sub_srem(i8 noundef %x, i8 %y) { 1741; CHECK-LABEL: @sub_srem( 1742; CHECK-NEXT: [[REM:%.*]] = srem i8 [[X:%.*]], [[Y:%.*]] 1743; CHECK-NEXT: [[SUB:%.*]] = sub nsw i8 [[X]], [[REM]] 1744; CHECK-NEXT: ret i8 [[SUB]] 1745; 1746 %rem = srem i8 %x, %y 1747 %sub = sub i8 %x, %rem 1748 ret i8 %sub 1749} 1750 1751define <2 x i5> @sub_urem(<2 x i5> noundef %x, <2 x i5> %y) { 1752; CHECK-LABEL: @sub_urem( 1753; CHECK-NEXT: [[REM:%.*]] = urem <2 x i5> [[X:%.*]], [[Y:%.*]] 1754; CHECK-NEXT: [[SUB:%.*]] = sub nuw <2 x i5> [[X]], [[REM]] 1755; CHECK-NEXT: ret <2 x i5> [[SUB]] 1756; 1757 %rem = urem <2 x i5> %x, %y 1758 %sub = sub <2 x i5> %x, %rem 1759 ret <2 x i5> %sub 1760} 1761 1762define <3 x i32> @nuw_const_zext(<3 x i8> %y) { 1763; CHECK-LABEL: @nuw_const_zext( 1764; CHECK-NEXT: [[ZY:%.*]] = zext <3 x i8> [[Y:%.*]] to <3 x i32> 1765; CHECK-NEXT: [[S:%.*]] = sub nuw nsw <3 x i32> <i32 255, i32 128, i32 0>, [[ZY]] 1766; CHECK-NEXT: ret <3 x i32> [[S]] 1767; 1768 %zy = zext <3 x i8> %y to <3 x i32> 1769 %s = sub nuw <3 x i32> <i32 255, i32 128, i32 0>, %zy 1770 ret <3 x i32> %s 1771} 1772 1773define i32 @nuw_const_zext_big(i8 %y) { 1774; CHECK-LABEL: @nuw_const_zext_big( 1775; CHECK-NEXT: [[ZY:%.*]] = zext i8 [[Y:%.*]] to i32 1776; CHECK-NEXT: [[S:%.*]] = sub nuw nsw i32 257, [[ZY]] 1777; CHECK-NEXT: ret i32 [[S]] 1778; 1779 %zy = zext i8 %y to i32 1780 %s = sub nuw i32 257, %zy 1781 ret i32 %s 1782} 1783 1784define i32 @nuw_zext_zext(i8 %x, i8 %y) { 1785; CHECK-LABEL: @nuw_zext_zext( 1786; CHECK-NEXT: [[ZX:%.*]] = zext i8 [[X:%.*]] to i32 1787; CHECK-NEXT: [[ZY:%.*]] = zext i8 [[Y:%.*]] to i32 1788; CHECK-NEXT: [[S:%.*]] = sub nuw nsw i32 [[ZX]], [[ZY]] 1789; CHECK-NEXT: ret i32 [[S]] 1790; 1791 %zx = zext i8 %x to i32 1792 %zy = zext i8 %y to i32 1793 %s = sub nuw i32 %zx, %zy 1794 ret i32 %s 1795} 1796 1797define <2 x i16> @nuw_zext_sext(<2 x i8> %x, <2 x i8> %y) { 1798; CHECK-LABEL: @nuw_zext_sext( 1799; CHECK-NEXT: [[ZX:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i16> 1800; CHECK-NEXT: [[SY:%.*]] = sext <2 x i8> [[Y:%.*]] to <2 x i16> 1801; CHECK-NEXT: [[S:%.*]] = sub nuw nsw <2 x i16> [[ZX]], [[SY]] 1802; CHECK-NEXT: ret <2 x i16> [[S]] 1803; 1804 %zx = zext <2 x i8> %x to <2 x i16> 1805 %sy = sext <2 x i8> %y to <2 x i16> 1806 %s = sub nuw <2 x i16> %zx, %sy 1807 ret <2 x i16> %s 1808} 1809 1810define i32 @nuw_sext_zext(i8 %x, i8 %y) { 1811; CHECK-LABEL: @nuw_sext_zext( 1812; CHECK-NEXT: [[SX:%.*]] = sext i8 [[X:%.*]] to i32 1813; CHECK-NEXT: [[ZY:%.*]] = zext i8 [[Y:%.*]] to i32 1814; CHECK-NEXT: [[S:%.*]] = sub nuw nsw i32 [[SX]], [[ZY]] 1815; CHECK-NEXT: ret i32 [[S]] 1816; 1817 %sx = sext i8 %x to i32 1818 %zy = zext i8 %y to i32 1819 %s = sub nuw i32 %sx, %zy 1820 ret i32 %s 1821} 1822 1823define i8 @nuw_zext_zext_use1(i5 %x, i5 %y) { 1824; CHECK-LABEL: @nuw_zext_zext_use1( 1825; CHECK-NEXT: [[ZX:%.*]] = zext i5 [[X:%.*]] to i8 1826; CHECK-NEXT: call void @use8(i8 [[ZX]]) 1827; CHECK-NEXT: [[ZY:%.*]] = zext i5 [[Y:%.*]] to i8 1828; CHECK-NEXT: [[S:%.*]] = sub nuw nsw i8 [[ZX]], [[ZY]] 1829; CHECK-NEXT: ret i8 [[S]] 1830; 1831 %zx = zext i5 %x to i8 1832 call void @use8(i8 %zx) 1833 %zy = zext i5 %y to i8 1834 %s = sub nuw i8 %zx, %zy 1835 ret i8 %s 1836} 1837 1838define i8 @nuw_zext_zext_use2(i5 %x, i5 %y) { 1839; CHECK-LABEL: @nuw_zext_zext_use2( 1840; CHECK-NEXT: [[ZX:%.*]] = zext i5 [[X:%.*]] to i8 1841; CHECK-NEXT: [[ZY:%.*]] = zext i5 [[Y:%.*]] to i8 1842; CHECK-NEXT: call void @use8(i8 [[ZY]]) 1843; CHECK-NEXT: [[S:%.*]] = sub nuw nsw i8 [[ZX]], [[ZY]] 1844; CHECK-NEXT: ret i8 [[S]] 1845; 1846 %zx = zext i5 %x to i8 1847 %zy = zext i5 %y to i8 1848 call void @use8(i8 %zy) 1849 %s = sub nuw i8 %zx, %zy 1850 ret i8 %s 1851} 1852 1853define i8 @nuw_zext_zext_use3(i5 %x, i5 %y) { 1854; CHECK-LABEL: @nuw_zext_zext_use3( 1855; CHECK-NEXT: [[ZX:%.*]] = zext i5 [[X:%.*]] to i8 1856; CHECK-NEXT: call void @use8(i8 [[ZX]]) 1857; CHECK-NEXT: [[ZY:%.*]] = zext i5 [[Y:%.*]] to i8 1858; CHECK-NEXT: call void @use8(i8 [[ZY]]) 1859; CHECK-NEXT: [[S:%.*]] = sub nuw nsw i8 [[ZX]], [[ZY]] 1860; CHECK-NEXT: ret i8 [[S]] 1861; 1862 %zx = zext i5 %x to i8 1863 call void @use8(i8 %zx) 1864 %zy = zext i5 %y to i8 1865 call void @use8(i8 %zy) 1866 %s = sub nuw i8 %zx, %zy 1867 ret i8 %s 1868} 1869 1870define i32 @nuw_zext_zext_different_width(i8 %x, i7 %y) { 1871; CHECK-LABEL: @nuw_zext_zext_different_width( 1872; CHECK-NEXT: [[ZX:%.*]] = zext i8 [[X:%.*]] to i32 1873; CHECK-NEXT: [[ZY:%.*]] = zext i7 [[Y:%.*]] to i32 1874; CHECK-NEXT: [[S:%.*]] = sub nuw nsw i32 [[ZX]], [[ZY]] 1875; CHECK-NEXT: ret i32 [[S]] 1876; 1877 %zx = zext i8 %x to i32 1878 %zy = zext i7 %y to i32 1879 %s = sub nuw i32 %zx, %zy 1880 ret i32 %s 1881} 1882 1883define i16 @sext_nsw_noundef(i8 noundef %x, i8 %y) { 1884; CHECK-LABEL: @sext_nsw_noundef( 1885; CHECK-NEXT: [[Z:%.*]] = sext i8 [[Y:%.*]] to i16 1886; CHECK-NEXT: ret i16 [[Z]] 1887; 1888 %d = sub nsw i8 %x, %y 1889 %ex = sext i8 %x to i16 1890 %ed = sext i8 %d to i16 1891 %z = sub i16 %ex, %ed 1892 ret i16 %z 1893} 1894 1895; negative test - requires noundef 1896 1897define i16 @sext_nsw(i8 %x, i8 %y) { 1898; CHECK-LABEL: @sext_nsw( 1899; CHECK-NEXT: [[D:%.*]] = sub nsw i8 [[X:%.*]], [[Y:%.*]] 1900; CHECK-NEXT: [[EX:%.*]] = sext i8 [[X]] to i16 1901; CHECK-NEXT: [[ED:%.*]] = sext i8 [[D]] to i16 1902; CHECK-NEXT: [[Z:%.*]] = sub nsw i16 [[EX]], [[ED]] 1903; CHECK-NEXT: ret i16 [[Z]] 1904; 1905 %d = sub nsw i8 %x, %y 1906 %ex = sext i8 %x to i16 1907 %ed = sext i8 %d to i16 1908 %z = sub i16 %ex, %ed 1909 ret i16 %z 1910} 1911 1912; negative test - requires nsw 1913 1914define i16 @sext_noundef(i8 noundef %x, i8 %y) { 1915; CHECK-LABEL: @sext_noundef( 1916; CHECK-NEXT: [[D:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] 1917; CHECK-NEXT: [[EX:%.*]] = sext i8 [[X]] to i16 1918; CHECK-NEXT: [[ED:%.*]] = sext i8 [[D]] to i16 1919; CHECK-NEXT: [[Z:%.*]] = sub nsw i16 [[EX]], [[ED]] 1920; CHECK-NEXT: ret i16 [[Z]] 1921; 1922 %d = sub i8 %x, %y 1923 %ex = sext i8 %x to i16 1924 %ed = sext i8 %d to i16 1925 %z = sub i16 %ex, %ed 1926 ret i16 %z 1927} 1928 1929; negative test - must have common operand 1930 1931define i16 @sext_nsw_noundef_wrong_val(i8 noundef %x, i8 noundef %y, i8 noundef %q) { 1932; CHECK-LABEL: @sext_nsw_noundef_wrong_val( 1933; CHECK-NEXT: [[D:%.*]] = sub nsw i8 [[X:%.*]], [[Y:%.*]] 1934; CHECK-NEXT: [[EQ:%.*]] = sext i8 [[Q:%.*]] to i16 1935; CHECK-NEXT: [[ED:%.*]] = sext i8 [[D]] to i16 1936; CHECK-NEXT: [[Z:%.*]] = sub nsw i16 [[EQ]], [[ED]] 1937; CHECK-NEXT: ret i16 [[Z]] 1938; 1939 %d = sub nsw i8 %x, %y 1940 %eq = sext i8 %q to i16 1941 %ed = sext i8 %d to i16 1942 %z = sub i16 %eq, %ed 1943 ret i16 %z 1944} 1945 1946; two no-wrap analyses combine to allow reduction 1947 1948define i16 @srem_sext_noundef(i8 noundef %x, i8 %y) { 1949; CHECK-LABEL: @srem_sext_noundef( 1950; CHECK-NEXT: [[R:%.*]] = srem i8 [[X:%.*]], [[Y:%.*]] 1951; CHECK-NEXT: [[Z:%.*]] = sext i8 [[R]] to i16 1952; CHECK-NEXT: ret i16 [[Z]] 1953; 1954 %r = srem i8 %x, %y 1955 %d = sub i8 %x, %r 1956 %sd = sext i8 %d to i16 1957 %sx = sext i8 %x to i16 1958 %z = sub i16 %sx, %sd 1959 ret i16 %z 1960} 1961 1962define i16 @zext_nuw_noundef(i8 noundef %x, i8 %y) { 1963; CHECK-LABEL: @zext_nuw_noundef( 1964; CHECK-NEXT: [[Z:%.*]] = zext i8 [[Y:%.*]] to i16 1965; CHECK-NEXT: ret i16 [[Z]] 1966; 1967 %d = sub nuw i8 %x, %y 1968 %ex = zext i8 %x to i16 1969 %ed = zext i8 %d to i16 1970 %z = sub i16 %ex, %ed 1971 ret i16 %z 1972} 1973 1974; negative test - requires noundef 1975 1976define i16 @zext_nuw(i8 %x, i8 %y) { 1977; CHECK-LABEL: @zext_nuw( 1978; CHECK-NEXT: [[D:%.*]] = sub nuw i8 [[X:%.*]], [[Y:%.*]] 1979; CHECK-NEXT: [[EX:%.*]] = zext i8 [[X]] to i16 1980; CHECK-NEXT: [[ED:%.*]] = zext i8 [[D]] to i16 1981; CHECK-NEXT: [[Z:%.*]] = sub nsw i16 [[EX]], [[ED]] 1982; CHECK-NEXT: ret i16 [[Z]] 1983; 1984 %d = sub nuw i8 %x, %y 1985 %ex = zext i8 %x to i16 1986 %ed = zext i8 %d to i16 1987 %z = sub i16 %ex, %ed 1988 ret i16 %z 1989} 1990 1991; negative test - requires nuw 1992 1993define i16 @zext_noundef(i8 noundef %x, i8 %y) { 1994; CHECK-LABEL: @zext_noundef( 1995; CHECK-NEXT: [[D:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] 1996; CHECK-NEXT: [[EX:%.*]] = zext i8 [[X]] to i16 1997; CHECK-NEXT: [[ED:%.*]] = zext i8 [[D]] to i16 1998; CHECK-NEXT: [[Z:%.*]] = sub nsw i16 [[EX]], [[ED]] 1999; CHECK-NEXT: ret i16 [[Z]] 2000; 2001 %d = sub i8 %x, %y 2002 %ex = zext i8 %x to i16 2003 %ed = zext i8 %d to i16 2004 %z = sub i16 %ex, %ed 2005 ret i16 %z 2006} 2007 2008; negative test - must have common operand 2009 2010define i16 @zext_nsw_noundef_wrong_val(i8 noundef %x, i8 noundef %y, i8 noundef %q) { 2011; CHECK-LABEL: @zext_nsw_noundef_wrong_val( 2012; CHECK-NEXT: [[D:%.*]] = sub nuw i8 [[X:%.*]], [[Y:%.*]] 2013; CHECK-NEXT: [[EQ:%.*]] = zext i8 [[Q:%.*]] to i16 2014; CHECK-NEXT: [[ED:%.*]] = zext i8 [[D]] to i16 2015; CHECK-NEXT: [[Z:%.*]] = sub nsw i16 [[EQ]], [[ED]] 2016; CHECK-NEXT: ret i16 [[Z]] 2017; 2018 %d = sub nuw i8 %x, %y 2019 %eq = zext i8 %q to i16 2020 %ed = zext i8 %d to i16 2021 %z = sub i16 %eq, %ed 2022 ret i16 %z 2023} 2024 2025; two no-wrap analyses combine to allow reduction 2026 2027define i16 @urem_zext_noundef(i8 noundef %x, i8 %y) { 2028; CHECK-LABEL: @urem_zext_noundef( 2029; CHECK-NEXT: [[R:%.*]] = urem i8 [[X:%.*]], [[Y:%.*]] 2030; CHECK-NEXT: [[Z:%.*]] = zext i8 [[R]] to i16 2031; CHECK-NEXT: ret i16 [[Z]] 2032; 2033 %r = urem i8 %x, %y 2034 %d = sub i8 %x, %r 2035 %ed = zext i8 %d to i16 2036 %ex = zext i8 %x to i16 2037 %z = sub i16 %ex, %ed 2038 ret i16 %z 2039} 2040 2041; x * y - x --> (y - 1) * x 2042; TODO: The mul could retain nsw. 2043 2044define i8 @mul_sub_common_factor_commute1(i8 %x, i8 %y) { 2045; CHECK-LABEL: @mul_sub_common_factor_commute1( 2046; CHECK-NEXT: [[X1:%.*]] = add i8 [[Y:%.*]], -1 2047; CHECK-NEXT: [[A:%.*]] = mul i8 [[X:%.*]], [[X1]] 2048; CHECK-NEXT: ret i8 [[A]] 2049; 2050 %m = mul nsw i8 %x, %y 2051 %a = sub nsw i8 %m, %x 2052 ret i8 %a 2053} 2054 2055; TODO: The mul could retain nuw. 2056 2057define <2 x i8> @mul_sub_common_factor_commute2(<2 x i8> %x, <2 x i8> %y) { 2058; CHECK-LABEL: @mul_sub_common_factor_commute2( 2059; CHECK-NEXT: [[M1:%.*]] = add <2 x i8> [[Y:%.*]], splat (i8 -1) 2060; CHECK-NEXT: [[A:%.*]] = mul <2 x i8> [[M1]], [[X:%.*]] 2061; CHECK-NEXT: ret <2 x i8> [[A]] 2062; 2063 %m = mul nuw <2 x i8> %y, %x 2064 %a = sub nuw <2 x i8> %m, %x 2065 ret <2 x i8> %a 2066} 2067 2068; x - (x * y) --> (1 - y) * x 2069 2070define i8 @mul_sub_common_factor_commute3(i8 %x, i8 %y) { 2071; CHECK-LABEL: @mul_sub_common_factor_commute3( 2072; CHECK-NEXT: [[M1:%.*]] = sub i8 1, [[Y:%.*]] 2073; CHECK-NEXT: [[A:%.*]] = mul i8 [[X:%.*]], [[M1]] 2074; CHECK-NEXT: ret i8 [[A]] 2075; 2076 %m = mul nuw i8 %x, %y 2077 %a = sub nsw i8 %x, %m 2078 ret i8 %a 2079} 2080 2081define i8 @mul_sub_common_factor_commute4(i8 %x, i8 %y) { 2082; CHECK-LABEL: @mul_sub_common_factor_commute4( 2083; CHECK-NEXT: [[M1:%.*]] = sub i8 1, [[Y:%.*]] 2084; CHECK-NEXT: [[A:%.*]] = mul i8 [[X:%.*]], [[M1]] 2085; CHECK-NEXT: ret i8 [[A]] 2086; 2087 %m = mul nsw i8 %y, %x 2088 %a = sub nuw i8 %x, %m 2089 ret i8 %a 2090} 2091 2092; negative test - uses 2093 2094define i8 @mul_sub_common_factor_use(i8 %x, i8 %y) { 2095; CHECK-LABEL: @mul_sub_common_factor_use( 2096; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], [[Y:%.*]] 2097; CHECK-NEXT: call void @use8(i8 [[M]]) 2098; CHECK-NEXT: [[A:%.*]] = sub i8 [[M]], [[X]] 2099; CHECK-NEXT: ret i8 [[A]] 2100; 2101 %m = mul i8 %x, %y 2102 call void @use8(i8 %m) 2103 %a = sub i8 %m, %x 2104 ret i8 %a 2105} 2106 2107define i5 @demand_low_bits_uses(i8 %x, i8 %y) { 2108; CHECK-LABEL: @demand_low_bits_uses( 2109; CHECK-NEXT: [[M:%.*]] = and i8 [[X:%.*]], 96 2110; CHECK-NEXT: [[A:%.*]] = sub i8 [[Y:%.*]], [[M]] 2111; CHECK-NEXT: call void @use8(i8 [[A]]) 2112; CHECK-NEXT: [[R:%.*]] = trunc i8 [[Y]] to i5 2113; CHECK-NEXT: ret i5 [[R]] 2114; 2115 %m = and i8 %x, 96 ; 0x60 2116 %a = sub i8 %y, %m 2117 call void @use8(i8 %a) 2118 %r = trunc i8 %a to i5 2119 ret i5 %r 2120} 2121 2122; negative test - demands one more bit 2123 2124define i6 @demand_low_bits_uses_extra_bit(i8 %x, i8 %y) { 2125; CHECK-LABEL: @demand_low_bits_uses_extra_bit( 2126; CHECK-NEXT: [[M:%.*]] = and i8 [[X:%.*]], 96 2127; CHECK-NEXT: [[A:%.*]] = sub i8 [[Y:%.*]], [[M]] 2128; CHECK-NEXT: call void @use8(i8 [[A]]) 2129; CHECK-NEXT: [[R:%.*]] = trunc i8 [[A]] to i6 2130; CHECK-NEXT: ret i6 [[R]] 2131; 2132 %m = and i8 %x, 96 ; 0x60 2133 %a = sub i8 %y, %m 2134 call void @use8(i8 %a) 2135 %r = trunc i8 %a to i6 2136 ret i6 %r 2137} 2138 2139; negative test - must be operand 1 2140 2141define i8 @demand_low_bits_uses_commute(i8 %x, i8 %y, i8 %z) { 2142; CHECK-LABEL: @demand_low_bits_uses_commute( 2143; CHECK-NEXT: [[M:%.*]] = and i8 [[X:%.*]], -64 2144; CHECK-NEXT: [[A:%.*]] = sub i8 [[M]], [[Y:%.*]] 2145; CHECK-NEXT: call void @use8(i8 [[A]]) 2146; CHECK-NEXT: [[S:%.*]] = sub i8 [[A]], [[Z:%.*]] 2147; CHECK-NEXT: [[R:%.*]] = shl i8 [[S]], 2 2148; CHECK-NEXT: ret i8 [[R]] 2149; 2150 %m = and i8 %x, -64 ; 0xC0 2151 %a = sub i8 %m, %y 2152 call void @use8(i8 %a) 2153 %s = sub i8 %a, %z 2154 %r = shl i8 %s, 2 2155 ret i8 %r 2156} 2157 2158; sub becomes negate and combines with shl 2159 2160define i8 @shrink_sub_from_constant_lowbits(i8 %x) { 2161; CHECK-LABEL: @shrink_sub_from_constant_lowbits( 2162; CHECK-NEXT: [[X000_NEG:%.*]] = mul i8 [[X:%.*]], -8 2163; CHECK-NEXT: ret i8 [[X000_NEG]] 2164; 2165 %x000 = shl i8 %x, 3 ; 3 low bits are known zero 2166 %sub = sub i8 7, %x000 2167 %r = and i8 %sub, -8 ; 3 low bits are not demanded 2168 ret i8 %r 2169} 2170 2171; negative test - extra use prevents shrinking '7' 2172 2173define i8 @shrink_sub_from_constant_lowbits_uses(i8 %x) { 2174; CHECK-LABEL: @shrink_sub_from_constant_lowbits_uses( 2175; CHECK-NEXT: [[X000:%.*]] = shl i8 [[X:%.*]], 3 2176; CHECK-NEXT: [[SUB:%.*]] = sub i8 7, [[X000]] 2177; CHECK-NEXT: call void @use8(i8 [[SUB]]) 2178; CHECK-NEXT: [[R:%.*]] = and i8 [[SUB]], -8 2179; CHECK-NEXT: ret i8 [[R]] 2180; 2181 %x000 = shl i8 %x, 3 ; 3 low bits are known zero 2182 %sub = sub i8 7, %x000 2183 call void @use8(i8 %sub) 2184 %r = and i8 %sub, -8 ; 3 low bits are not demanded 2185 ret i8 %r 2186} 2187 2188; safe to clear 3 low bits (2 higher bits remain set) 2189 2190define i8 @shrink_sub_from_constant_lowbits2(i8 %x) { 2191; CHECK-LABEL: @shrink_sub_from_constant_lowbits2( 2192; CHECK-NEXT: [[X000:%.*]] = and i8 [[X:%.*]], -8 2193; CHECK-NEXT: [[SUB:%.*]] = sub nsw i8 24, [[X000]] 2194; CHECK-NEXT: [[R:%.*]] = and i8 [[SUB]], -16 2195; CHECK-NEXT: ret i8 [[R]] 2196; 2197 %x000 = and i8 %x, -8 ; 3 low bits are known zero 2198 %sub = sub nsw i8 30, %x000 ; 0b0001_1110 2199 %r = and i8 %sub, -16 ; 4 low bits are not demanded 2200 ret i8 %r 2201} 2202 2203; safe to clear 3 low bits (2 higher bits remain set) 2204 2205define <2 x i8> @shrink_sub_from_constant_lowbits3(<2 x i8> %x) { 2206; CHECK-LABEL: @shrink_sub_from_constant_lowbits3( 2207; CHECK-NEXT: [[X0000:%.*]] = shl <2 x i8> [[X:%.*]], splat (i8 4) 2208; CHECK-NEXT: [[SUB:%.*]] = sub nuw <2 x i8> splat (i8 24), [[X0000]] 2209; CHECK-NEXT: [[R:%.*]] = lshr exact <2 x i8> [[SUB]], splat (i8 3) 2210; CHECK-NEXT: ret <2 x i8> [[R]] 2211; 2212 %x0000 = shl <2 x i8> %x, <i8 4, i8 4> ; 4 low bits are known zero 2213 %sub = sub nuw <2 x i8> <i8 31, i8 31>, %x0000 2214 %r = lshr <2 x i8> %sub, <i8 3, i8 3> ; 3 low bits are not demanded 2215 ret <2 x i8> %r 2216} 2217 2218; eliminate the mask of y or the mask of the result 2219 2220define i8 @demand_sub_from_variable_lowbits(i8 %x, i8 %y) { 2221; CHECK-LABEL: @demand_sub_from_variable_lowbits( 2222; CHECK-NEXT: [[X000:%.*]] = shl i8 [[X:%.*]], 3 2223; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[Y:%.*]], [[X000]] 2224; CHECK-NEXT: [[R:%.*]] = and i8 [[SUB]], -8 2225; CHECK-NEXT: ret i8 [[R]] 2226; 2227 %x000 = shl i8 %x, 3 ; 3 low bits are known zero 2228 %y000 = and i8 %y, -8 2229 %sub = sub i8 %y000, %x000 2230 %r = and i8 %sub, -8 ; 3 low bits are not demanded 2231 ret i8 %r 2232} 2233 2234; setting the low 3 bits of y doesn't change anything 2235 2236define i8 @demand_sub_from_variable_lowbits2(i8 %x, i8 %y) { 2237; CHECK-LABEL: @demand_sub_from_variable_lowbits2( 2238; CHECK-NEXT: [[X0000:%.*]] = shl i8 [[X:%.*]], 4 2239; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i8 [[Y:%.*]], [[X0000]] 2240; CHECK-NEXT: [[R:%.*]] = lshr i8 [[SUB]], 4 2241; CHECK-NEXT: ret i8 [[R]] 2242; 2243 %x0000 = shl i8 %x, 4 ; 4 low bits are known zero 2244 %y111 = or i8 %y, 7 2245 %sub = sub nsw nuw i8 %y111, %x0000 2246 %r = lshr i8 %sub, 4 ; 4 low bits are not demanded 2247 ret i8 %r 2248} 2249 2250; negative test - the mask of y removes an extra bit, so that instruction is needed 2251 2252define i8 @demand_sub_from_variable_lowbits3(i8 %x, i8 %y) { 2253; CHECK-LABEL: @demand_sub_from_variable_lowbits3( 2254; CHECK-NEXT: [[X0000:%.*]] = shl i8 [[X:%.*]], 4 2255; CHECK-NEXT: [[Y00000:%.*]] = and i8 [[Y:%.*]], -32 2256; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[Y00000]], [[X0000]] 2257; CHECK-NEXT: [[R:%.*]] = lshr exact i8 [[SUB]], 4 2258; CHECK-NEXT: ret i8 [[R]] 2259; 2260 %x0000 = shl i8 %x, 4 ; 4 low bits are known zero 2261 %y00000 = and i8 %y, -32 2262 %sub = sub i8 %y00000, %x0000 2263 %r = lshr i8 %sub, 4 ; 4 low bits are not demanded 2264 ret i8 %r 2265} 2266 2267; C - ((C3 - X) & C2) --> (C - (C2 & C3)) + (X & C2) when: 2268; (C3 - ((C2 & C3) - 1)) is pow2 2269; ((C2 + C3) & ((C2 & C3) - 1)) == ((C2 & C3) - 1) 2270; C2 is negative pow2 2271define i10 @sub_to_and_nuw(i10 %x) { 2272; CHECK-LABEL: @sub_to_and_nuw( 2273; CHECK-NEXT: [[TMP1:%.*]] = and i10 [[X:%.*]], 120 2274; CHECK-NEXT: [[R:%.*]] = add nuw nsw i10 [[TMP1]], 379 2275; CHECK-NEXT: ret i10 [[R]] 2276; 2277 %sub = sub nuw i10 71, %x 2278 %and = and i10 %sub, 120 2279 %r = sub i10 443, %and 2280 ret i10 %r 2281} 2282 2283; C - ((C3 -nuw X) & C2) --> (C - (C2 & C3)) + (X & C2) when: 2284; (C3 - ((C2 & C3) - 1)) is pow2 2285; ((C2 + C3) & ((C2 & C3) - 1)) == ((C2 & C3) - 1) 2286define i10 @sub_to_and_negpow2(i10 %x) { 2287; CHECK-LABEL: @sub_to_and_negpow2( 2288; CHECK-NEXT: [[TMP1:%.*]] = and i10 [[X:%.*]], -8 2289; CHECK-NEXT: [[R:%.*]] = add i10 [[TMP1]], -31 2290; CHECK-NEXT: ret i10 [[R]] 2291; 2292 %sub = sub i10 71, %x 2293 %and = and i10 %sub, -8 2294 %r = sub i10 33, %and 2295 ret i10 %r 2296} 2297 2298; TODO: 2299; C + ((C3 -nuw X) & C2) --> (C + (C2 & C3)) - (X & C2) when: 2300define i10 @add_to_and_nuw(i10 %x) { 2301; CHECK-LABEL: @add_to_and_nuw( 2302; CHECK-NEXT: [[SUB:%.*]] = sub nuw i10 71, [[X:%.*]] 2303; CHECK-NEXT: [[AND:%.*]] = and i10 [[SUB]], 120 2304; CHECK-NEXT: [[R:%.*]] = add nuw nsw i10 [[AND]], 224 2305; CHECK-NEXT: ret i10 [[R]] 2306; 2307 %sub = sub nuw i10 71, %x 2308 %and = and i10 %sub, 120 2309 %r = add i10 224, %and 2310 ret i10 %r 2311} 2312 2313; (C3 - (C2 & C3) + 1) is not pow2 2314define i10 @sub_to_and_negative1(i10 %x) { 2315; CHECK-LABEL: @sub_to_and_negative1( 2316; CHECK-NEXT: [[SUB:%.*]] = sub i10 71, [[X:%.*]] 2317; CHECK-NEXT: [[AND:%.*]] = and i10 [[SUB]], 248 2318; CHECK-NEXT: [[R:%.*]] = sub nuw nsw i10 444, [[AND]] 2319; CHECK-NEXT: ret i10 [[R]] 2320; 2321 %sub = sub nuw i10 327, %x 2322 %and = and i10 %sub, 248 2323 %r = sub i10 444, %and 2324 ret i10 %r 2325} 2326 2327; ((C2 + C3) & ((C2 & C3) - 1)) == ((C2 & C3) - 1) 2328define i10 @sub_to_and_negative2(i10 %x) { 2329; CHECK-LABEL: @sub_to_and_negative2( 2330; CHECK-NEXT: [[SUB:%.*]] = sub nuw i10 71, [[X:%.*]] 2331; CHECK-NEXT: [[AND:%.*]] = and i10 [[SUB]], 88 2332; CHECK-NEXT: [[R:%.*]] = sub nsw i10 64, [[AND]] 2333; CHECK-NEXT: ret i10 [[R]] 2334; 2335 %sub = sub nuw i10 71, %x 2336 %and = and i10 %sub, 88 2337 %r = sub i10 64, %and 2338 ret i10 %r 2339} 2340 2341; no nuw && C2 is not neg-pow2 2342define i10 @sub_to_and_negative3(i10 %x) { 2343; CHECK-LABEL: @sub_to_and_negative3( 2344; CHECK-NEXT: [[SUB:%.*]] = sub i10 71, [[X:%.*]] 2345; CHECK-NEXT: [[AND:%.*]] = and i10 [[SUB]], 120 2346; CHECK-NEXT: [[R:%.*]] = sub nsw i10 64, [[AND]] 2347; CHECK-NEXT: ret i10 [[R]] 2348; 2349 %sub = sub i10 71, %x 2350 %and = and i10 %sub, 120 2351 %r = sub i10 64, %and 2352 ret i10 %r 2353} 2354 2355declare void @use10(i10) 2356 2357; and is not one-use 2358define i10 @sub_to_and_negative4(i10 %x) { 2359; CHECK-LABEL: @sub_to_and_negative4( 2360; CHECK-NEXT: [[SUB:%.*]] = sub i10 71, [[X:%.*]] 2361; CHECK-NEXT: [[AND:%.*]] = and i10 [[SUB]], 120 2362; CHECK-NEXT: [[R:%.*]] = sub nsw i10 64, [[AND]] 2363; CHECK-NEXT: call void @use10(i10 [[AND]]) 2364; CHECK-NEXT: ret i10 [[R]] 2365; 2366 %sub = sub i10 71, %x 2367 %and = and i10 %sub, 120 2368 %r = sub i10 64, %and 2369 call void @use10(i10 %and) 2370 ret i10 %r 2371} 2372 2373 2374define <2 x i8> @sub_to_and_vector1(<2 x i8> %x) { 2375; CHECK-LABEL: @sub_to_and_vector1( 2376; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 120) 2377; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i8> [[TMP1]], splat (i8 -9) 2378; CHECK-NEXT: ret <2 x i8> [[R]] 2379; 2380 %sub = sub nuw <2 x i8> <i8 71, i8 71>, %x 2381 %and = and <2 x i8> %sub, <i8 120, i8 120> 2382 %r = sub <2 x i8> <i8 55, i8 55>, %and 2383 ret <2 x i8> %r 2384} 2385 2386 2387define <2 x i8> @sub_to_and_vector2(<2 x i8> %x) { 2388; CHECK-LABEL: @sub_to_and_vector2( 2389; CHECK-NEXT: [[SUB:%.*]] = sub nuw <2 x i8> <i8 71, i8 poison>, [[X:%.*]] 2390; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[SUB]], splat (i8 120) 2391; CHECK-NEXT: [[R:%.*]] = sub nsw <2 x i8> splat (i8 77), [[AND]] 2392; CHECK-NEXT: ret <2 x i8> [[R]] 2393; 2394 %sub = sub nuw <2 x i8> <i8 71, i8 poison>, %x 2395 %and = and <2 x i8> %sub, <i8 120, i8 120> 2396 %r = sub <2 x i8> <i8 77, i8 77>, %and 2397 ret <2 x i8> %r 2398} 2399 2400 2401define <2 x i8> @sub_to_and_vector3(<2 x i8> %x) { 2402; CHECK-LABEL: @sub_to_and_vector3( 2403; CHECK-NEXT: [[SUB:%.*]] = sub nuw <2 x i8> splat (i8 71), [[X:%.*]] 2404; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[SUB]], <i8 120, i8 poison> 2405; CHECK-NEXT: [[R:%.*]] = sub nsw <2 x i8> splat (i8 44), [[AND]] 2406; CHECK-NEXT: ret <2 x i8> [[R]] 2407; 2408 %sub = sub nuw <2 x i8> <i8 71, i8 71>, %x 2409 %and = and <2 x i8> %sub, <i8 120, i8 poison> 2410 %r = sub <2 x i8> <i8 44, i8 44>, %and 2411 ret <2 x i8> %r 2412} 2413 2414 2415define <2 x i8> @sub_to_and_vector4(<2 x i8> %x) { 2416; CHECK-LABEL: @sub_to_and_vector4( 2417; CHECK-NEXT: [[SUB:%.*]] = sub nuw <2 x i8> splat (i8 71), [[X:%.*]] 2418; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[SUB]], splat (i8 120) 2419; CHECK-NEXT: [[R:%.*]] = sub nsw <2 x i8> <i8 88, i8 poison>, [[AND]] 2420; CHECK-NEXT: ret <2 x i8> [[R]] 2421; 2422 %sub = sub nuw <2 x i8> <i8 71, i8 71>, %x 2423 %and = and <2 x i8> %sub, <i8 120, i8 120> 2424 %r = sub <2 x i8> <i8 88, i8 poison>, %and 2425 ret <2 x i8> %r 2426} 2427 2428; (X * X) - (Y * Y) --> (X + Y) * (X - Y) 2429 2430define i8 @diff_of_squares(i8 %x, i8 %y) { 2431; CHECK-LABEL: @diff_of_squares( 2432; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X:%.*]], [[Y:%.*]] 2433; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[X]], [[Y]] 2434; CHECK-NEXT: [[R:%.*]] = mul i8 [[ADD]], [[SUB]] 2435; CHECK-NEXT: ret i8 [[R]] 2436; 2437 %x2 = mul i8 %x, %x 2438 %y2 = mul i8 %y, %y 2439 %r = sub i8 %x2, %y2 2440 ret i8 %r 2441} 2442 2443; All-or-nothing for propagation of no-wrap flags (possibly conservative) 2444 2445define i5 @diff_of_squares_nuw(i5 %x, i5 %y) { 2446; CHECK-LABEL: @diff_of_squares_nuw( 2447; CHECK-NEXT: [[ADD:%.*]] = add nuw i5 [[X:%.*]], [[Y:%.*]] 2448; CHECK-NEXT: [[SUB:%.*]] = sub nuw i5 [[X]], [[Y]] 2449; CHECK-NEXT: [[R:%.*]] = mul nuw i5 [[ADD]], [[SUB]] 2450; CHECK-NEXT: ret i5 [[R]] 2451; 2452 %x2 = mul nuw i5 %x, %x 2453 %y2 = mul nuw i5 %y, %y 2454 %r = sub nuw i5 %x2, %y2 2455 ret i5 %r 2456} 2457 2458; All-or-nothing for propagation of no-wrap flags (possibly conservative) 2459 2460define i5 @diff_of_squares_partial_nuw(i5 %x, i5 %y) { 2461; CHECK-LABEL: @diff_of_squares_partial_nuw( 2462; CHECK-NEXT: [[ADD:%.*]] = add i5 [[X:%.*]], [[Y:%.*]] 2463; CHECK-NEXT: [[SUB:%.*]] = sub i5 [[X]], [[Y]] 2464; CHECK-NEXT: [[R:%.*]] = mul i5 [[ADD]], [[SUB]] 2465; CHECK-NEXT: ret i5 [[R]] 2466; 2467 %x2 = mul nuw i5 %x, %x 2468 %y2 = mul nuw i5 %y, %y 2469 %r = sub i5 %x2, %y2 2470 ret i5 %r 2471} 2472 2473; All-or-nothing for propagation of no-wrap flags (possibly conservative) 2474 2475define <2 x i5> @diff_of_squares_nsw(<2 x i5> %x, <2 x i5> %y) { 2476; CHECK-LABEL: @diff_of_squares_nsw( 2477; CHECK-NEXT: [[ADD:%.*]] = add nsw <2 x i5> [[X:%.*]], [[Y:%.*]] 2478; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i5> [[X]], [[Y]] 2479; CHECK-NEXT: [[R:%.*]] = mul nsw <2 x i5> [[ADD]], [[SUB]] 2480; CHECK-NEXT: ret <2 x i5> [[R]] 2481; 2482 %x2 = mul nsw <2 x i5> %x, %x 2483 %y2 = mul nsw <2 x i5> %y, %y 2484 %r = sub nsw <2 x i5> %x2, %y2 2485 ret <2 x i5> %r 2486} 2487 2488; All-or-nothing for propagation of no-wrap flags (possibly conservative) 2489 2490define <2 x i5> @diff_of_squares_partial_nsw(<2 x i5> %x, <2 x i5> %y) { 2491; CHECK-LABEL: @diff_of_squares_partial_nsw( 2492; CHECK-NEXT: [[ADD:%.*]] = add <2 x i5> [[X:%.*]], [[Y:%.*]] 2493; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i5> [[X]], [[Y]] 2494; CHECK-NEXT: [[R:%.*]] = mul <2 x i5> [[ADD]], [[SUB]] 2495; CHECK-NEXT: ret <2 x i5> [[R]] 2496; 2497 %x2 = mul nsw <2 x i5> %x, %x 2498 %y2 = mul <2 x i5> %y, %y 2499 %r = sub nsw <2 x i5> %x2, %y2 2500 ret <2 x i5> %r 2501} 2502 2503define i1 @diff_of_squares_nsw_i1(i1 %x, i1 %y) { 2504; CHECK-LABEL: @diff_of_squares_nsw_i1( 2505; CHECK-NEXT: ret i1 false 2506; 2507 %x2 = mul nsw i1 %x, %x 2508 %y2 = mul nsw i1 %y, %y 2509 %r = sub nsw i1 %x2, %y2 2510 ret i1 %r 2511} 2512 2513define i1 @diff_of_squares_nuw_i1(i1 %x, i1 %y) { 2514; CHECK-LABEL: @diff_of_squares_nuw_i1( 2515; CHECK-NEXT: [[R:%.*]] = xor i1 [[Y:%.*]], [[X:%.*]] 2516; CHECK-NEXT: ret i1 [[R]] 2517; 2518 %x2 = mul nuw i1 %x, %x 2519 %y2 = mul nuw i1 %y, %y 2520 %r = sub nuw i1 %x2, %y2 2521 ret i1 %r 2522} 2523 2524; It is not correct to propagate nsw. 2525; TODO: This should reduce more. 2526 2527define i2 @diff_of_squares_nsw_i2(i2 %x, i2 %y) { 2528; CHECK-LABEL: @diff_of_squares_nsw_i2( 2529; CHECK-NEXT: [[ADD:%.*]] = add i2 [[X:%.*]], [[Y:%.*]] 2530; CHECK-NEXT: [[SUB:%.*]] = sub i2 [[X]], [[Y]] 2531; CHECK-NEXT: [[R:%.*]] = mul i2 [[ADD]], [[SUB]] 2532; CHECK-NEXT: ret i2 [[R]] 2533; 2534 %x2 = mul nsw i2 %x, %x 2535 %y2 = mul nsw i2 %y, %y 2536 %r = sub nsw i2 %x2, %y2 2537 ret i2 %r 2538} 2539 2540; TODO: This should reduce more. 2541 2542define i2 @diff_of_squares_nuw_i2(i2 %x, i2 %y) { 2543; CHECK-LABEL: @diff_of_squares_nuw_i2( 2544; CHECK-NEXT: [[ADD:%.*]] = add nuw i2 [[X:%.*]], [[Y:%.*]] 2545; CHECK-NEXT: [[SUB:%.*]] = sub nuw i2 [[X]], [[Y]] 2546; CHECK-NEXT: [[R:%.*]] = mul nuw i2 [[ADD]], [[SUB]] 2547; CHECK-NEXT: ret i2 [[R]] 2548; 2549 %x2 = mul nuw i2 %x, %x 2550 %y2 = mul nuw i2 %y, %y 2551 %r = sub nuw i2 %x2, %y2 2552 ret i2 %r 2553} 2554 2555; negative test 2556 2557define i8 @diff_of_squares_use1(i8 %x, i8 %y) { 2558; CHECK-LABEL: @diff_of_squares_use1( 2559; CHECK-NEXT: [[X2:%.*]] = mul i8 [[X:%.*]], [[X]] 2560; CHECK-NEXT: call void @use8(i8 [[X2]]) 2561; CHECK-NEXT: [[Y2:%.*]] = mul i8 [[Y:%.*]], [[Y]] 2562; CHECK-NEXT: [[R:%.*]] = sub i8 [[X2]], [[Y2]] 2563; CHECK-NEXT: ret i8 [[R]] 2564; 2565 %x2 = mul i8 %x, %x 2566 call void @use8(i8 %x2) 2567 %y2 = mul i8 %y, %y 2568 %r = sub i8 %x2, %y2 2569 ret i8 %r 2570} 2571 2572; negative test 2573 2574define i8 @diff_of_squares_use2(i8 %x, i8 %y) { 2575; CHECK-LABEL: @diff_of_squares_use2( 2576; CHECK-NEXT: [[X2:%.*]] = mul i8 [[X:%.*]], [[X]] 2577; CHECK-NEXT: [[Y2:%.*]] = mul i8 [[Y:%.*]], [[Y]] 2578; CHECK-NEXT: call void @use8(i8 [[Y2]]) 2579; CHECK-NEXT: [[R:%.*]] = sub i8 [[X2]], [[Y2]] 2580; CHECK-NEXT: ret i8 [[R]] 2581; 2582 %x2 = mul i8 %x, %x 2583 %y2 = mul i8 %y, %y 2584 call void @use8(i8 %y2) 2585 %r = sub i8 %x2, %y2 2586 ret i8 %r 2587} 2588 2589; negative test - must be squares 2590 2591define i8 @diff_of_muls1(i8 %x, i8 %y, i8 %z) { 2592; CHECK-LABEL: @diff_of_muls1( 2593; CHECK-NEXT: [[M:%.*]] = mul i8 [[X:%.*]], [[Z:%.*]] 2594; CHECK-NEXT: [[Y2:%.*]] = mul i8 [[Y:%.*]], [[Y]] 2595; CHECK-NEXT: [[R:%.*]] = sub i8 [[M]], [[Y2]] 2596; CHECK-NEXT: ret i8 [[R]] 2597; 2598 %m = mul i8 %x, %z 2599 %y2 = mul i8 %y, %y 2600 %r = sub i8 %m, %y2 2601 ret i8 %r 2602} 2603 2604; negative test - must be squares 2605 2606define i8 @diff_of_muls2(i8 %x, i8 %y, i8 %z) { 2607; CHECK-LABEL: @diff_of_muls2( 2608; CHECK-NEXT: [[X2:%.*]] = mul i8 [[X:%.*]], [[X]] 2609; CHECK-NEXT: [[M:%.*]] = mul i8 [[Y:%.*]], [[Z:%.*]] 2610; CHECK-NEXT: [[R:%.*]] = sub i8 [[X2]], [[M]] 2611; CHECK-NEXT: ret i8 [[R]] 2612; 2613 %x2 = mul i8 %x, %x 2614 %m = mul i8 %y, %z 2615 %r = sub i8 %x2, %m 2616 ret i8 %r 2617} 2618 2619define i8 @sub_of_adds_2xz_multiuse(i8 %x, i8 %y, i8 %z) { 2620; CHECK-LABEL: @sub_of_adds_2xz_multiuse( 2621; CHECK-NEXT: [[XZ:%.*]] = add i8 [[X:%.*]], [[Z:%.*]] 2622; CHECK-NEXT: [[YZ:%.*]] = add i8 [[Z]], [[Y:%.*]] 2623; CHECK-NEXT: [[R:%.*]] = sub i8 [[X]], [[Y]] 2624; CHECK-NEXT: call void @use8(i8 [[XZ]]) 2625; CHECK-NEXT: call void @use8(i8 [[YZ]]) 2626; CHECK-NEXT: ret i8 [[R]] 2627; 2628 %xz = add i8 %x, %z 2629 %yz = add i8 %z, %y 2630 %r = sub i8 %xz, %yz 2631 call void @use8(i8 %xz) 2632 call void @use8(i8 %yz) 2633 ret i8 %r 2634} 2635 2636define i8 @sub_of_adds_2xc_multiuse2_fail(i8 %x, i8 %y) { 2637; CHECK-LABEL: @sub_of_adds_2xc_multiuse2_fail( 2638; CHECK-NEXT: [[XC:%.*]] = add i8 [[X:%.*]], 10 2639; CHECK-NEXT: [[YC:%.*]] = add i8 [[Y:%.*]], 11 2640; CHECK-NEXT: [[R:%.*]] = sub i8 [[XC]], [[YC]] 2641; CHECK-NEXT: call void @use8(i8 [[XC]]) 2642; CHECK-NEXT: call void @use8(i8 [[YC]]) 2643; CHECK-NEXT: ret i8 [[R]] 2644; 2645 %xc = add i8 %x, 10 2646 %yc = add i8 %y, 11 2647 %r = sub i8 %xc, %yc 2648 call void @use8(i8 %xc) 2649 call void @use8(i8 %yc) 2650 ret i8 %r 2651} 2652 2653define i8 @sub_of_adds_2xc(i8 %x, i8 %y) { 2654; CHECK-LABEL: @sub_of_adds_2xc( 2655; CHECK-NEXT: [[TMP1:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] 2656; CHECK-NEXT: [[R:%.*]] = add i8 [[TMP1]], 2 2657; CHECK-NEXT: ret i8 [[R]] 2658; 2659 %xc = add i8 %x, 10 2660 %yc = add i8 %y, 8 2661 %r = sub i8 %xc, %yc 2662 ret i8 %r 2663} 2664 2665define i32 @sub_infer_nuw_from_domcond(i32 %x, i32 %y) { 2666; CHECK-LABEL: @sub_infer_nuw_from_domcond( 2667; CHECK-NEXT: [[COND_NOT:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 2668; CHECK-NEXT: br i1 [[COND_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] 2669; CHECK: if.then: 2670; CHECK-NEXT: [[SUB:%.*]] = sub nuw i32 [[X]], [[Y]] 2671; CHECK-NEXT: ret i32 [[SUB]] 2672; CHECK: if.else: 2673; CHECK-NEXT: ret i32 0 2674; 2675 %cond = icmp uge i32 %x, %y 2676 br i1 %cond, label %if.then, label %if.else 2677 2678if.then: 2679 %sub = sub i32 %x, %y 2680 ret i32 %sub 2681 2682if.else: 2683 ret i32 0 2684} 2685 2686define i1 @sub_infer_nuw_from_domcond_fold1(i32 %x, i32 %y) { 2687; CHECK-LABEL: @sub_infer_nuw_from_domcond_fold1( 2688; CHECK-NEXT: [[COND_NOT:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 2689; CHECK-NEXT: br i1 [[COND_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] 2690; CHECK: if.then: 2691; CHECK-NEXT: ret i1 false 2692; CHECK: if.else: 2693; CHECK-NEXT: ret i1 false 2694; 2695 %cond = icmp uge i32 %x, %y 2696 br i1 %cond, label %if.then, label %if.else 2697 2698if.then: 2699 %ext0 = zext i32 %y to i64 2700 %ext1 = zext i32 %x to i64 2701 %sub = sub i32 %x, %y 2702 %ext2 = zext i32 %sub to i64 2703 %add = add nuw nsw i64 %ext2, %ext0 2704 %cmp = icmp ugt i64 %add, %ext1 2705 ret i1 %cmp 2706 2707if.else: 2708 ret i1 false 2709} 2710 2711define i64 @sub_infer_nuw_from_domcond_fold2(i32 range(i32 0, 2147483648) %x, i32 range(i32 0, 2147483648) %y) { 2712; CHECK-LABEL: @sub_infer_nuw_from_domcond_fold2( 2713; CHECK-NEXT: [[COND_NOT:%.*]] = icmp samesign ult i32 [[X:%.*]], [[Y:%.*]] 2714; CHECK-NEXT: br i1 [[COND_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] 2715; CHECK: if.then: 2716; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[X]], [[Y]] 2717; CHECK-NEXT: [[EXT:%.*]] = zext nneg i32 [[SUB]] to i64 2718; CHECK-NEXT: ret i64 [[EXT]] 2719; CHECK: if.else: 2720; CHECK-NEXT: ret i64 0 2721; 2722 %cond = icmp uge i32 %x, %y 2723 br i1 %cond, label %if.then, label %if.else 2724 2725if.then: 2726 %sub = sub i32 %x, %y 2727 %ext = zext i32 %sub to i64 2728 ret i64 %ext 2729 2730if.else: 2731 ret i64 0 2732} 2733 2734define i1 @sub_infer_nuw_from_domcond_fold3(i16 %xx, i32 range(i32 0, 12) %y) { 2735; CHECK-LABEL: @sub_infer_nuw_from_domcond_fold3( 2736; CHECK-NEXT: [[X:%.*]] = zext i16 [[XX:%.*]] to i32 2737; CHECK-NEXT: [[COND:%.*]] = icmp samesign ugt i32 [[Y:%.*]], [[X]] 2738; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 2739; CHECK: if.then: 2740; CHECK-NEXT: ret i1 false 2741; CHECK: if.else: 2742; CHECK-NEXT: ret i1 false 2743; 2744 %x = zext i16 %xx to i32 2745 %cond = icmp ult i32 %x, %y 2746 br i1 %cond, label %if.then, label %if.else 2747 2748if.then: 2749 %sub = sub nsw i32 %y, %x 2750 %cmp = icmp eq i32 %sub, -1 2751 ret i1 %cmp 2752 2753if.else: 2754 ret i1 false 2755} 2756 2757; negative tests 2758 2759define i32 @sub_infer_nuw_from_domcond_wrong_pred(i32 %x, i32 %y) { 2760; CHECK-LABEL: @sub_infer_nuw_from_domcond_wrong_pred( 2761; CHECK-NEXT: [[COND_NOT:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]] 2762; CHECK-NEXT: br i1 [[COND_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] 2763; CHECK: if.then: 2764; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X]], [[Y]] 2765; CHECK-NEXT: ret i32 [[SUB]] 2766; CHECK: if.else: 2767; CHECK-NEXT: ret i32 0 2768; 2769 %cond = icmp sge i32 %x, %y 2770 br i1 %cond, label %if.then, label %if.else 2771 2772if.then: 2773 %sub = sub i32 %x, %y 2774 ret i32 %sub 2775 2776if.else: 2777 ret i32 0 2778} 2779 2780define i32 @sub_infer_nuw_from_domcond_lhs_is_false(i32 %x, i32 %y) { 2781; CHECK-LABEL: @sub_infer_nuw_from_domcond_lhs_is_false( 2782; CHECK-NEXT: [[COND_NOT:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 2783; CHECK-NEXT: br i1 [[COND_NOT]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 2784; CHECK: if.then: 2785; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X]], [[Y]] 2786; CHECK-NEXT: ret i32 [[SUB]] 2787; CHECK: if.else: 2788; CHECK-NEXT: ret i32 0 2789; 2790 %cond = icmp uge i32 %x, %y 2791 br i1 %cond, label %if.else, label %if.then 2792 2793if.then: 2794 %sub = sub i32 %x, %y 2795 ret i32 %sub 2796 2797if.else: 2798 ret i32 0 2799} 2800 2801define i32 @fold_sub_and_into_andn(i32 %x) { 2802; CHECK-LABEL: @fold_sub_and_into_andn( 2803; CHECK-NEXT: entry: 2804; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[X:%.*]], 63 2805; CHECK-NEXT: [[AND:%.*]] = xor i32 [[TMP0]], 63 2806; CHECK-NEXT: ret i32 [[AND]] 2807; 2808entry: 2809 %sub = sub i32 63, %x 2810 %and = and i32 %sub, 63 2811 ret i32 %and 2812} 2813 2814define i1 @fold_sub_and_into_andn_icmp(i32 %x) { 2815; CHECK-LABEL: @fold_sub_and_into_andn_icmp( 2816; CHECK-NEXT: entry: 2817; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[X:%.*]], 63 2818; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], 63 2819; CHECK-NEXT: ret i1 [[CMP]] 2820; 2821entry: 2822 %sub = sub i32 63, %x 2823 %and = and i32 %sub, 63 2824 %cmp = icmp eq i32 %and, 0 2825 ret i1 %cmp 2826} 2827 2828define i32 @fold_sub_and_into_andn_subset(i32 %x) { 2829; CHECK-LABEL: @fold_sub_and_into_andn_subset( 2830; CHECK-NEXT: entry: 2831; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[X:%.*]], 31 2832; CHECK-NEXT: [[AND:%.*]] = xor i32 [[TMP0]], 31 2833; CHECK-NEXT: ret i32 [[AND]] 2834; 2835entry: 2836 %sub = sub i32 63, %x 2837 %and = and i32 %sub, 31 2838 ret i32 %and 2839} 2840 2841; Negative tests 2842 2843define i32 @fold_sub_and_into_andn_nonmask(i32 %x, i32 %y) { 2844; CHECK-LABEL: @fold_sub_and_into_andn_nonmask( 2845; CHECK-NEXT: entry: 2846; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[Y:%.*]], [[X:%.*]] 2847; CHECK-NEXT: [[AND:%.*]] = and i32 [[SUB]], 63 2848; CHECK-NEXT: ret i32 [[AND]] 2849; 2850entry: 2851 %sub = sub i32 %y, %x 2852 %and = and i32 %sub, 63 2853 ret i32 %and 2854} 2855 2856define i32 @fold_sub_and_into_andn_superset(i32 %x) { 2857; CHECK-LABEL: @fold_sub_and_into_andn_superset( 2858; CHECK-NEXT: entry: 2859; CHECK-NEXT: [[SUB:%.*]] = sub i32 63, [[X:%.*]] 2860; CHECK-NEXT: [[AND:%.*]] = and i32 [[SUB]], 127 2861; CHECK-NEXT: ret i32 [[AND]] 2862; 2863entry: 2864 %sub = sub i32 63, %x 2865 %and = and i32 %sub, 127 2866 ret i32 %and 2867} 2868