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 (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 <2 x i32> @test44vec(<2 x i32> %x) { 834; CHECK-LABEL: @test44vec( 835; CHECK-NEXT: [[SUB:%.*]] = add nsw <2 x i32> [[X:%.*]], <i32 -32768, 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:%.*]], shufflevector (<vscale x 2 x i32> insertelement (<vscale x 2 x i32> poison, i32 -32768, i32 0), <vscale x 2 x i32> poison, <vscale x 2 x i32> zeroinitializer) 845; CHECK-NEXT: ret <vscale x 2 x i32> [[SUB]] 846; 847 %sub = sub nsw <vscale x 2 x i32> %x, shufflevector (<vscale x 2 x i32> insertelement (<vscale x 2 x i32> undef, i32 32768, i32 0), <vscale x 2 x i32> undef, <vscale x 2 x i32> zeroinitializer) 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:%.*]], <i16 -32768, 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:%.*]], shufflevector (<vscale x 2 x i16> insertelement (<vscale x 2 x i16> poison, i16 -32768, i32 0), <vscale x 2 x i16> poison, <vscale x 2 x i32> zeroinitializer) 865; CHECK-NEXT: ret <vscale x 2 x i16> [[SUB]] 866; 867 %sub = sub nsw <vscale x 2 x i16> %x, shufflevector (<vscale x 2 x i16> insertelement (<vscale x 2 x i16> undef, i16 -32768, i32 0), <vscale x 2 x i16> undef, <vscale x 2 x i32> zeroinitializer) 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 [[X_NOT]], [[Y:%.*]] 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 [[X_NOT]], [[Y:%.*]] 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> <i32 -877, i32 -877>, <2 x i32> <i32 113, 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> [ <i32 -877, i32 -877>, [[ENTRY:%.*]] ], [ <i32 113, 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 i8* 1109@dummy_global2 = external global i8* 1110 1111define i64 @test58([100 x [100 x i8]]* %foo, i64 %i, i64 %j) { 1112; CHECK-LABEL: @test58( 1113; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[I:%.*]], [[J:%.*]] 1114; CHECK-NEXT: ret i64 [[TMP1]] 1115; 1116 %gep1 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 %i 1117 %gep2 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 %j 1118 %cast1 = ptrtoint i8* %gep1 to i64 1119 %cast2 = ptrtoint i8* %gep2 to i64 1120 %sub = sub i64 %cast1, %cast2 1121 ret i64 %sub 1122} 1123 1124define i64 @test59([100 x [100 x i8]]* %foo, i64 %i) { 1125; CHECK-LABEL: @test59( 1126; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* [[FOO:%.*]], i64 0, i64 42, i64 [[I:%.*]] 1127; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* [[FOO]], i64 0, i64 42, i64 0 1128; CHECK-NEXT: store i8* [[GEP1]], i8** @dummy_global1, align 8 1129; CHECK-NEXT: store i8* [[GEP2]], i8** @dummy_global2, align 8 1130; CHECK-NEXT: ret i64 [[I]] 1131; 1132; gep1 and gep2 have more than one uses 1133 %gep1 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 %i 1134 %gep2 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 0 1135 %cast1 = ptrtoint i8* %gep1 to i64 1136 %cast2 = ptrtoint i8* %gep2 to i64 1137 %sub = sub i64 %cast1, %cast2 1138 store i8* %gep1, i8** @dummy_global1 1139 store i8* %gep2, i8** @dummy_global2 1140 ret i64 %sub 1141} 1142 1143define i64 @test60([100 x [100 x i8]]* %foo, i64 %i, i64 %j) { 1144; CHECK-LABEL: @test60( 1145; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* [[FOO:%.*]], i64 0, i64 [[J:%.*]], i64 [[I:%.*]] 1146; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* [[FOO]], i64 0, i64 42, i64 0 1147; CHECK-NEXT: [[CAST1:%.*]] = ptrtoint i8* [[GEP1]] to i64 1148; CHECK-NEXT: [[CAST2:%.*]] = ptrtoint i8* [[GEP2]] to i64 1149; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[CAST1]], [[CAST2]] 1150; CHECK-NEXT: store i8* [[GEP1]], i8** @dummy_global1, align 8 1151; CHECK-NEXT: ret i64 [[SUB]] 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]], [100 x [100 x i8]]* %foo, i64 0, i64 %j, i64 %i 1155 %gep2 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 0 1156 %cast1 = ptrtoint i8* %gep1 to i64 1157 %cast2 = ptrtoint i8* %gep2 to i64 1158 %sub = sub i64 %cast1, %cast2 1159 store i8* %gep1, i8** @dummy_global1 1160 ret i64 %sub 1161} 1162 1163define i64 @test61([100 x [100 x i8]]* %foo, i64 %i, i64 %j) { 1164; CHECK-LABEL: @test61( 1165; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* [[FOO:%.*]], i64 0, i64 42, i64 0 1166; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* [[FOO]], i64 0, i64 [[J:%.*]], i64 [[I:%.*]] 1167; CHECK-NEXT: [[CAST1:%.*]] = ptrtoint i8* [[GEP1]] to i64 1168; CHECK-NEXT: [[CAST2:%.*]] = ptrtoint i8* [[GEP2]] to i64 1169; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[CAST1]], [[CAST2]] 1170; CHECK-NEXT: store i8* [[GEP2]], i8** @dummy_global2, align 8 1171; CHECK-NEXT: ret i64 [[SUB]] 1172; 1173; gep2 has a non-constant index and more than one uses. Shouldn't duplicate the arithmetic. 1174 %gep1 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 42, i64 0 1175 %gep2 = getelementptr inbounds [100 x [100 x i8]], [100 x [100 x i8]]* %foo, i64 0, i64 %j, i64 %i 1176 %cast1 = ptrtoint i8* %gep1 to i64 1177 %cast2 = ptrtoint i8* %gep2 to i64 1178 %sub = sub i64 %cast1, %cast2 1179 store i8* %gep2, i8** @dummy_global2 1180 ret i64 %sub 1181} 1182 1183define i32 @test62(i32 %A) { 1184; CHECK-LABEL: @test62( 1185; CHECK-NEXT: [[DOTNEG:%.*]] = mul i32 [[A:%.*]], -2 1186; CHECK-NEXT: [[C:%.*]] = add i32 [[DOTNEG]], 2 1187; CHECK-NEXT: ret i32 [[C]] 1188; 1189 %B = sub i32 1, %A 1190 %C = shl i32 %B, 1 1191 ret i32 %C 1192} 1193 1194define <2 x i32> @test62vec(<2 x i32> %A) { 1195; CHECK-LABEL: @test62vec( 1196; CHECK-NEXT: [[DOTNEG:%.*]] = mul <2 x i32> [[A:%.*]], <i32 -2, i32 -2> 1197; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[DOTNEG]], <i32 2, i32 2> 1198; CHECK-NEXT: ret <2 x i32> [[C]] 1199; 1200 %B = sub <2 x i32> <i32 1, i32 1>, %A 1201 %C = shl <2 x i32> %B, <i32 1, i32 1> 1202 ret <2 x i32> %C 1203} 1204 1205define i32 @test63(i32 %A) { 1206; CHECK-LABEL: @test63( 1207; CHECK-NEXT: [[DOTNEG_NEG:%.*]] = shl i32 [[A:%.*]], 1 1208; CHECK-NEXT: ret i32 [[DOTNEG_NEG]] 1209; 1210 %B = sub i32 1, %A 1211 %C = shl i32 %B, 1 1212 %D = sub i32 2, %C 1213 ret i32 %D 1214} 1215 1216define <2 x i32> @test63vec(<2 x i32> %A) { 1217; CHECK-LABEL: @test63vec( 1218; CHECK-NEXT: [[DOTNEG_NEG:%.*]] = shl <2 x i32> [[A:%.*]], <i32 1, i32 1> 1219; CHECK-NEXT: ret <2 x i32> [[DOTNEG_NEG]] 1220; 1221 %B = sub <2 x i32> <i32 1, i32 1>, %A 1222 %C = shl <2 x i32> %B, <i32 1, i32 1> 1223 %D = sub <2 x i32> <i32 2, i32 2>, %C 1224 ret <2 x i32> %D 1225} 1226 1227define i32 @test64(i32 %x) { 1228; CHECK-LABEL: @test64( 1229; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 255) 1230; CHECK-NEXT: [[DOTNEG:%.*]] = add nsw i32 [[TMP1]], 1 1231; CHECK-NEXT: ret i32 [[DOTNEG]] 1232; 1233 %1 = xor i32 %x, -1 1234 %2 = icmp sgt i32 %1, -256 1235 %3 = select i1 %2, i32 %1, i32 -256 1236 %res = sub i32 0, %3 1237 ret i32 %res 1238} 1239 1240define i32 @test65(i32 %x) { 1241; CHECK-LABEL: @test65( 1242; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 -256) 1243; CHECK-NEXT: [[DOTNEG:%.*]] = add i32 [[TMP1]], 1 1244; CHECK-NEXT: ret i32 [[DOTNEG]] 1245; 1246 %1 = xor i32 %x, -1 1247 %2 = icmp slt i32 %1, 255 1248 %3 = select i1 %2, i32 %1, i32 255 1249 %res = sub i32 0, %3 1250 ret i32 %res 1251} 1252 1253define i32 @test66(i32 %x) { 1254; CHECK-LABEL: @test66( 1255; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 -101) 1256; CHECK-NEXT: [[DOTNEG:%.*]] = add nuw i32 [[TMP1]], 1 1257; CHECK-NEXT: ret i32 [[DOTNEG]] 1258; 1259 %1 = xor i32 %x, -1 1260 %2 = icmp ugt i32 %1, 100 1261 %3 = select i1 %2, i32 %1, i32 100 1262 %res = sub i32 0, %3 1263 ret i32 %res 1264} 1265 1266define i32 @test67(i32 %x) { 1267; CHECK-LABEL: @test67( 1268; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 100) 1269; CHECK-NEXT: [[DOTNEG:%.*]] = add i32 [[TMP1]], 1 1270; CHECK-NEXT: ret i32 [[DOTNEG]] 1271; 1272 %1 = xor i32 %x, -1 1273 %2 = icmp ult i32 %1, -101 1274 %3 = select i1 %2, i32 %1, i32 -101 1275 %res = sub i32 0, %3 1276 ret i32 %res 1277} 1278 1279; Check splat vectors too 1280define <2 x i32> @test68(<2 x i32> %x) { 1281; CHECK-LABEL: @test68( 1282; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 255, i32 255>) 1283; CHECK-NEXT: [[DOTNEG:%.*]] = add nsw <2 x i32> [[TMP1]], <i32 1, i32 1> 1284; CHECK-NEXT: ret <2 x i32> [[DOTNEG]] 1285; 1286 %1 = xor <2 x i32> %x, <i32 -1, i32 -1> 1287 %2 = icmp sgt <2 x i32> %1, <i32 -256, i32 -256> 1288 %3 = select <2 x i1> %2, <2 x i32> %1, <2 x i32> <i32 -256, i32 -256> 1289 %res = sub <2 x i32> zeroinitializer, %3 1290 ret <2 x i32> %res 1291} 1292 1293; And non-splat constant vectors. 1294define <2 x i32> @test69(<2 x i32> %x) { 1295; CHECK-LABEL: @test69( 1296; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 255, i32 127>) 1297; CHECK-NEXT: [[DOTNEG:%.*]] = add <2 x i32> [[TMP1]], <i32 1, i32 1> 1298; CHECK-NEXT: ret <2 x i32> [[DOTNEG]] 1299; 1300 %1 = xor <2 x i32> %x, <i32 -1, i32 -1> 1301 %2 = icmp sgt <2 x i32> %1, <i32 -256, i32 -128> 1302 %3 = select <2 x i1> %2, <2 x i32> %1, <2 x i32> <i32 -256, i32 -128> 1303 %res = sub <2 x i32> zeroinitializer, %3 1304 ret <2 x i32> %res 1305} 1306 1307; Check (X | Y) - Y --> X & ~Y when Y is a constant 1308define i32 @test70(i32 %A) { 1309; CHECK-LABEL: @test70( 1310; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], -124 1311; CHECK-NEXT: ret i32 [[TMP1]] 1312; 1313 %B = or i32 %A, 123 1314 %C = sub i32 %B, 123 1315 ret i32 %C 1316} 1317 1318; Check (X | Y) - Y --> (X | Y) ^ Y doesn't happen where (X | Y) has multiple uses 1319define i32 @test71(i32 %A, i32 %B) { 1320; CHECK-LABEL: @test71( 1321; CHECK-NEXT: [[C:%.*]] = or i32 [[A:%.*]], [[B:%.*]] 1322; CHECK-NEXT: [[D:%.*]] = sub i32 [[C]], [[B]] 1323; CHECK-NEXT: [[E:%.*]] = mul i32 [[C]], [[D]] 1324; CHECK-NEXT: ret i32 [[E]] 1325; 1326 %C = or i32 %A, %B 1327 %D = sub i32 %C, %B 1328 %E = mul i32 %C, %D 1329 ret i32 %E 1330} 1331 1332; Check (X | Y) - Y --> X & ~Y where X and Y are vectors 1333define <2 x i32> @test72(<2 x i32> %A, <2 x i32> %B) { 1334; CHECK-LABEL: @test72( 1335; CHECK-NEXT: [[B_NOT:%.*]] = xor <2 x i32> [[B:%.*]], <i32 -1, i32 -1> 1336; CHECK-NEXT: [[D:%.*]] = and <2 x i32> [[B_NOT]], [[A:%.*]] 1337; CHECK-NEXT: ret <2 x i32> [[D]] 1338; 1339 %C = or <2 x i32> %A, %B 1340 %D = sub <2 x i32> %C, %B 1341 ret <2 x i32> %D 1342} 1343 1344; Check reversing sub operands won't trigger (X | Y) - Y --> X & ~Y 1345define i32 @test73(i32 %A, i32 %B) { 1346; CHECK-LABEL: @test73( 1347; CHECK-NEXT: [[C:%.*]] = or i32 [[A:%.*]], [[B:%.*]] 1348; CHECK-NEXT: [[D:%.*]] = sub i32 [[B]], [[C]] 1349; CHECK-NEXT: ret i32 [[D]] 1350; 1351 %C = or i32 %A, %B 1352 %D = sub i32 %B, %C 1353 ret i32 %D 1354} 1355 1356define i32 @nsw_inference1(i32 %x, i32 %y) { 1357; CHECK-LABEL: @nsw_inference1( 1358; CHECK-NEXT: [[X2:%.*]] = or i32 [[X:%.*]], 1024 1359; CHECK-NEXT: [[Y2:%.*]] = and i32 [[Y:%.*]], 1 1360; CHECK-NEXT: [[Z:%.*]] = sub nuw nsw i32 [[X2]], [[Y2]] 1361; CHECK-NEXT: ret i32 [[Z]] 1362; 1363 %x2 = or i32 %x, 1024 1364 %y2 = and i32 %y, 1 1365 %z = sub i32 %x2, %y2 1366 ret i32 %z 1367} 1368 1369define i32 @nsw_inference2(i32 %x, i32 %y) { 1370; CHECK-LABEL: @nsw_inference2( 1371; CHECK-NEXT: [[X2:%.*]] = and i32 [[X:%.*]], -1025 1372; CHECK-NEXT: [[Y2:%.*]] = or i32 [[Y:%.*]], -2 1373; CHECK-NEXT: [[Z:%.*]] = sub nsw i32 [[X2]], [[Y2]] 1374; CHECK-NEXT: ret i32 [[Z]] 1375; 1376 %x2 = and i32 %x, -1025 1377 %y2 = or i32 %y, -2 1378 %z = sub i32 %x2, %y2 1379 ret i32 %z 1380} 1381 1382define i8 @test74(i8 %x, i8 %y) { 1383; CHECK-LABEL: @test74( 1384; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], [[Y:%.*]] 1385; CHECK-NEXT: call void @use8(i8 [[T0]]) 1386; CHECK-NEXT: [[T1:%.*]] = sub i8 [[X]], [[T0]] 1387; CHECK-NEXT: ret i8 [[T1]] 1388; 1389 %t0 = and i8 %x, %y 1390 call void @use8(i8 %t0) 1391 %t1 = sub i8 %x, %t0 1392 ret i8 %t1 1393} 1394 1395define i8 @test75(i8 %x) { 1396; CHECK-LABEL: @test75( 1397; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], -8 1398; CHECK-NEXT: call void @use8(i8 [[T0]]) 1399; CHECK-NEXT: [[T1:%.*]] = and i8 [[X]], 7 1400; CHECK-NEXT: ret i8 [[T1]] 1401; 1402 %t0 = and i8 %x, -8 1403 call void @use8(i8 %t0) 1404 %t1 = sub i8 %x, %t0 1405 ret i8 %t1 1406} 1407 1408; ((w-x) + y) - z --> (w+y) - (x+z) 1409 1410define i8 @sub_add_sub_reassoc(i8 %w, i8 %x, i8 %y, i8 %z) { 1411; CHECK-LABEL: @sub_add_sub_reassoc( 1412; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[W:%.*]], [[Y:%.*]] 1413; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[X:%.*]], [[Z:%.*]] 1414; CHECK-NEXT: [[S2:%.*]] = sub i8 [[TMP1]], [[TMP2]] 1415; CHECK-NEXT: ret i8 [[S2]] 1416; 1417 %s1 = sub i8 %w, %x 1418 %a = add i8 %s1, %y 1419 %s2 = sub i8 %a, %z 1420 ret i8 %s2 1421} 1422 1423; vectors work too. 1424 1425define <2 x i8> @sub_add_sub_reassoc_commute(<2 x i8> %w, <2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 1426; CHECK-LABEL: @sub_add_sub_reassoc_commute( 1427; CHECK-NEXT: [[D:%.*]] = sdiv <2 x i8> [[Y:%.*]], <i8 42, i8 -42> 1428; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[D]], [[W:%.*]] 1429; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i8> [[X:%.*]], [[Z:%.*]] 1430; CHECK-NEXT: [[S2:%.*]] = sub <2 x i8> [[TMP1]], [[TMP2]] 1431; CHECK-NEXT: ret <2 x i8> [[S2]] 1432; 1433 %d = sdiv <2 x i8> %y, <i8 42, i8 -42> ; thwart complexity-based canonicalization 1434 %s1 = sub <2 x i8> %w, %x 1435 %a = add <2 x i8> %d, %s1 1436 %s2 = sub <2 x i8> %a, %z 1437 ret <2 x i8> %s2 1438} 1439 1440; (v-w) + (x-y) - z --> (v+x) - (w+y+z) 1441 1442define i8 @sub_add_sub_reassoc_twice(i8 %v, i8 %w, i8 %x, i8 %y, i8 %z) { 1443; CHECK-LABEL: @sub_add_sub_reassoc_twice( 1444; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[W:%.*]], [[Z:%.*]] 1445; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[X:%.*]], [[V:%.*]] 1446; CHECK-NEXT: [[TMP3:%.*]] = add i8 [[TMP1]], [[Y:%.*]] 1447; CHECK-NEXT: [[S3:%.*]] = sub i8 [[TMP2]], [[TMP3]] 1448; CHECK-NEXT: ret i8 [[S3]] 1449; 1450 %s1 = sub i8 %v, %w 1451 %s2 = sub i8 %x, %y 1452 %a = add i8 %s1, %s2 1453 %s3 = sub i8 %a, %z 1454 ret i8 %s3 1455} 1456 1457; negative test - uses 1458 1459define i8 @sub_add_sub_reassoc_use1(i8 %w, i8 %x, i8 %y, i8 %z) { 1460; CHECK-LABEL: @sub_add_sub_reassoc_use1( 1461; CHECK-NEXT: [[S1:%.*]] = sub i8 [[W:%.*]], [[X:%.*]] 1462; CHECK-NEXT: call void @use8(i8 [[S1]]) 1463; CHECK-NEXT: [[A:%.*]] = add i8 [[S1]], [[Y:%.*]] 1464; CHECK-NEXT: [[S2:%.*]] = sub i8 [[A]], [[Z:%.*]] 1465; CHECK-NEXT: ret i8 [[S2]] 1466; 1467 %s1 = sub i8 %w, %x 1468 call void @use8(i8 %s1) 1469 %a = add i8 %s1, %y 1470 %s2 = sub i8 %a, %z 1471 ret i8 %s2 1472} 1473 1474; negative test - uses 1475 1476define i8 @sub_add_sub_reassoc_use2(i8 %w, i8 %x, i8 %y, i8 %z) { 1477; CHECK-LABEL: @sub_add_sub_reassoc_use2( 1478; CHECK-NEXT: [[S1:%.*]] = sub i8 [[W:%.*]], [[X:%.*]] 1479; CHECK-NEXT: [[A:%.*]] = add i8 [[S1]], [[Y:%.*]] 1480; CHECK-NEXT: call void @use8(i8 [[A]]) 1481; CHECK-NEXT: [[S2:%.*]] = sub i8 [[A]], [[Z:%.*]] 1482; CHECK-NEXT: ret i8 [[S2]] 1483; 1484 %s1 = sub i8 %w, %x 1485 %a = add i8 %s1, %y 1486 call void @use8(i8 %a) 1487 %s2 = sub i8 %a, %z 1488 ret i8 %s2 1489} 1490 1491define i8 @sub_mask_lowbits(i8 %x) { 1492; CHECK-LABEL: @sub_mask_lowbits( 1493; CHECK-NEXT: [[A1:%.*]] = add i8 [[X:%.*]], -108 1494; CHECK-NEXT: [[R:%.*]] = and i8 [[A1]], -4 1495; CHECK-NEXT: ret i8 [[R]] 1496; 1497 %a1 = add i8 %x, 148 ; 0x94 1498 %a2 = and i8 %x, 3 1499 %r = sub i8 %a1, %a2 1500 ret i8 %r 1501} 1502 1503; Negative test - low-bit mask must not overlap with offset 1504 1505define i8 @sub_not_mask_lowbits(i8 %x) { 1506; CHECK-LABEL: @sub_not_mask_lowbits( 1507; CHECK-NEXT: [[A1:%.*]] = add i8 [[X:%.*]], 4 1508; CHECK-NEXT: [[A2:%.*]] = and i8 [[X]], 7 1509; CHECK-NEXT: [[R:%.*]] = sub i8 [[A1]], [[A2]] 1510; CHECK-NEXT: ret i8 [[R]] 1511; 1512 %a1 = add i8 %x, 4 1513 %a2 = and i8 %x, 7 1514 %r = sub i8 %a1, %a2 1515 ret i8 %r 1516} 1517 1518define <2 x i8> @sub_mask_lowbits_splat_extra_use(<2 x i8> %x, <2 x i8>* %p) { 1519; CHECK-LABEL: @sub_mask_lowbits_splat_extra_use( 1520; CHECK-NEXT: [[A1:%.*]] = add <2 x i8> [[X:%.*]], <i8 -64, i8 -64> 1521; CHECK-NEXT: [[A2:%.*]] = and <2 x i8> [[X]], <i8 10, i8 10> 1522; CHECK-NEXT: store <2 x i8> [[A2]], <2 x i8>* [[P:%.*]], align 2 1523; CHECK-NEXT: [[R:%.*]] = and <2 x i8> [[A1]], <i8 -11, i8 -11> 1524; CHECK-NEXT: ret <2 x i8> [[R]] 1525; 1526 %a1 = add <2 x i8> %x, <i8 192, i8 192> ; 0xc0 1527 %a2 = and <2 x i8> %x, <i8 10, i8 10> ; 0x0a 1528 store <2 x i8> %a2, <2 x i8>* %p 1529 %r = sub <2 x i8> %a1, %a2 1530 ret <2 x i8> %r 1531} 1532 1533define i16 @sub_nsw_mul_nsw(i16 %x, i16 %y) { 1534; CHECK-LABEL: @sub_nsw_mul_nsw( 1535; CHECK-NEXT: [[TMP1:%.*]] = sub nsw i16 [[X:%.*]], [[Y:%.*]] 1536; CHECK-NEXT: [[R:%.*]] = shl nsw i16 [[TMP1]], 3 1537; CHECK-NEXT: ret i16 [[R]] 1538; 1539 %x8 = mul nsw i16 %x, 8 1540 %y8 = mul nsw i16 %y, 8 1541 %r = sub nsw i16 %x8, %y8 1542 ret i16 %r 1543} 1544 1545define i16 @sub_nuw_mul_nsw(i16 %x, i16 %y) { 1546; CHECK-LABEL: @sub_nuw_mul_nsw( 1547; CHECK-NEXT: [[TMP1:%.*]] = sub i16 [[X:%.*]], [[Y:%.*]] 1548; CHECK-NEXT: [[R:%.*]] = shl i16 [[TMP1]], 2 1549; CHECK-NEXT: ret i16 [[R]] 1550; 1551 %x8 = mul nsw i16 %x, 4 1552 %y8 = mul nsw i16 %y, 4 1553 %r = sub nuw i16 %x8, %y8 1554 ret i16 %r 1555} 1556 1557define i16 @sub_mul_nsw(i16 %x, i16 %y) { 1558; CHECK-LABEL: @sub_mul_nsw( 1559; CHECK-NEXT: [[TMP1:%.*]] = sub i16 [[X:%.*]], [[Y:%.*]] 1560; CHECK-NEXT: [[R:%.*]] = shl i16 [[TMP1]], 4 1561; CHECK-NEXT: ret i16 [[R]] 1562; 1563 %x8 = mul nsw i16 %x, 16 1564 %y8 = mul nsw i16 %y, 16 1565 %r = sub i16 %x8, %y8 1566 ret i16 %r 1567} 1568 1569define i16 @sub_nsw_mul_nuw(i16 %x, i16 %y) { 1570; CHECK-LABEL: @sub_nsw_mul_nuw( 1571; CHECK-NEXT: [[TMP1:%.*]] = sub i16 [[X:%.*]], [[Y:%.*]] 1572; CHECK-NEXT: [[R:%.*]] = shl i16 [[TMP1]], 3 1573; CHECK-NEXT: ret i16 [[R]] 1574; 1575 %x8 = mul nuw i16 %x, 8 1576 %y8 = mul nuw i16 %y, 8 1577 %r = sub nsw i16 %x8, %y8 1578 ret i16 %r 1579} 1580 1581define i16 @sub_nuw_mul_nuw(i16 %x, i16 %y) { 1582; CHECK-LABEL: @sub_nuw_mul_nuw( 1583; CHECK-NEXT: [[TMP1:%.*]] = sub nuw i16 [[X:%.*]], [[Y:%.*]] 1584; CHECK-NEXT: [[R:%.*]] = shl nuw i16 [[TMP1]], 4 1585; CHECK-NEXT: ret i16 [[R]] 1586; 1587 %x8 = mul nuw i16 %x, 16 1588 %y8 = mul nuw i16 %y, 16 1589 %r = sub nuw i16 %x8, %y8 1590 ret i16 %r 1591} 1592 1593define i16 @sub_mul_nuw(i16 %x, i16 %y) { 1594; CHECK-LABEL: @sub_mul_nuw( 1595; CHECK-NEXT: [[TMP1:%.*]] = sub i16 [[X:%.*]], [[Y:%.*]] 1596; CHECK-NEXT: [[R:%.*]] = shl i16 [[TMP1]], 5 1597; CHECK-NEXT: ret i16 [[R]] 1598; 1599 %x8 = mul nuw i16 %x, 32 1600 %y8 = mul nuw i16 %y, 32 1601 %r = sub i16 %x8, %y8 1602 ret i16 %r 1603} 1604define i32 @and_test(i32 %x, i32 %y) { 1605; CHECK-LABEL: @and_test( 1606; CHECK-NEXT: [[R:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 1607; CHECK-NEXT: ret i32 [[R]] 1608; 1609 %a = add i32 %x, %y 1610 %o = or i32 %x, %y 1611 %r = sub i32 %a, %o 1612 ret i32 %r 1613} 1614 1615define i32 @and_test2(i32 %x, i32 %y) { 1616; CHECK-LABEL: @and_test2( 1617; CHECK-NEXT: [[R:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 1618; CHECK-NEXT: ret i32 [[R]] 1619; 1620 %a = add i32 %x, %y 1621 %o = or i32 %y, %x 1622 %r = sub i32 %a, %o 1623 ret i32 %r 1624} 1625 1626define i32 @and_test3(i32 %x, i32 %y) { 1627; CHECK-LABEL: @and_test3( 1628; CHECK-NEXT: [[R:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 1629; CHECK-NEXT: ret i32 [[R]] 1630; 1631 %a = add i32 %y, %x 1632 %o = or i32 %x, %y 1633 %r = sub i32 %a, %o 1634 ret i32 %r 1635} 1636 1637 1638define <2 x i8> @and_vec(<2 x i8> %X, <2 x i8> %Y) { 1639; CHECK-LABEL: @and_vec( 1640; CHECK-NEXT: [[R:%.*]] = and <2 x i8> [[X:%.*]], [[Y:%.*]] 1641; CHECK-NEXT: ret <2 x i8> [[R]] 1642; 1643 %a = add <2 x i8> %X, %Y 1644 %o = or <2 x i8> %X, %Y 1645 %r = sub <2 x i8> %a, %o 1646 ret <2 x i8> %r 1647} 1648 1649define i32 @or_test(i32 %x, i32 %y) { 1650; CHECK-LABEL: @or_test( 1651; CHECK-NEXT: [[R:%.*]] = or i32 [[X:%.*]], [[Y:%.*]] 1652; CHECK-NEXT: ret i32 [[R]] 1653; 1654 %a = add i32 %x, %y 1655 %b = and i32 %x, %y 1656 %r = sub i32 %a, %b 1657 ret i32 %r 1658} 1659 1660define i32 @or_test2(i32 %x, i32 %y) { 1661; CHECK-LABEL: @or_test2( 1662; CHECK-NEXT: [[R:%.*]] = or i32 [[X:%.*]], [[Y:%.*]] 1663; CHECK-NEXT: ret i32 [[R]] 1664; 1665 %a = add i32 %x, %y 1666 %b = and i32 %y, %x 1667 %r = sub i32 %a, %b 1668 ret i32 %r 1669} 1670 1671define i32 @or_test3(i32 %x, i32 %y) { 1672; CHECK-LABEL: @or_test3( 1673; CHECK-NEXT: [[R:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] 1674; CHECK-NEXT: ret i32 [[R]] 1675; 1676 %a = add i32 %y, %x 1677 %b = and i32 %x, %y 1678 %r = sub i32 %a, %b 1679 ret i32 %r 1680} 1681 1682define <2 x i8> @or_vec(<2 x i8> %X, <2 x i8> %Y) { 1683; CHECK-LABEL: @or_vec( 1684; CHECK-NEXT: [[R:%.*]] = or <2 x i8> [[X:%.*]], [[Y:%.*]] 1685; CHECK-NEXT: ret <2 x i8> [[R]] 1686; 1687 %a = add <2 x i8> %X, %Y 1688 %b = and <2 x i8> %X, %Y 1689 %r = sub <2 x i8> %a, %b 1690 ret <2 x i8> %r 1691} 1692 1693define i32 @pr51584(i32 %a, i32 %b) { 1694; CHECK-LABEL: @pr51584( 1695; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]] 1696; CHECK-NEXT: [[DOTNEG:%.*]] = sub i32 -11, [[TMP1]] 1697; CHECK-NEXT: ret i32 [[DOTNEG]] 1698; 1699 %sub = sub i32 0, %a 1700 %add = add nsw i32 11, %b 1701 %sub1 = sub i32 %sub, %add 1702 ret i32 %sub1 1703} 1704 1705define i8 @sub_srem(i8 noundef %x, i8 %y) { 1706; CHECK-LABEL: @sub_srem( 1707; CHECK-NEXT: [[REM:%.*]] = srem i8 [[X:%.*]], [[Y:%.*]] 1708; CHECK-NEXT: [[SUB:%.*]] = sub nsw i8 [[X]], [[REM]] 1709; CHECK-NEXT: ret i8 [[SUB]] 1710; 1711 %rem = srem i8 %x, %y 1712 %sub = sub i8 %x, %rem 1713 ret i8 %sub 1714} 1715 1716define <2 x i5> @sub_urem(<2 x i5> noundef %x, <2 x i5> %y) { 1717; CHECK-LABEL: @sub_urem( 1718; CHECK-NEXT: [[REM:%.*]] = urem <2 x i5> [[X:%.*]], [[Y:%.*]] 1719; CHECK-NEXT: [[SUB:%.*]] = sub nuw <2 x i5> [[X]], [[REM]] 1720; CHECK-NEXT: ret <2 x i5> [[SUB]] 1721; 1722 %rem = urem <2 x i5> %x, %y 1723 %sub = sub <2 x i5> %x, %rem 1724 ret <2 x i5> %sub 1725} 1726 1727define <3 x i32> @nuw_const_zext(<3 x i8> %y) { 1728; CHECK-LABEL: @nuw_const_zext( 1729; CHECK-NEXT: [[ZY:%.*]] = zext <3 x i8> [[Y:%.*]] to <3 x i32> 1730; CHECK-NEXT: [[S:%.*]] = sub nuw nsw <3 x i32> <i32 255, i32 128, i32 0>, [[ZY]] 1731; CHECK-NEXT: ret <3 x i32> [[S]] 1732; 1733 %zy = zext <3 x i8> %y to <3 x i32> 1734 %s = sub nuw <3 x i32> <i32 255, i32 128, i32 0>, %zy 1735 ret <3 x i32> %s 1736} 1737 1738define i32 @nuw_const_zext_big(i8 %y) { 1739; CHECK-LABEL: @nuw_const_zext_big( 1740; CHECK-NEXT: [[ZY:%.*]] = zext i8 [[Y:%.*]] to i32 1741; CHECK-NEXT: [[S:%.*]] = sub nuw nsw i32 257, [[ZY]] 1742; CHECK-NEXT: ret i32 [[S]] 1743; 1744 %zy = zext i8 %y to i32 1745 %s = sub nuw i32 257, %zy 1746 ret i32 %s 1747} 1748 1749define i32 @nuw_zext_zext(i8 %x, i8 %y) { 1750; CHECK-LABEL: @nuw_zext_zext( 1751; CHECK-NEXT: [[ZX:%.*]] = zext i8 [[X:%.*]] to i32 1752; CHECK-NEXT: [[ZY:%.*]] = zext i8 [[Y:%.*]] to i32 1753; CHECK-NEXT: [[S:%.*]] = sub nuw nsw i32 [[ZX]], [[ZY]] 1754; CHECK-NEXT: ret i32 [[S]] 1755; 1756 %zx = zext i8 %x to i32 1757 %zy = zext i8 %y to i32 1758 %s = sub nuw i32 %zx, %zy 1759 ret i32 %s 1760} 1761 1762define <2 x i16> @nuw_zext_sext(<2 x i8> %x, <2 x i8> %y) { 1763; CHECK-LABEL: @nuw_zext_sext( 1764; CHECK-NEXT: [[ZX:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i16> 1765; CHECK-NEXT: [[SY:%.*]] = sext <2 x i8> [[Y:%.*]] to <2 x i16> 1766; CHECK-NEXT: [[S:%.*]] = sub nuw nsw <2 x i16> [[ZX]], [[SY]] 1767; CHECK-NEXT: ret <2 x i16> [[S]] 1768; 1769 %zx = zext <2 x i8> %x to <2 x i16> 1770 %sy = sext <2 x i8> %y to <2 x i16> 1771 %s = sub nuw <2 x i16> %zx, %sy 1772 ret <2 x i16> %s 1773} 1774 1775define i32 @nuw_sext_zext(i8 %x, i8 %y) { 1776; CHECK-LABEL: @nuw_sext_zext( 1777; CHECK-NEXT: [[SX:%.*]] = sext i8 [[X:%.*]] to i32 1778; CHECK-NEXT: [[ZY:%.*]] = zext i8 [[Y:%.*]] to i32 1779; CHECK-NEXT: [[S:%.*]] = sub nuw nsw i32 [[SX]], [[ZY]] 1780; CHECK-NEXT: ret i32 [[S]] 1781; 1782 %sx = sext i8 %x to i32 1783 %zy = zext i8 %y to i32 1784 %s = sub nuw i32 %sx, %zy 1785 ret i32 %s 1786} 1787 1788define i8 @nuw_zext_zext_use1(i5 %x, i5 %y) { 1789; CHECK-LABEL: @nuw_zext_zext_use1( 1790; CHECK-NEXT: [[ZX:%.*]] = zext i5 [[X:%.*]] to i8 1791; CHECK-NEXT: call void @use8(i8 [[ZX]]) 1792; CHECK-NEXT: [[ZY:%.*]] = zext i5 [[Y:%.*]] to i8 1793; CHECK-NEXT: [[S:%.*]] = sub nuw nsw i8 [[ZX]], [[ZY]] 1794; CHECK-NEXT: ret i8 [[S]] 1795; 1796 %zx = zext i5 %x to i8 1797 call void @use8(i8 %zx) 1798 %zy = zext i5 %y to i8 1799 %s = sub nuw i8 %zx, %zy 1800 ret i8 %s 1801} 1802 1803define i8 @nuw_zext_zext_use2(i5 %x, i5 %y) { 1804; CHECK-LABEL: @nuw_zext_zext_use2( 1805; CHECK-NEXT: [[ZX:%.*]] = zext i5 [[X:%.*]] to i8 1806; CHECK-NEXT: [[ZY:%.*]] = zext i5 [[Y:%.*]] to i8 1807; CHECK-NEXT: call void @use8(i8 [[ZY]]) 1808; CHECK-NEXT: [[S:%.*]] = sub nuw nsw i8 [[ZX]], [[ZY]] 1809; CHECK-NEXT: ret i8 [[S]] 1810; 1811 %zx = zext i5 %x to i8 1812 %zy = zext i5 %y to i8 1813 call void @use8(i8 %zy) 1814 %s = sub nuw i8 %zx, %zy 1815 ret i8 %s 1816} 1817 1818define i8 @nuw_zext_zext_use3(i5 %x, i5 %y) { 1819; CHECK-LABEL: @nuw_zext_zext_use3( 1820; CHECK-NEXT: [[ZX:%.*]] = zext i5 [[X:%.*]] to i8 1821; CHECK-NEXT: call void @use8(i8 [[ZX]]) 1822; CHECK-NEXT: [[ZY:%.*]] = zext i5 [[Y:%.*]] to i8 1823; CHECK-NEXT: call void @use8(i8 [[ZY]]) 1824; CHECK-NEXT: [[S:%.*]] = sub nuw nsw i8 [[ZX]], [[ZY]] 1825; CHECK-NEXT: ret i8 [[S]] 1826; 1827 %zx = zext i5 %x to i8 1828 call void @use8(i8 %zx) 1829 %zy = zext i5 %y to i8 1830 call void @use8(i8 %zy) 1831 %s = sub nuw i8 %zx, %zy 1832 ret i8 %s 1833} 1834 1835define i32 @nuw_zext_zext_different_width(i8 %x, i7 %y) { 1836; CHECK-LABEL: @nuw_zext_zext_different_width( 1837; CHECK-NEXT: [[ZX:%.*]] = zext i8 [[X:%.*]] to i32 1838; CHECK-NEXT: [[ZY:%.*]] = zext i7 [[Y:%.*]] to i32 1839; CHECK-NEXT: [[S:%.*]] = sub nuw nsw i32 [[ZX]], [[ZY]] 1840; CHECK-NEXT: ret i32 [[S]] 1841; 1842 %zx = zext i8 %x to i32 1843 %zy = zext i7 %y to i32 1844 %s = sub nuw i32 %zx, %zy 1845 ret i32 %s 1846} 1847 1848define i16 @sext_nsw_noundef(i8 noundef %x, i8 %y) { 1849; CHECK-LABEL: @sext_nsw_noundef( 1850; CHECK-NEXT: [[Z:%.*]] = sext i8 [[Y:%.*]] to i16 1851; CHECK-NEXT: ret i16 [[Z]] 1852; 1853 %d = sub nsw i8 %x, %y 1854 %ex = sext i8 %x to i16 1855 %ed = sext i8 %d to i16 1856 %z = sub i16 %ex, %ed 1857 ret i16 %z 1858} 1859 1860; negative test - requires noundef 1861 1862define i16 @sext_nsw(i8 %x, i8 %y) { 1863; CHECK-LABEL: @sext_nsw( 1864; CHECK-NEXT: [[D:%.*]] = sub nsw i8 [[X:%.*]], [[Y:%.*]] 1865; CHECK-NEXT: [[EX:%.*]] = sext i8 [[X]] to i16 1866; CHECK-NEXT: [[ED:%.*]] = sext i8 [[D]] to i16 1867; CHECK-NEXT: [[Z:%.*]] = sub nsw i16 [[EX]], [[ED]] 1868; CHECK-NEXT: ret i16 [[Z]] 1869; 1870 %d = sub nsw i8 %x, %y 1871 %ex = sext i8 %x to i16 1872 %ed = sext i8 %d to i16 1873 %z = sub i16 %ex, %ed 1874 ret i16 %z 1875} 1876 1877; negative test - requires nsw 1878 1879define i16 @sext_noundef(i8 noundef %x, i8 %y) { 1880; CHECK-LABEL: @sext_noundef( 1881; CHECK-NEXT: [[D:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] 1882; CHECK-NEXT: [[EX:%.*]] = sext i8 [[X]] to i16 1883; CHECK-NEXT: [[ED:%.*]] = sext i8 [[D]] to i16 1884; CHECK-NEXT: [[Z:%.*]] = sub nsw i16 [[EX]], [[ED]] 1885; CHECK-NEXT: ret i16 [[Z]] 1886; 1887 %d = sub i8 %x, %y 1888 %ex = sext i8 %x to i16 1889 %ed = sext i8 %d to i16 1890 %z = sub i16 %ex, %ed 1891 ret i16 %z 1892} 1893 1894; negative test - must have common operand 1895 1896define i16 @sext_nsw_noundef_wrong_val(i8 noundef %x, i8 noundef %y, i8 noundef %q) { 1897; CHECK-LABEL: @sext_nsw_noundef_wrong_val( 1898; CHECK-NEXT: [[D:%.*]] = sub nsw i8 [[X:%.*]], [[Y:%.*]] 1899; CHECK-NEXT: [[EQ:%.*]] = sext i8 [[Q:%.*]] to i16 1900; CHECK-NEXT: [[ED:%.*]] = sext i8 [[D]] to i16 1901; CHECK-NEXT: [[Z:%.*]] = sub nsw i16 [[EQ]], [[ED]] 1902; CHECK-NEXT: ret i16 [[Z]] 1903; 1904 %d = sub nsw i8 %x, %y 1905 %eq = sext i8 %q to i16 1906 %ed = sext i8 %d to i16 1907 %z = sub i16 %eq, %ed 1908 ret i16 %z 1909} 1910 1911; two no-wrap analyses combine to allow reduction 1912 1913define i16 @srem_sext_noundef(i8 noundef %x, i8 %y) { 1914; CHECK-LABEL: @srem_sext_noundef( 1915; CHECK-NEXT: [[R:%.*]] = srem i8 [[X:%.*]], [[Y:%.*]] 1916; CHECK-NEXT: [[Z:%.*]] = sext i8 [[R]] to i16 1917; CHECK-NEXT: ret i16 [[Z]] 1918; 1919 %r = srem i8 %x, %y 1920 %d = sub i8 %x, %r 1921 %sd = sext i8 %d to i16 1922 %sx = sext i8 %x to i16 1923 %z = sub i16 %sx, %sd 1924 ret i16 %z 1925} 1926 1927define i16 @zext_nuw_noundef(i8 noundef %x, i8 %y) { 1928; CHECK-LABEL: @zext_nuw_noundef( 1929; CHECK-NEXT: [[Z:%.*]] = zext i8 [[Y:%.*]] to i16 1930; CHECK-NEXT: ret i16 [[Z]] 1931; 1932 %d = sub nuw i8 %x, %y 1933 %ex = zext i8 %x to i16 1934 %ed = zext i8 %d to i16 1935 %z = sub i16 %ex, %ed 1936 ret i16 %z 1937} 1938 1939; negative test - requires noundef 1940 1941define i16 @zext_nuw(i8 %x, i8 %y) { 1942; CHECK-LABEL: @zext_nuw( 1943; CHECK-NEXT: [[D:%.*]] = sub nuw i8 [[X:%.*]], [[Y:%.*]] 1944; CHECK-NEXT: [[EX:%.*]] = zext i8 [[X]] to i16 1945; CHECK-NEXT: [[ED:%.*]] = zext i8 [[D]] to i16 1946; CHECK-NEXT: [[Z:%.*]] = sub nsw i16 [[EX]], [[ED]] 1947; CHECK-NEXT: ret i16 [[Z]] 1948; 1949 %d = sub nuw i8 %x, %y 1950 %ex = zext i8 %x to i16 1951 %ed = zext i8 %d to i16 1952 %z = sub i16 %ex, %ed 1953 ret i16 %z 1954} 1955 1956; negative test - requires nuw 1957 1958define i16 @zext_noundef(i8 noundef %x, i8 %y) { 1959; CHECK-LABEL: @zext_noundef( 1960; CHECK-NEXT: [[D:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] 1961; CHECK-NEXT: [[EX:%.*]] = zext i8 [[X]] to i16 1962; CHECK-NEXT: [[ED:%.*]] = zext i8 [[D]] to i16 1963; CHECK-NEXT: [[Z:%.*]] = sub nsw i16 [[EX]], [[ED]] 1964; CHECK-NEXT: ret i16 [[Z]] 1965; 1966 %d = sub i8 %x, %y 1967 %ex = zext i8 %x to i16 1968 %ed = zext i8 %d to i16 1969 %z = sub i16 %ex, %ed 1970 ret i16 %z 1971} 1972 1973; negative test - must have common operand 1974 1975define i16 @zext_nsw_noundef_wrong_val(i8 noundef %x, i8 noundef %y, i8 noundef %q) { 1976; CHECK-LABEL: @zext_nsw_noundef_wrong_val( 1977; CHECK-NEXT: [[D:%.*]] = sub nuw i8 [[X:%.*]], [[Y:%.*]] 1978; CHECK-NEXT: [[EQ:%.*]] = zext i8 [[Q:%.*]] to i16 1979; CHECK-NEXT: [[ED:%.*]] = zext i8 [[D]] to i16 1980; CHECK-NEXT: [[Z:%.*]] = sub nsw i16 [[EQ]], [[ED]] 1981; CHECK-NEXT: ret i16 [[Z]] 1982; 1983 %d = sub nuw i8 %x, %y 1984 %eq = zext i8 %q to i16 1985 %ed = zext i8 %d to i16 1986 %z = sub i16 %eq, %ed 1987 ret i16 %z 1988} 1989 1990; two no-wrap analyses combine to allow reduction 1991 1992define i16 @urem_zext_noundef(i8 noundef %x, i8 %y) { 1993; CHECK-LABEL: @urem_zext_noundef( 1994; CHECK-NEXT: [[R:%.*]] = urem i8 [[X:%.*]], [[Y:%.*]] 1995; CHECK-NEXT: [[Z:%.*]] = zext i8 [[R]] to i16 1996; CHECK-NEXT: ret i16 [[Z]] 1997; 1998 %r = urem i8 %x, %y 1999 %d = sub i8 %x, %r 2000 %ed = zext i8 %d to i16 2001 %ex = zext i8 %x to i16 2002 %z = sub i16 %ex, %ed 2003 ret i16 %z 2004} 2005