1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4declare void @use4(i4) 5declare void @use8(i8) 6declare void @use_v2i4(<2 x i4>) 7declare i1 @use32gen1(i32) 8 9; Constant can be freely negated. 10define i8 @t0(i8 %x) { 11; CHECK-LABEL: @t0( 12; CHECK-NEXT: [[T0:%.*]] = add i8 [[X:%.*]], 42 13; CHECK-NEXT: ret i8 [[T0]] 14; 15 %t0 = sub i8 %x, -42 16 ret i8 %t0 17} 18 19; Negation can be negated for free 20define i8 @t1(i8 %x, i8 %y) { 21; CHECK-LABEL: @t1( 22; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[Y:%.*]] 23; CHECK-NEXT: call void @use8(i8 [[T0]]) 24; CHECK-NEXT: [[T1:%.*]] = add i8 [[X:%.*]], [[Y]] 25; CHECK-NEXT: ret i8 [[T1]] 26; 27 %t0 = sub i8 0, %y 28 call void @use8(i8 %t0) 29 %t1 = sub i8 %x, %t0 30 ret i8 %t1 31} 32 33; Shift-left can be negated if all uses can be updated 34define i8 @t2(i8 %x, i8 %y) { 35; CHECK-LABEL: @t2( 36; CHECK-NEXT: [[T0_NEG:%.*]] = shl i8 42, [[Y:%.*]] 37; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]] 38; CHECK-NEXT: ret i8 [[T1]] 39; 40 %t0 = shl i8 -42, %y 41 %t1 = sub i8 %x, %t0 42 ret i8 %t1 43} 44define i8 @n2(i8 %x, i8 %y) { 45; CHECK-LABEL: @n2( 46; CHECK-NEXT: [[T0:%.*]] = shl i8 -42, [[Y:%.*]] 47; CHECK-NEXT: call void @use8(i8 [[T0]]) 48; CHECK-NEXT: [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] 49; CHECK-NEXT: ret i8 [[T1]] 50; 51 %t0 = shl i8 -42, %y 52 call void @use8(i8 %t0) 53 %t1 = sub i8 %x, %t0 54 ret i8 %t1 55} 56define i8 @t3(i8 %x, i8 %y, i8 %z) { 57; CHECK-LABEL: @t3( 58; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[Z:%.*]] 59; CHECK-NEXT: call void @use8(i8 [[T0]]) 60; CHECK-NEXT: [[T1_NEG:%.*]] = shl i8 [[Z]], [[Y:%.*]] 61; CHECK-NEXT: [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]] 62; CHECK-NEXT: ret i8 [[T2]] 63; 64 %t0 = sub i8 0, %z 65 call void @use8(i8 %t0) 66 %t1 = shl i8 %t0, %y 67 %t2 = sub i8 %x, %t1 68 ret i8 %t2 69} 70define i8 @n3(i8 %x, i8 %y, i8 %z) { 71; CHECK-LABEL: @n3( 72; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[Z:%.*]] 73; CHECK-NEXT: call void @use8(i8 [[T0]]) 74; CHECK-NEXT: [[T1:%.*]] = shl i8 [[T0]], [[Y:%.*]] 75; CHECK-NEXT: call void @use8(i8 [[T1]]) 76; CHECK-NEXT: [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]] 77; CHECK-NEXT: ret i8 [[T2]] 78; 79 %t0 = sub i8 0, %z 80 call void @use8(i8 %t0) 81 %t1 = shl i8 %t0, %y 82 call void @use8(i8 %t1) 83 %t2 = sub i8 %x, %t1 84 ret i8 %t2 85} 86 87; Select can be negated if all it's operands can be negated and all the users of select can be updated 88define i8 @t4(i8 %x, i1 %y) { 89; CHECK-LABEL: @t4( 90; CHECK-NEXT: [[T0_NEG:%.*]] = select i1 [[Y:%.*]], i8 42, i8 -44 91; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]] 92; CHECK-NEXT: ret i8 [[T1]] 93; 94 %t0 = select i1 %y, i8 -42, i8 44 95 %t1 = sub i8 %x, %t0 96 ret i8 %t1 97} 98 99define i8 @select_of_constants_multi_use(i1 %b) { 100; CHECK-LABEL: @select_of_constants_multi_use( 101; CHECK-NEXT: [[S_NEG:%.*]] = select i1 [[B:%.*]], i8 -42, i8 2 102; CHECK-NEXT: [[S:%.*]] = select i1 [[B]], i8 42, i8 -2 103; CHECK-NEXT: call void @use8(i8 [[S]]) 104; CHECK-NEXT: ret i8 [[S_NEG]] 105; 106 %s = select i1 %b, i8 42, i8 -2 107 call void @use8(i8 %s) 108 %n = sub i8 0, %s 109 ret i8 %n 110} 111 112define i32 @PR52261(i1 %b) { 113; CHECK-LABEL: @PR52261( 114; CHECK-NEXT: ret i32 2 115; 116 %s = select i1 %b, i32 2, i32 -2 117 %n = sub nsw i32 0, %s 118 %a = and i32 %s, %n 119 ret i32 %a 120} 121 122define i8 @n4(i8 %x, i1 %y) { 123; CHECK-LABEL: @n4( 124; CHECK-NEXT: [[T0:%.*]] = select i1 [[Y:%.*]], i8 -42, i8 44 125; CHECK-NEXT: call void @use8(i8 [[T0]]) 126; CHECK-NEXT: [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] 127; CHECK-NEXT: ret i8 [[T1]] 128; 129 %t0 = select i1 %y, i8 -42, i8 44 130 call void @use8(i8 %t0) 131 %t1 = sub i8 %x, %t0 132 ret i8 %t1 133} 134define i8 @n5(i8 %x, i1 %y, i8 %z) { 135; CHECK-LABEL: @n5( 136; CHECK-NEXT: [[T0:%.*]] = select i1 [[Y:%.*]], i8 -42, i8 [[Z:%.*]] 137; CHECK-NEXT: [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] 138; CHECK-NEXT: ret i8 [[T1]] 139; 140 %t0 = select i1 %y, i8 -42, i8 %z 141 %t1 = sub i8 %x, %t0 142 ret i8 %t1 143} 144define i8 @t6(i8 %x, i1 %y, i8 %z) { 145; CHECK-LABEL: @t6( 146; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[Z:%.*]] 147; CHECK-NEXT: call void @use8(i8 [[T0]]) 148; CHECK-NEXT: [[T1_NEG:%.*]] = select i1 [[Y:%.*]], i8 42, i8 [[Z]] 149; CHECK-NEXT: [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]] 150; CHECK-NEXT: ret i8 [[T2]] 151; 152 %t0 = sub i8 0, %z 153 call void @use8(i8 %t0) 154 %t1 = select i1 %y, i8 -42, i8 %t0 155 %t2 = sub i8 %x, %t1 156 ret i8 %t2 157} 158define i8 @t7(i8 %x, i1 %y, i8 %z) { 159; CHECK-LABEL: @t7( 160; CHECK-NEXT: [[T0_NEG:%.*]] = shl nsw i8 -1, [[Z:%.*]] 161; CHECK-NEXT: [[T1_NEG:%.*]] = select i1 [[Y:%.*]], i8 0, i8 [[T0_NEG]] 162; CHECK-NEXT: [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]] 163; CHECK-NEXT: ret i8 [[T2]] 164; 165 %t0 = shl i8 1, %z 166 %t1 = select i1 %y, i8 0, i8 %t0 167 %t2 = sub i8 %x, %t1 168 ret i8 %t2 169} 170define i8 @n8(i8 %x, i1 %y, i8 %z) { 171; CHECK-LABEL: @n8( 172; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Z:%.*]] 173; CHECK-NEXT: call void @use8(i8 [[T0]]) 174; CHECK-NEXT: [[T1:%.*]] = select i1 [[Y:%.*]], i8 0, i8 [[T0]] 175; CHECK-NEXT: [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]] 176; CHECK-NEXT: ret i8 [[T2]] 177; 178 %t0 = shl i8 1, %z 179 call void @use8(i8 %t0) 180 %t1 = select i1 %y, i8 0, i8 %t0 181 %t2 = sub i8 %x, %t1 182 ret i8 %t2 183} 184 185; Subtraction can be negated by swapping its operands. 186; x - (y - z) -> x - y + z -> x + (z - y) 187define i8 @t9(i8 %x, i8 %y) { 188; CHECK-LABEL: @t9( 189; CHECK-NEXT: [[T0_NEG:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] 190; CHECK-NEXT: ret i8 [[T0_NEG]] 191; 192 %t0 = sub i8 %y, %x 193 %t1 = sub i8 0, %t0 194 ret i8 %t1 195} 196 197define i8 @n10(i8 %x, i8 %y, i8 %z) { 198; CHECK-LABEL: @n10( 199; CHECK-NEXT: [[T0:%.*]] = sub i8 [[Y:%.*]], [[X:%.*]] 200; CHECK-NEXT: call void @use8(i8 [[T0]]) 201; CHECK-NEXT: [[T1:%.*]] = sub i8 0, [[T0]] 202; CHECK-NEXT: ret i8 [[T1]] 203; 204 %t0 = sub i8 %y, %x 205 call void @use8(i8 %t0) 206 %t1 = sub i8 0, %t0 207 ret i8 %t1 208} 209 210define i8 @neg_of_sub_from_constant(i8 %x) { 211; CHECK-LABEL: @neg_of_sub_from_constant( 212; CHECK-NEXT: [[S_NEG:%.*]] = add i8 [[X:%.*]], -42 213; CHECK-NEXT: ret i8 [[S_NEG]] 214; 215 %s = sub i8 42, %x 216 %r = sub i8 0, %s 217 ret i8 %r 218} 219 220define i8 @neg_of_sub_from_constant_multi_use(i8 %x) { 221; CHECK-LABEL: @neg_of_sub_from_constant_multi_use( 222; CHECK-NEXT: [[S_NEG:%.*]] = add i8 [[X:%.*]], -42 223; CHECK-NEXT: [[S:%.*]] = sub i8 42, [[X]] 224; CHECK-NEXT: call void @use8(i8 [[S]]) 225; CHECK-NEXT: ret i8 [[S_NEG]] 226; 227 %s = sub i8 42, %x 228 call void @use8(i8 %s) 229 %r = sub i8 0, %s 230 ret i8 %r 231} 232 233define i8 @sub_from_constant_of_sub_from_constant(i8 %x) { 234; CHECK-LABEL: @sub_from_constant_of_sub_from_constant( 235; CHECK-NEXT: [[R:%.*]] = add i8 [[X:%.*]], -31 236; CHECK-NEXT: ret i8 [[R]] 237; 238 %s = sub i8 42, %x 239 %r = sub i8 11, %s 240 ret i8 %r 241} 242 243define i8 @sub_from_constant_of_sub_from_constant_multi_use(i8 %x) { 244; CHECK-LABEL: @sub_from_constant_of_sub_from_constant_multi_use( 245; CHECK-NEXT: [[S:%.*]] = sub i8 42, [[X:%.*]] 246; CHECK-NEXT: call void @use8(i8 [[S]]) 247; CHECK-NEXT: [[R:%.*]] = add i8 [[X]], -31 248; CHECK-NEXT: ret i8 [[R]] 249; 250 %s = sub i8 42, %x 251 call void @use8(i8 %s) 252 %r = sub i8 11, %s 253 ret i8 %r 254} 255 256define i8 @sub_from_variable_of_sub_from_constant(i8 %x, i8 %y) { 257; CHECK-LABEL: @sub_from_variable_of_sub_from_constant( 258; CHECK-NEXT: [[S_NEG:%.*]] = add i8 [[X:%.*]], -42 259; CHECK-NEXT: [[R:%.*]] = add i8 [[S_NEG]], [[Y:%.*]] 260; CHECK-NEXT: ret i8 [[R]] 261; 262 %s = sub i8 42, %x 263 %r = sub i8 %y, %s 264 ret i8 %r 265} 266 267define i8 @sub_from_variable_of_sub_from_constant_multi_use(i8 %x, i8 %y) { 268; CHECK-LABEL: @sub_from_variable_of_sub_from_constant_multi_use( 269; CHECK-NEXT: [[S:%.*]] = sub i8 42, [[X:%.*]] 270; CHECK-NEXT: call void @use8(i8 [[S]]) 271; CHECK-NEXT: [[R:%.*]] = sub i8 [[Y:%.*]], [[S]] 272; CHECK-NEXT: ret i8 [[R]] 273; 274 %s = sub i8 42, %x 275 call void @use8(i8 %s) 276 %r = sub i8 %y, %s 277 ret i8 %r 278} 279 280; Addition can be negated if both operands can be negated 281; x - (y + z) -> x - y - z -> x + ((-y) + (-z))) 282define i8 @t12(i8 %x, i8 %y, i8 %z) { 283; CHECK-LABEL: @t12( 284; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[Y:%.*]] 285; CHECK-NEXT: call void @use8(i8 [[T0]]) 286; CHECK-NEXT: [[T1:%.*]] = sub i8 0, [[Z:%.*]] 287; CHECK-NEXT: call void @use8(i8 [[T1]]) 288; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y]], [[Z]] 289; CHECK-NEXT: [[T3:%.*]] = add i8 [[X:%.*]], [[TMP1]] 290; CHECK-NEXT: ret i8 [[T3]] 291; 292 %t0 = sub i8 0, %y 293 call void @use8(i8 %t0) 294 %t1 = sub i8 0, %z 295 call void @use8(i8 %t1) 296 %t2 = add i8 %t0, %t1 297 %t3 = sub i8 %x, %t2 298 ret i8 %t3 299} 300define i8 @n13(i8 %x, i8 %y, i8 %z) { 301; CHECK-LABEL: @n13( 302; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[Y:%.*]] 303; CHECK-NEXT: call void @use8(i8 [[T0]]) 304; CHECK-NEXT: [[T1_NEG:%.*]] = sub i8 [[Y]], [[Z:%.*]] 305; CHECK-NEXT: [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]] 306; CHECK-NEXT: ret i8 [[T2]] 307; 308 %t0 = sub i8 0, %y 309 call void @use8(i8 %t0) 310 %t1 = add i8 %t0, %z 311 %t2 = sub i8 %x, %t1 312 ret i8 %t2 313} 314define i8 @n14(i8 %x, i8 %y, i8 %z) { 315; CHECK-LABEL: @n14( 316; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[Y:%.*]] 317; CHECK-NEXT: call void @use8(i8 [[T0]]) 318; CHECK-NEXT: [[T1:%.*]] = sub i8 0, [[Z:%.*]] 319; CHECK-NEXT: call void @use8(i8 [[T1]]) 320; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y]], [[Z]] 321; CHECK-NEXT: [[T2:%.*]] = sub i8 0, [[TMP1]] 322; CHECK-NEXT: call void @use8(i8 [[T2]]) 323; CHECK-NEXT: [[T3:%.*]] = add i8 [[X:%.*]], [[TMP1]] 324; CHECK-NEXT: ret i8 [[T3]] 325; 326 %t0 = sub i8 0, %y 327 call void @use8(i8 %t0) 328 %t1 = sub i8 0, %z 329 call void @use8(i8 %t1) 330 %t2 = add i8 %t0, %t1 331 call void @use8(i8 %t2) 332 %t3 = sub i8 %x, %t2 333 ret i8 %t3 334} 335 336define i8 @neg_of_add_with_constant(i8 %x) { 337; CHECK-LABEL: @neg_of_add_with_constant( 338; CHECK-NEXT: [[R:%.*]] = sub i8 -42, [[X:%.*]] 339; CHECK-NEXT: ret i8 [[R]] 340; 341 %s = add i8 %x, 42 342 %r = sub i8 0, %s 343 ret i8 %r 344} 345 346define i8 @neg_of_add_with_constant_multi_use(i8 %x) { 347; CHECK-LABEL: @neg_of_add_with_constant_multi_use( 348; CHECK-NEXT: [[S:%.*]] = add i8 [[X:%.*]], 42 349; CHECK-NEXT: call void @use8(i8 [[S]]) 350; CHECK-NEXT: [[R:%.*]] = sub i8 -42, [[X]] 351; CHECK-NEXT: ret i8 [[R]] 352; 353 %s = add i8 %x, 42 354 call void @use8(i8 %s) 355 %r = sub i8 0, %s 356 ret i8 %r 357} 358 359define i8 @sub_from_constant_of_add_with_constant(i8 %x) { 360; CHECK-LABEL: @sub_from_constant_of_add_with_constant( 361; CHECK-NEXT: [[R:%.*]] = sub i8 -31, [[X:%.*]] 362; CHECK-NEXT: ret i8 [[R]] 363; 364 %s = add i8 %x, 42 365 %r = sub i8 11, %s 366 ret i8 %r 367} 368 369define i8 @sub_from_constant_of_add_with_constant_multi_use(i8 %x) { 370; CHECK-LABEL: @sub_from_constant_of_add_with_constant_multi_use( 371; CHECK-NEXT: [[S:%.*]] = add i8 [[X:%.*]], 42 372; CHECK-NEXT: call void @use8(i8 [[S]]) 373; CHECK-NEXT: [[R:%.*]] = sub i8 -31, [[X]] 374; CHECK-NEXT: ret i8 [[R]] 375; 376 %s = add i8 %x, 42 377 call void @use8(i8 %s) 378 %r = sub i8 11, %s 379 ret i8 %r 380} 381 382define i8 @sub_from_variable_of_add_with_constant(i8 %x, i8 %y) { 383; CHECK-LABEL: @sub_from_variable_of_add_with_constant( 384; CHECK-NEXT: [[S:%.*]] = add i8 [[X:%.*]], 42 385; CHECK-NEXT: [[R:%.*]] = sub i8 [[Y:%.*]], [[S]] 386; CHECK-NEXT: ret i8 [[R]] 387; 388 %s = add i8 %x, 42 389 %r = sub i8 %y, %s 390 ret i8 %r 391} 392 393define i8 @sub_from_variable_of_add_with_constant_multi_use(i8 %x, i8 %y) { 394; CHECK-LABEL: @sub_from_variable_of_add_with_constant_multi_use( 395; CHECK-NEXT: [[S:%.*]] = add i8 [[X:%.*]], 42 396; CHECK-NEXT: call void @use8(i8 [[S]]) 397; CHECK-NEXT: [[R:%.*]] = sub i8 [[Y:%.*]], [[S]] 398; CHECK-NEXT: ret i8 [[R]] 399; 400 %s = add i8 %x, 42 401 call void @use8(i8 %s) 402 %r = sub i8 %y, %s 403 ret i8 %r 404} 405 406; Multiplication can be negated if either one of operands can be negated 407; x - (y * z) -> x + ((-y) * z) or x + ((-z) * y) 408define i8 @t15(i8 %x, i8 %y, i8 %z) { 409; CHECK-LABEL: @t15( 410; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[Y:%.*]] 411; CHECK-NEXT: call void @use8(i8 [[T0]]) 412; CHECK-NEXT: [[T1_NEG:%.*]] = mul i8 [[Y]], [[Z:%.*]] 413; CHECK-NEXT: [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]] 414; CHECK-NEXT: ret i8 [[T2]] 415; 416 %t0 = sub i8 0, %y 417 call void @use8(i8 %t0) 418 %t1 = mul i8 %t0, %z 419 %t2 = sub i8 %x, %t1 420 ret i8 %t2 421} 422define i8 @n16(i8 %x, i8 %y, i8 %z) { 423; CHECK-LABEL: @n16( 424; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[Y:%.*]] 425; CHECK-NEXT: call void @use8(i8 [[T0]]) 426; CHECK-NEXT: [[T1:%.*]] = mul i8 [[Z:%.*]], [[T0]] 427; CHECK-NEXT: call void @use8(i8 [[T1]]) 428; CHECK-NEXT: [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]] 429; CHECK-NEXT: ret i8 [[T2]] 430; 431 %t0 = sub i8 0, %y 432 call void @use8(i8 %t0) 433 %t1 = mul i8 %t0, %z 434 call void @use8(i8 %t1) 435 %t2 = sub i8 %x, %t1 436 ret i8 %t2 437} 438 439; Phi can be negated if all incoming values can be negated 440define i8 @t16(i1 %c, i8 %x) { 441; CHECK-LABEL: @t16( 442; CHECK-NEXT: begin: 443; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 444; CHECK: then: 445; CHECK-NEXT: br label [[END:%.*]] 446; CHECK: else: 447; CHECK-NEXT: br label [[END]] 448; CHECK: end: 449; CHECK-NEXT: [[Z_NEG:%.*]] = phi i8 [ [[X:%.*]], [[THEN]] ], [ 42, [[ELSE]] ] 450; CHECK-NEXT: ret i8 [[Z_NEG]] 451; 452begin: 453 br i1 %c, label %then, label %else 454then: 455 %y = sub i8 0, %x 456 br label %end 457else: 458 br label %end 459end: 460 %z = phi i8 [ %y, %then], [ -42, %else ] 461 %n = sub i8 0, %z 462 ret i8 %n 463} 464define i8 @n17(i1 %c, i8 %x) { 465; CHECK-LABEL: @n17( 466; CHECK-NEXT: begin: 467; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 468; CHECK: then: 469; CHECK-NEXT: [[Y:%.*]] = sub i8 0, [[X:%.*]] 470; CHECK-NEXT: br label [[END:%.*]] 471; CHECK: else: 472; CHECK-NEXT: br label [[END]] 473; CHECK: end: 474; CHECK-NEXT: [[Z:%.*]] = phi i8 [ [[Y]], [[THEN]] ], [ -42, [[ELSE]] ] 475; CHECK-NEXT: call void @use8(i8 [[Z]]) 476; CHECK-NEXT: [[N:%.*]] = sub i8 0, [[Z]] 477; CHECK-NEXT: ret i8 [[N]] 478; 479begin: 480 br i1 %c, label %then, label %else 481then: 482 %y = sub i8 0, %x 483 br label %end 484else: 485 br label %end 486end: 487 %z = phi i8 [ %y, %then], [ -42, %else ] 488 call void @use8(i8 %z) 489 %n = sub i8 0, %z 490 ret i8 %n 491} 492define i8 @n19(i1 %c, i8 %x, i8 %y) { 493; CHECK-LABEL: @n19( 494; CHECK-NEXT: begin: 495; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 496; CHECK: then: 497; CHECK-NEXT: [[Z:%.*]] = sub i8 0, [[X:%.*]] 498; CHECK-NEXT: br label [[END:%.*]] 499; CHECK: else: 500; CHECK-NEXT: br label [[END]] 501; CHECK: end: 502; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[Z]], [[THEN]] ], [ [[Y:%.*]], [[ELSE]] ] 503; CHECK-NEXT: [[N:%.*]] = sub i8 0, [[R]] 504; CHECK-NEXT: ret i8 [[N]] 505; 506begin: 507 br i1 %c, label %then, label %else 508then: 509 %z = sub i8 0, %x 510 br label %end 511else: 512 br label %end 513end: 514 %r = phi i8 [ %z, %then], [ %y, %else ] 515 %n = sub i8 0, %r 516 ret i8 %n 517} 518define void @phi_with_duplicate_incoming_basic_blocks(i32 %x, i32 %y, i1 %should_lookup, i32 %z) { 519; CHECK-LABEL: @phi_with_duplicate_incoming_basic_blocks( 520; CHECK-NEXT: entry: 521; CHECK-NEXT: [[X_INC_NEG:%.*]] = xor i32 [[X:%.*]], -1 522; CHECK-NEXT: br i1 [[SHOULD_LOOKUP:%.*]], label [[LOOKUP:%.*]], label [[LOOP:%.*]] 523; CHECK: lookup: 524; CHECK-NEXT: [[TO_LOOKUP:%.*]] = phi i32 [ [[Y:%.*]], [[ENTRY:%.*]] ], [ [[METAVAL_NEG:%.*]], [[LOOP]] ] 525; CHECK-NEXT: switch i32 [[TO_LOOKUP]], label [[END:%.*]] [ 526; CHECK-NEXT: i32 0, label [[LOOP]] 527; CHECK-NEXT: i32 42, label [[LOOP]] 528; CHECK-NEXT: ] 529; CHECK: loop: 530; CHECK-NEXT: [[METAVAL_NEG]] = phi i32 [ [[X_INC_NEG]], [[LOOKUP]] ], [ [[X_INC_NEG]], [[LOOKUP]] ], [ -84, [[ENTRY]] ] 531; CHECK-NEXT: [[REPEAT:%.*]] = call i1 @use32gen1(i32 [[METAVAL_NEG]]) 532; CHECK-NEXT: br i1 [[REPEAT]], label [[LOOKUP]], label [[END]] 533; CHECK: end: 534; CHECK-NEXT: ret void 535; 536entry: 537 %x_inc = add i32 %x, 1 538 br i1 %should_lookup, label %lookup, label %loop 539 540lookup: 541 %to_lookup = phi i32 [ %y, %entry ], [ %negated_metaval, %loop ] 542 switch i32 %to_lookup, label %end [ 543 i32 0, label %loop 544 i32 42, label %loop 545 ] 546 547loop: 548 %metaval = phi i32 [ %x_inc, %lookup ], [ %x_inc, %lookup ], [ 84, %entry ] 549 %negated_metaval = sub i32 0, %metaval 550 %repeat = call i1 @use32gen1(i32 %negated_metaval) 551 br i1 %repeat, label %lookup, label %end 552 553end: 554 ret void 555} 556 557; truncation can be negated if it's operand can be negated 558define i8 @t20(i8 %x, i16 %y) { 559; CHECK-LABEL: @t20( 560; CHECK-NEXT: [[T0_NEG:%.*]] = shl i16 42, [[Y:%.*]] 561; CHECK-NEXT: [[T1_NEG:%.*]] = trunc i16 [[T0_NEG]] to i8 562; CHECK-NEXT: [[T2:%.*]] = add i8 [[X:%.*]], [[T1_NEG]] 563; CHECK-NEXT: ret i8 [[T2]] 564; 565 %t0 = shl i16 -42, %y 566 %t1 = trunc i16 %t0 to i8 567 %t2 = sub i8 %x, %t1 568 ret i8 %t2 569} 570define i8 @n21(i8 %x, i16 %y) { 571; CHECK-LABEL: @n21( 572; CHECK-NEXT: [[T0:%.*]] = shl i16 -42, [[Y:%.*]] 573; CHECK-NEXT: [[T1:%.*]] = trunc i16 [[T0]] to i8 574; CHECK-NEXT: call void @use8(i8 [[T1]]) 575; CHECK-NEXT: [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]] 576; CHECK-NEXT: ret i8 [[T2]] 577; 578 %t0 = shl i16 -42, %y 579 %t1 = trunc i16 %t0 to i8 580 call void @use8(i8 %t1) 581 %t2 = sub i8 %x, %t1 582 ret i8 %t2 583} 584 585define i4 @negate_xor(i4 %x) { 586; CHECK-LABEL: @negate_xor( 587; CHECK-NEXT: [[TMP1:%.*]] = xor i4 [[X:%.*]], -6 588; CHECK-NEXT: [[O_NEG:%.*]] = add i4 [[TMP1]], 1 589; CHECK-NEXT: ret i4 [[O_NEG]] 590; 591 %o = xor i4 %x, 5 592 %r = sub i4 0, %o 593 ret i4 %r 594} 595 596define <2 x i4> @negate_xor_vec(<2 x i4> %x) { 597; CHECK-LABEL: @negate_xor_vec( 598; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i4> [[X:%.*]], <i4 -6, i4 5> 599; CHECK-NEXT: [[O_NEG:%.*]] = add <2 x i4> [[TMP1]], splat (i4 1) 600; CHECK-NEXT: ret <2 x i4> [[O_NEG]] 601; 602 %o = xor <2 x i4> %x, <i4 5, i4 10> 603 %r = sub <2 x i4> zeroinitializer, %o 604 ret <2 x i4> %r 605} 606 607define i8 @negate_xor_use(i8 %x) { 608; CHECK-LABEL: @negate_xor_use( 609; CHECK-NEXT: [[O:%.*]] = xor i8 [[X:%.*]], 5 610; CHECK-NEXT: call void @use8(i8 [[O]]) 611; CHECK-NEXT: [[R:%.*]] = sub i8 0, [[O]] 612; CHECK-NEXT: ret i8 [[R]] 613; 614 %o = xor i8 %x, 5 615 call void @use8(i8 %o) 616 %r = sub i8 0, %o 617 ret i8 %r 618} 619 620define i4 @negate_shl_xor(i4 %x, i4 %y) { 621; CHECK-LABEL: @negate_shl_xor( 622; CHECK-NEXT: [[TMP1:%.*]] = xor i4 [[X:%.*]], -6 623; CHECK-NEXT: [[O_NEG:%.*]] = add i4 [[TMP1]], 1 624; CHECK-NEXT: [[S_NEG:%.*]] = shl i4 [[O_NEG]], [[Y:%.*]] 625; CHECK-NEXT: ret i4 [[S_NEG]] 626; 627 %o = xor i4 %x, 5 628 %s = shl i4 %o, %y 629 %r = sub i4 0, %s 630 ret i4 %r 631} 632 633define i8 @negate_shl_not_uses(i8 %x, i8 %y) { 634; CHECK-LABEL: @negate_shl_not_uses( 635; CHECK-NEXT: [[O_NEG:%.*]] = add i8 [[X:%.*]], 1 636; CHECK-NEXT: [[O:%.*]] = xor i8 [[X]], -1 637; CHECK-NEXT: call void @use8(i8 [[O]]) 638; CHECK-NEXT: [[S_NEG:%.*]] = shl i8 [[O_NEG]], [[Y:%.*]] 639; CHECK-NEXT: ret i8 [[S_NEG]] 640; 641 %o = xor i8 %x, -1 642 call void @use8(i8 %o) 643 %s = shl i8 %o, %y 644 %r = sub i8 0, %s 645 ret i8 %r 646} 647 648define <2 x i4> @negate_mul_not_uses_vec(<2 x i4> %x, <2 x i4> %y) { 649; CHECK-LABEL: @negate_mul_not_uses_vec( 650; CHECK-NEXT: [[O_NEG:%.*]] = add <2 x i4> [[X:%.*]], splat (i4 1) 651; CHECK-NEXT: [[O:%.*]] = xor <2 x i4> [[X]], splat (i4 -1) 652; CHECK-NEXT: call void @use_v2i4(<2 x i4> [[O]]) 653; CHECK-NEXT: [[S_NEG:%.*]] = mul <2 x i4> [[O_NEG]], [[Y:%.*]] 654; CHECK-NEXT: ret <2 x i4> [[S_NEG]] 655; 656 %o = xor <2 x i4> %x, <i4 -1, i4 -1> 657 call void @use_v2i4(<2 x i4> %o) 658 %s = mul <2 x i4> %o, %y 659 %r = sub <2 x i4> zeroinitializer, %s 660 ret <2 x i4> %r 661} 662 663; signed division can be negated if divisor can be negated and is not 1/-1 664define i8 @negate_sdiv(i8 %x, i8 %y) { 665; CHECK-LABEL: @negate_sdiv( 666; CHECK-NEXT: [[T0_NEG:%.*]] = sdiv i8 [[Y:%.*]], -42 667; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]] 668; CHECK-NEXT: ret i8 [[T1]] 669; 670 %t0 = sdiv i8 %y, 42 671 %t1 = sub i8 %x, %t0 672 ret i8 %t1 673} 674define i8 @negate_sdiv_extrause(i8 %x, i8 %y) { 675; CHECK-LABEL: @negate_sdiv_extrause( 676; CHECK-NEXT: [[T0:%.*]] = sdiv i8 [[Y:%.*]], 42 677; CHECK-NEXT: call void @use8(i8 [[T0]]) 678; CHECK-NEXT: [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] 679; CHECK-NEXT: ret i8 [[T1]] 680; 681 %t0 = sdiv i8 %y, 42 682 call void @use8(i8 %t0) 683 %t1 = sub i8 %x, %t0 684 ret i8 %t1 685} 686define i8 @negate_sdiv_extrause2(i8 %x, i8 %y) { 687; CHECK-LABEL: @negate_sdiv_extrause2( 688; CHECK-NEXT: [[T0:%.*]] = sdiv i8 [[Y:%.*]], 42 689; CHECK-NEXT: call void @use8(i8 [[T0]]) 690; CHECK-NEXT: [[T1:%.*]] = sub nsw i8 0, [[T0]] 691; CHECK-NEXT: ret i8 [[T1]] 692; 693 %t0 = sdiv i8 %y, 42 694 call void @use8(i8 %t0) 695 %t1 = sub i8 0, %t0 696 ret i8 %t1 697} 698 699; Right-shift sign bit smear is negatible. 700define i8 @negate_ashr(i8 %x, i8 %y) { 701; CHECK-LABEL: @negate_ashr( 702; CHECK-NEXT: [[T0_NEG:%.*]] = lshr i8 [[Y:%.*]], 7 703; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]] 704; CHECK-NEXT: ret i8 [[T1]] 705; 706 %t0 = ashr i8 %y, 7 707 %t1 = sub i8 %x, %t0 708 ret i8 %t1 709} 710define i8 @negate_lshr(i8 %x, i8 %y) { 711; CHECK-LABEL: @negate_lshr( 712; CHECK-NEXT: [[T0_NEG:%.*]] = ashr i8 [[Y:%.*]], 7 713; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]] 714; CHECK-NEXT: ret i8 [[T1]] 715; 716 %t0 = lshr i8 %y, 7 717 %t1 = sub i8 %x, %t0 718 ret i8 %t1 719} 720define i8 @negate_ashr_extrause(i8 %x, i8 %y) { 721; CHECK-LABEL: @negate_ashr_extrause( 722; CHECK-NEXT: [[T0:%.*]] = ashr i8 [[Y:%.*]], 7 723; CHECK-NEXT: call void @use8(i8 [[T0]]) 724; CHECK-NEXT: [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] 725; CHECK-NEXT: ret i8 [[T1]] 726; 727 %t0 = ashr i8 %y, 7 728 call void @use8(i8 %t0) 729 %t1 = sub i8 %x, %t0 730 ret i8 %t1 731} 732define i8 @negate_lshr_extrause(i8 %x, i8 %y) { 733; CHECK-LABEL: @negate_lshr_extrause( 734; CHECK-NEXT: [[T0:%.*]] = lshr i8 [[Y:%.*]], 7 735; CHECK-NEXT: call void @use8(i8 [[T0]]) 736; CHECK-NEXT: [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] 737; CHECK-NEXT: ret i8 [[T1]] 738; 739 %t0 = lshr i8 %y, 7 740 call void @use8(i8 %t0) 741 %t1 = sub i8 %x, %t0 742 ret i8 %t1 743} 744define i8 @negate_ashr_wrongshift(i8 %x, i8 %y) { 745; CHECK-LABEL: @negate_ashr_wrongshift( 746; CHECK-NEXT: [[T0:%.*]] = ashr i8 [[Y:%.*]], 6 747; CHECK-NEXT: [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] 748; CHECK-NEXT: ret i8 [[T1]] 749; 750 %t0 = ashr i8 %y, 6 751 %t1 = sub i8 %x, %t0 752 ret i8 %t1 753} 754define i8 @negate_lshr_wrongshift(i8 %x, i8 %y) { 755; CHECK-LABEL: @negate_lshr_wrongshift( 756; CHECK-NEXT: [[T0:%.*]] = lshr i8 [[Y:%.*]], 6 757; CHECK-NEXT: [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] 758; CHECK-NEXT: ret i8 [[T1]] 759; 760 %t0 = lshr i8 %y, 6 761 %t1 = sub i8 %x, %t0 762 ret i8 %t1 763} 764 765; *ext of i1 is always negatible 766define i8 @negate_sext(i8 %x, i1 %y) { 767; CHECK-LABEL: @negate_sext( 768; CHECK-NEXT: [[T0_NEG:%.*]] = zext i1 [[Y:%.*]] to i8 769; CHECK-NEXT: [[T1:%.*]] = add i8 [[X:%.*]], [[T0_NEG]] 770; CHECK-NEXT: ret i8 [[T1]] 771; 772 %t0 = sext i1 %y to i8 773 %t1 = sub i8 %x, %t0 774 ret i8 %t1 775} 776define i8 @negate_zext(i8 %x, i1 %y) { 777; CHECK-LABEL: @negate_zext( 778; CHECK-NEXT: [[T0_NEG:%.*]] = sext i1 [[Y:%.*]] to i8 779; CHECK-NEXT: [[T1:%.*]] = add i8 [[X:%.*]], [[T0_NEG]] 780; CHECK-NEXT: ret i8 [[T1]] 781; 782 %t0 = zext i1 %y to i8 783 %t1 = sub i8 %x, %t0 784 ret i8 %t1 785} 786define i8 @negate_sext_extrause(i8 %x, i1 %y) { 787; CHECK-LABEL: @negate_sext_extrause( 788; CHECK-NEXT: [[T0:%.*]] = sext i1 [[Y:%.*]] to i8 789; CHECK-NEXT: call void @use8(i8 [[T0]]) 790; CHECK-NEXT: [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] 791; CHECK-NEXT: ret i8 [[T1]] 792; 793 %t0 = sext i1 %y to i8 794 call void @use8(i8 %t0) 795 %t1 = sub i8 %x, %t0 796 ret i8 %t1 797} 798define i8 @negate_zext_extrause(i8 %x, i1 %y) { 799; CHECK-LABEL: @negate_zext_extrause( 800; CHECK-NEXT: [[T0:%.*]] = zext i1 [[Y:%.*]] to i8 801; CHECK-NEXT: call void @use8(i8 [[T0]]) 802; CHECK-NEXT: [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] 803; CHECK-NEXT: ret i8 [[T1]] 804; 805 %t0 = zext i1 %y to i8 806 call void @use8(i8 %t0) 807 %t1 = sub i8 %x, %t0 808 ret i8 %t1 809} 810define i8 @negate_sext_wrongwidth(i8 %x, i2 %y) { 811; CHECK-LABEL: @negate_sext_wrongwidth( 812; CHECK-NEXT: [[T0:%.*]] = sext i2 [[Y:%.*]] to i8 813; CHECK-NEXT: [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] 814; CHECK-NEXT: ret i8 [[T1]] 815; 816 %t0 = sext i2 %y to i8 817 %t1 = sub i8 %x, %t0 818 ret i8 %t1 819} 820define i8 @negate_zext_wrongwidth(i8 %x, i2 %y) { 821; CHECK-LABEL: @negate_zext_wrongwidth( 822; CHECK-NEXT: [[T0:%.*]] = zext i2 [[Y:%.*]] to i8 823; CHECK-NEXT: [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] 824; CHECK-NEXT: ret i8 [[T1]] 825; 826 %t0 = zext i2 %y to i8 827 %t1 = sub i8 %x, %t0 828 ret i8 %t1 829} 830 831define <2 x i4> @negate_shufflevector_oneinput_reverse(<2 x i4> %x, <2 x i4> %y) { 832; CHECK-LABEL: @negate_shufflevector_oneinput_reverse( 833; CHECK-NEXT: [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X:%.*]] 834; CHECK-NEXT: [[T1_NEG:%.*]] = shufflevector <2 x i4> [[T0_NEG]], <2 x i4> poison, <2 x i32> <i32 1, i32 0> 835; CHECK-NEXT: [[T2:%.*]] = add <2 x i4> [[T1_NEG]], [[Y:%.*]] 836; CHECK-NEXT: ret <2 x i4> [[T2]] 837; 838 %t0 = shl <2 x i4> <i4 -6, i4 5>, %x 839 %t1 = shufflevector <2 x i4> %t0, <2 x i4> undef, <2 x i32> <i32 1, i32 0> 840 %t2 = sub <2 x i4> %y, %t1 841 ret <2 x i4> %t2 842} 843define <2 x i4> @negate_shufflevector_oneinput_second_lane_is_undef(<2 x i4> %x, <2 x i4> %y) { 844; CHECK-LABEL: @negate_shufflevector_oneinput_second_lane_is_undef( 845; CHECK-NEXT: [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X:%.*]] 846; CHECK-NEXT: [[T11_NEG:%.*]] = insertelement <2 x i4> [[T0_NEG]], i4 undef, i64 1 847; CHECK-NEXT: [[T2:%.*]] = add <2 x i4> [[T11_NEG]], [[Y:%.*]] 848; CHECK-NEXT: ret <2 x i4> [[T2]] 849; 850 %t0 = shl <2 x i4> <i4 -6, i4 5>, %x 851 %t1 = shufflevector <2 x i4> %t0, <2 x i4> undef, <2 x i32> <i32 0, i32 2> 852 %t2 = sub <2 x i4> %y, %t1 853 ret <2 x i4> %t2 854} 855define <2 x i4> @negate_shufflevector_twoinputs(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) { 856; CHECK-LABEL: @negate_shufflevector_twoinputs( 857; CHECK-NEXT: [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X:%.*]] 858; CHECK-NEXT: [[T1_NEG:%.*]] = add <2 x i4> [[Y:%.*]], <i4 poison, i4 1> 859; CHECK-NEXT: [[T2_NEG:%.*]] = shufflevector <2 x i4> [[T0_NEG]], <2 x i4> [[T1_NEG]], <2 x i32> <i32 0, i32 3> 860; CHECK-NEXT: [[T3:%.*]] = add <2 x i4> [[T2_NEG]], [[Z:%.*]] 861; CHECK-NEXT: ret <2 x i4> [[T3]] 862; 863 %t0 = shl <2 x i4> <i4 -6, i4 5>, %x 864 %t1 = xor <2 x i4> %y, <i4 -1, i4 -1> 865 %t2 = shufflevector <2 x i4> %t0, <2 x i4> %t1, <2 x i32> <i32 0, i32 3> 866 %t3 = sub <2 x i4> %z, %t2 867 ret <2 x i4> %t3 868} 869define <2 x i4> @negate_shufflevector_oneinput_extrause(<2 x i4> %x, <2 x i4> %y) { 870; CHECK-LABEL: @negate_shufflevector_oneinput_extrause( 871; CHECK-NEXT: [[T0:%.*]] = shl <2 x i4> <i4 -6, i4 5>, [[X:%.*]] 872; CHECK-NEXT: [[T1:%.*]] = shufflevector <2 x i4> [[T0]], <2 x i4> poison, <2 x i32> <i32 1, i32 0> 873; CHECK-NEXT: call void @use_v2i4(<2 x i4> [[T1]]) 874; CHECK-NEXT: [[T2:%.*]] = sub <2 x i4> [[Y:%.*]], [[T1]] 875; CHECK-NEXT: ret <2 x i4> [[T2]] 876; 877 %t0 = shl <2 x i4> <i4 -6, i4 5>, %x 878 %t1 = shufflevector <2 x i4> %t0, <2 x i4> undef, <2 x i32> <i32 1, i32 0> 879 call void @use_v2i4(<2 x i4> %t1) 880 %t2 = sub <2 x i4> %y, %t1 881 ret <2 x i4> %t2 882} 883 884; zext of non-negative can be negated 885; sext of non-positive can be negated 886define i16 @negation_of_zeroext_of_nonnegative(i8 %x) { 887; CHECK-LABEL: @negation_of_zeroext_of_nonnegative( 888; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[X:%.*]] 889; CHECK-NEXT: [[T1:%.*]] = icmp sgt i8 [[T0]], -1 890; CHECK-NEXT: br i1 [[T1]], label [[NONNEG_BB:%.*]], label [[NEG_BB:%.*]] 891; CHECK: nonneg_bb: 892; CHECK-NEXT: [[T2:%.*]] = zext nneg i8 [[T0]] to i16 893; CHECK-NEXT: [[T3:%.*]] = sub nsw i16 0, [[T2]] 894; CHECK-NEXT: ret i16 [[T3]] 895; CHECK: neg_bb: 896; CHECK-NEXT: ret i16 0 897; 898 %t0 = sub i8 0, %x 899 %t1 = icmp sge i8 %t0, 0 900 br i1 %t1, label %nonneg_bb, label %neg_bb 901 902nonneg_bb: 903 %t2 = zext i8 %t0 to i16 904 %t3 = sub i16 0, %t2 905 ret i16 %t3 906 907neg_bb: 908 ret i16 0 909} 910define i16 @negation_of_zeroext_of_positive(i8 %x) { 911; CHECK-LABEL: @negation_of_zeroext_of_positive( 912; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[X:%.*]] 913; CHECK-NEXT: [[T1:%.*]] = icmp sgt i8 [[T0]], 0 914; CHECK-NEXT: br i1 [[T1]], label [[NONNEG_BB:%.*]], label [[NEG_BB:%.*]] 915; CHECK: nonneg_bb: 916; CHECK-NEXT: [[T2:%.*]] = zext nneg i8 [[T0]] to i16 917; CHECK-NEXT: [[T3:%.*]] = sub nsw i16 0, [[T2]] 918; CHECK-NEXT: ret i16 [[T3]] 919; CHECK: neg_bb: 920; CHECK-NEXT: ret i16 0 921; 922 %t0 = sub i8 0, %x 923 %t1 = icmp sgt i8 %t0, 0 924 br i1 %t1, label %nonneg_bb, label %neg_bb 925 926nonneg_bb: 927 %t2 = zext i8 %t0 to i16 928 %t3 = sub i16 0, %t2 929 ret i16 %t3 930 931neg_bb: 932 ret i16 0 933} 934define i16 @negation_of_signext_of_negative(i8 %x) { 935; CHECK-LABEL: @negation_of_signext_of_negative( 936; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[X:%.*]] 937; CHECK-NEXT: [[T1:%.*]] = icmp slt i8 [[T0]], 0 938; CHECK-NEXT: br i1 [[T1]], label [[NEG_BB:%.*]], label [[NONNEG_BB:%.*]] 939; CHECK: neg_bb: 940; CHECK-NEXT: [[T2:%.*]] = sext i8 [[T0]] to i16 941; CHECK-NEXT: [[T3:%.*]] = sub nsw i16 0, [[T2]] 942; CHECK-NEXT: ret i16 [[T3]] 943; CHECK: nonneg_bb: 944; CHECK-NEXT: ret i16 0 945; 946 %t0 = sub i8 0, %x 947 %t1 = icmp slt i8 %t0, 0 948 br i1 %t1, label %neg_bb, label %nonneg_bb 949 950neg_bb: 951 %t2 = sext i8 %t0 to i16 952 %t3 = sub i16 0, %t2 953 ret i16 %t3 954 955nonneg_bb: 956 ret i16 0 957} 958define i16 @negation_of_signext_of_nonpositive(i8 %x) { 959; CHECK-LABEL: @negation_of_signext_of_nonpositive( 960; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[X:%.*]] 961; CHECK-NEXT: [[T1:%.*]] = icmp slt i8 [[T0]], 1 962; CHECK-NEXT: br i1 [[T1]], label [[NEG_BB:%.*]], label [[NONNEG_BB:%.*]] 963; CHECK: neg_bb: 964; CHECK-NEXT: [[T2:%.*]] = sext i8 [[T0]] to i16 965; CHECK-NEXT: [[T3:%.*]] = sub nsw i16 0, [[T2]] 966; CHECK-NEXT: ret i16 [[T3]] 967; CHECK: nonneg_bb: 968; CHECK-NEXT: ret i16 0 969; 970 %t0 = sub i8 0, %x 971 %t1 = icmp sle i8 %t0, 0 972 br i1 %t1, label %neg_bb, label %nonneg_bb 973 974neg_bb: 975 %t2 = sext i8 %t0 to i16 976 %t3 = sub i16 0, %t2 977 ret i16 %t3 978 979nonneg_bb: 980 ret i16 0 981} 982define i16 @negation_of_signext_of_nonnegative__wrong_cast(i8 %x) { 983; CHECK-LABEL: @negation_of_signext_of_nonnegative__wrong_cast( 984; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[X:%.*]] 985; CHECK-NEXT: [[T1:%.*]] = icmp sgt i8 [[T0]], -1 986; CHECK-NEXT: br i1 [[T1]], label [[NONNEG_BB:%.*]], label [[NEG_BB:%.*]] 987; CHECK: nonneg_bb: 988; CHECK-NEXT: [[T2:%.*]] = zext nneg i8 [[T0]] to i16 989; CHECK-NEXT: [[T3:%.*]] = sub nsw i16 0, [[T2]] 990; CHECK-NEXT: ret i16 [[T3]] 991; CHECK: neg_bb: 992; CHECK-NEXT: ret i16 0 993; 994 %t0 = sub i8 0, %x 995 %t1 = icmp sge i8 %t0, 0 996 br i1 %t1, label %nonneg_bb, label %neg_bb 997 998nonneg_bb: 999 %t2 = sext i8 %t0 to i16 1000 %t3 = sub i16 0, %t2 1001 ret i16 %t3 1002 1003neg_bb: 1004 ret i16 0 1005} 1006define i16 @negation_of_zeroext_of_negative_wrongcast(i8 %x) { 1007; CHECK-LABEL: @negation_of_zeroext_of_negative_wrongcast( 1008; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[X:%.*]] 1009; CHECK-NEXT: [[T1:%.*]] = icmp slt i8 [[T0]], 0 1010; CHECK-NEXT: br i1 [[T1]], label [[NEG_BB:%.*]], label [[NONNEG_BB:%.*]] 1011; CHECK: neg_bb: 1012; CHECK-NEXT: [[T2:%.*]] = zext i8 [[T0]] to i16 1013; CHECK-NEXT: [[T3:%.*]] = sub nsw i16 0, [[T2]] 1014; CHECK-NEXT: ret i16 [[T3]] 1015; CHECK: nonneg_bb: 1016; CHECK-NEXT: ret i16 0 1017; 1018 %t0 = sub i8 0, %x 1019 %t1 = icmp slt i8 %t0, 0 1020 br i1 %t1, label %neg_bb, label %nonneg_bb 1021 1022neg_bb: 1023 %t2 = zext i8 %t0 to i16 1024 %t3 = sub i16 0, %t2 1025 ret i16 %t3 1026 1027nonneg_bb: 1028 ret i16 0 1029} 1030 1031; 'or' of 1 and operand with no lowest bit set is 'inc' 1032define i8 @negation_of_increment_via_or_with_no_common_bits_set(i8 %x, i8 %y) { 1033; CHECK-LABEL: @negation_of_increment_via_or_with_no_common_bits_set( 1034; CHECK-NEXT: [[T0:%.*]] = shl i8 [[Y:%.*]], 1 1035; CHECK-NEXT: [[T1_NEG:%.*]] = xor i8 [[T0]], -1 1036; CHECK-NEXT: [[T2:%.*]] = add i8 [[X:%.*]], [[T1_NEG]] 1037; CHECK-NEXT: ret i8 [[T2]] 1038; 1039 %t0 = shl i8 %y, 1 1040 %t1 = or i8 %t0, 1 1041 %t2 = sub i8 %x, %t1 1042 ret i8 %t2 1043} 1044define i8 @negation_of_increment_via_or_with_no_common_bits_set_extrause(i8 %x, i8 %y) { 1045; CHECK-LABEL: @negation_of_increment_via_or_with_no_common_bits_set_extrause( 1046; CHECK-NEXT: [[T0:%.*]] = shl i8 [[Y:%.*]], 1 1047; CHECK-NEXT: [[T1:%.*]] = or disjoint i8 [[T0]], 1 1048; CHECK-NEXT: call void @use8(i8 [[T1]]) 1049; CHECK-NEXT: [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]] 1050; CHECK-NEXT: ret i8 [[T2]] 1051; 1052 %t0 = shl i8 %y, 1 1053 %t1 = or i8 %t0, 1 1054 call void @use8(i8 %t1) 1055 %t2 = sub i8 %x, %t1 1056 ret i8 %t2 1057} 1058define i8 @negation_of_increment_via_or_common_bits_set(i8 %x, i8 %y) { 1059; CHECK-LABEL: @negation_of_increment_via_or_common_bits_set( 1060; CHECK-NEXT: [[T0:%.*]] = shl i8 [[Y:%.*]], 1 1061; CHECK-NEXT: [[T1:%.*]] = or i8 [[T0]], 3 1062; CHECK-NEXT: [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]] 1063; CHECK-NEXT: ret i8 [[T2]] 1064; 1065 %t0 = shl i8 %y, 1 1066 %t1 = or i8 %t0, 3 1067 %t2 = sub i8 %x, %t1 1068 ret i8 %t2 1069} 1070 1071define i8 @negation_of_increment_via_or_disjoint(i8 %x, i8 %y) { 1072; CHECK-LABEL: @negation_of_increment_via_or_disjoint( 1073; CHECK-NEXT: [[T1_NEG:%.*]] = xor i8 [[Y:%.*]], -1 1074; CHECK-NEXT: [[T2:%.*]] = add i8 [[X:%.*]], [[T1_NEG]] 1075; CHECK-NEXT: ret i8 [[T2]] 1076; 1077 %t1 = or disjoint i8 %y, 1 1078 %t2 = sub i8 %x, %t1 1079 ret i8 %t2 1080} 1081 1082; 'or' of operands with no common bits set is 'add' 1083define i8 @add_via_or_with_no_common_bits_set(i8 %x, i8 %y) { 1084; CHECK-LABEL: @add_via_or_with_no_common_bits_set( 1085; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[Y:%.*]] 1086; CHECK-NEXT: call void @use8(i8 [[T0]]) 1087; CHECK-NEXT: [[T1_NEG:%.*]] = shl i8 [[Y]], 2 1088; CHECK-NEXT: [[T2_NEG:%.*]] = add i8 [[T1_NEG]], -3 1089; CHECK-NEXT: [[T3:%.*]] = add i8 [[T2_NEG]], [[X:%.*]] 1090; CHECK-NEXT: ret i8 [[T3]] 1091; 1092 %t0 = sub i8 0, %y 1093 call void @use8(i8 %t0) 1094 %t1 = shl i8 %t0, 2 1095 %t2 = or i8 %t1, 3 1096 %t3 = sub i8 %x, %t2 1097 ret i8 %t3 1098} 1099define i8 @add_via_or_with_common_bit_maybe_set(i8 %x, i8 %y) { 1100; CHECK-LABEL: @add_via_or_with_common_bit_maybe_set( 1101; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[Y:%.*]] 1102; CHECK-NEXT: call void @use8(i8 [[T0]]) 1103; CHECK-NEXT: [[T1:%.*]] = shl i8 [[T0]], 2 1104; CHECK-NEXT: [[T2:%.*]] = or i8 [[T1]], 4 1105; CHECK-NEXT: [[T3:%.*]] = sub i8 [[X:%.*]], [[T2]] 1106; CHECK-NEXT: ret i8 [[T3]] 1107; 1108 %t0 = sub i8 0, %y 1109 call void @use8(i8 %t0) 1110 %t1 = shl i8 %t0, 2 1111 %t2 = or i8 %t1, 4 1112 %t3 = sub i8 %x, %t2 1113 ret i8 %t3 1114} 1115define i8 @add_via_or_with_no_common_bits_set_extrause(i8 %x, i8 %y) { 1116; CHECK-LABEL: @add_via_or_with_no_common_bits_set_extrause( 1117; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[Y:%.*]] 1118; CHECK-NEXT: call void @use8(i8 [[T0]]) 1119; CHECK-NEXT: [[T1:%.*]] = shl i8 [[T0]], 2 1120; CHECK-NEXT: [[T2:%.*]] = or disjoint i8 [[T1]], 3 1121; CHECK-NEXT: call void @use8(i8 [[T2]]) 1122; CHECK-NEXT: [[T3:%.*]] = sub i8 [[X:%.*]], [[T2]] 1123; CHECK-NEXT: ret i8 [[T3]] 1124; 1125 %t0 = sub i8 0, %y 1126 call void @use8(i8 %t0) 1127 %t1 = shl i8 %t0, 2 1128 %t2 = or i8 %t1, 3 1129 call void @use8(i8 %t2) 1130 %t3 = sub i8 %x, %t2 1131 ret i8 %t3 1132} 1133 1134; `extractelement` is negatible if source operand is negatible. 1135define i4 @negate_extractelement(<2 x i4> %x, i32 %y, i4 %z) { 1136; CHECK-LABEL: @negate_extractelement( 1137; CHECK-NEXT: [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[X:%.*]] 1138; CHECK-NEXT: call void @use_v2i4(<2 x i4> [[T0]]) 1139; CHECK-NEXT: [[T1_NEG:%.*]] = extractelement <2 x i4> [[X]], i32 [[Y:%.*]] 1140; CHECK-NEXT: [[T2:%.*]] = add i4 [[T1_NEG]], [[Z:%.*]] 1141; CHECK-NEXT: ret i4 [[T2]] 1142; 1143 %t0 = sub <2 x i4> zeroinitializer, %x 1144 call void @use_v2i4(<2 x i4> %t0) 1145 %t1 = extractelement <2 x i4> %t0, i32 %y 1146 %t2 = sub i4 %z, %t1 1147 ret i4 %t2 1148} 1149define i4 @negate_extractelement_extrause(<2 x i4> %x, i32 %y, i4 %z) { 1150; CHECK-LABEL: @negate_extractelement_extrause( 1151; CHECK-NEXT: [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[X:%.*]] 1152; CHECK-NEXT: call void @use_v2i4(<2 x i4> [[T0]]) 1153; CHECK-NEXT: [[T1:%.*]] = extractelement <2 x i4> [[T0]], i32 [[Y:%.*]] 1154; CHECK-NEXT: call void @use4(i4 [[T1]]) 1155; CHECK-NEXT: [[T2:%.*]] = sub i4 [[Z:%.*]], [[T1]] 1156; CHECK-NEXT: ret i4 [[T2]] 1157; 1158 %t0 = sub <2 x i4> zeroinitializer, %x 1159 call void @use_v2i4(<2 x i4> %t0) 1160 %t1 = extractelement <2 x i4> %t0, i32 %y 1161 call void @use4(i4 %t1) 1162 %t2 = sub i4 %z, %t1 1163 ret i4 %t2 1164} 1165 1166; `insertelement` is negatible if both source vector and element-to-be-inserted are negatible. 1167define <2 x i4> @negate_insertelement(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) { 1168; CHECK-LABEL: @negate_insertelement( 1169; CHECK-NEXT: [[T2_NEG:%.*]] = insertelement <2 x i4> [[SRC:%.*]], i4 [[A:%.*]], i32 [[X:%.*]] 1170; CHECK-NEXT: [[T3:%.*]] = add <2 x i4> [[T2_NEG]], [[B:%.*]] 1171; CHECK-NEXT: ret <2 x i4> [[T3]] 1172; 1173 %t0 = sub <2 x i4> zeroinitializer, %src 1174 %t1 = sub i4 zeroinitializer, %a 1175 %t2 = insertelement <2 x i4> %t0, i4 %t1, i32 %x 1176 %t3 = sub <2 x i4> %b, %t2 1177 ret <2 x i4> %t3 1178} 1179define <2 x i4> @negate_insertelement_extrause(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) { 1180; CHECK-LABEL: @negate_insertelement_extrause( 1181; CHECK-NEXT: [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[SRC:%.*]] 1182; CHECK-NEXT: [[T1:%.*]] = sub i4 0, [[A:%.*]] 1183; CHECK-NEXT: [[T2:%.*]] = insertelement <2 x i4> [[T0]], i4 [[T1]], i32 [[X:%.*]] 1184; CHECK-NEXT: call void @use_v2i4(<2 x i4> [[T2]]) 1185; CHECK-NEXT: [[T3:%.*]] = sub <2 x i4> [[B:%.*]], [[T2]] 1186; CHECK-NEXT: ret <2 x i4> [[T3]] 1187; 1188 %t0 = sub <2 x i4> zeroinitializer, %src 1189 %t1 = sub i4 zeroinitializer, %a 1190 %t2 = insertelement <2 x i4> %t0, i4 %t1, i32 %x 1191 call void @use_v2i4(<2 x i4> %t2) 1192 %t3 = sub <2 x i4> %b, %t2 1193 ret <2 x i4> %t3 1194} 1195define <2 x i4> @negate_insertelement_nonnegatible_base(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) { 1196; CHECK-LABEL: @negate_insertelement_nonnegatible_base( 1197; CHECK-NEXT: [[T1:%.*]] = sub i4 0, [[A:%.*]] 1198; CHECK-NEXT: [[T2:%.*]] = insertelement <2 x i4> [[SRC:%.*]], i4 [[T1]], i32 [[X:%.*]] 1199; CHECK-NEXT: [[T3:%.*]] = sub <2 x i4> [[B:%.*]], [[T2]] 1200; CHECK-NEXT: ret <2 x i4> [[T3]] 1201; 1202 %t1 = sub i4 zeroinitializer, %a 1203 %t2 = insertelement <2 x i4> %src, i4 %t1, i32 %x 1204 %t3 = sub <2 x i4> %b, %t2 1205 ret <2 x i4> %t3 1206} 1207define <2 x i4> @negate_insertelement_nonnegatible_insert(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) { 1208; CHECK-LABEL: @negate_insertelement_nonnegatible_insert( 1209; CHECK-NEXT: [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[SRC:%.*]] 1210; CHECK-NEXT: [[T2:%.*]] = insertelement <2 x i4> [[T0]], i4 [[A:%.*]], i32 [[X:%.*]] 1211; CHECK-NEXT: [[T3:%.*]] = sub <2 x i4> [[B:%.*]], [[T2]] 1212; CHECK-NEXT: ret <2 x i4> [[T3]] 1213; 1214 %t0 = sub <2 x i4> zeroinitializer, %src 1215 %t2 = insertelement <2 x i4> %t0, i4 %a, i32 %x 1216 %t3 = sub <2 x i4> %b, %t2 1217 ret <2 x i4> %t3 1218} 1219 1220; left-shift by constant can always be negated 1221define i8 @negate_left_shift_by_constant_prefer_keeping_shl(i8 %x, i8 %y, i8 %z) { 1222; CHECK-LABEL: @negate_left_shift_by_constant_prefer_keeping_shl( 1223; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[Z:%.*]] 1224; CHECK-NEXT: call void @use8(i8 [[T0]]) 1225; CHECK-NEXT: [[T1_NEG:%.*]] = shl i8 [[Z]], 4 1226; CHECK-NEXT: [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]] 1227; CHECK-NEXT: ret i8 [[T2]] 1228; 1229 %t0 = sub i8 0, %z 1230 call void @use8(i8 %t0) 1231 %t1 = shl i8 %t0, 4 1232 %t2 = sub i8 %x, %t1 1233 ret i8 %t2 1234} 1235define i8 @negate_left_shift_by_constant_prefer_keeping_shl_extrause(i8 %x, i8 %y, i8 %z) { 1236; CHECK-LABEL: @negate_left_shift_by_constant_prefer_keeping_shl_extrause( 1237; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[Z:%.*]] 1238; CHECK-NEXT: call void @use8(i8 [[T0]]) 1239; CHECK-NEXT: [[T1:%.*]] = shl i8 [[T0]], 4 1240; CHECK-NEXT: call void @use8(i8 [[T1]]) 1241; CHECK-NEXT: [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]] 1242; CHECK-NEXT: ret i8 [[T2]] 1243; 1244 %t0 = sub i8 0, %z 1245 call void @use8(i8 %t0) 1246 %t1 = shl i8 %t0, 4 1247 call void @use8(i8 %t1) 1248 %t2 = sub i8 %x, %t1 1249 ret i8 %t2 1250} 1251define i8 @negate_left_shift_by_constant(i8 %x, i8 %y, i8 %z, i8 %k) { 1252; CHECK-LABEL: @negate_left_shift_by_constant( 1253; CHECK-NEXT: [[T0:%.*]] = sub i8 [[K:%.*]], [[Z:%.*]] 1254; CHECK-NEXT: call void @use8(i8 [[T0]]) 1255; CHECK-NEXT: [[T1:%.*]] = shl i8 [[T0]], 4 1256; CHECK-NEXT: [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]] 1257; CHECK-NEXT: ret i8 [[T2]] 1258; 1259 %t0 = sub i8 %k, %z 1260 call void @use8(i8 %t0) 1261 %t1 = shl i8 %t0, 4 1262 %t2 = sub i8 %x, %t1 1263 ret i8 %t2 1264} 1265define i8 @negate_left_shift_by_constant_extrause(i8 %x, i8 %y, i8 %z, i8 %k) { 1266; CHECK-LABEL: @negate_left_shift_by_constant_extrause( 1267; CHECK-NEXT: [[T0:%.*]] = sub i8 [[K:%.*]], [[Z:%.*]] 1268; CHECK-NEXT: call void @use8(i8 [[T0]]) 1269; CHECK-NEXT: [[T1:%.*]] = shl i8 [[T0]], 4 1270; CHECK-NEXT: call void @use8(i8 [[T1]]) 1271; CHECK-NEXT: [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]] 1272; CHECK-NEXT: ret i8 [[T2]] 1273; 1274 %t0 = sub i8 %k, %z 1275 call void @use8(i8 %t0) 1276 %t1 = shl i8 %t0, 4 1277 call void @use8(i8 %t1) 1278 %t2 = sub i8 %x, %t1 1279 ret i8 %t2 1280} 1281 1282; `add` with single negatible operand is still negatible 1283define i8 @negate_add_with_single_negatible_operand(i8 %x, i8 %y) { 1284; CHECK-LABEL: @negate_add_with_single_negatible_operand( 1285; CHECK-NEXT: [[T1:%.*]] = sub i8 -42, [[X:%.*]] 1286; CHECK-NEXT: ret i8 [[T1]] 1287; 1288 %t0 = add i8 %x, 42 1289 %t1 = sub i8 0, %t0 1290 ret i8 %t1 1291} 1292; do so even if we are two levels deep 1293define i8 @negate_add_with_single_negatible_operand_depth2(i8 %x, i8 %y) { 1294; CHECK-LABEL: @negate_add_with_single_negatible_operand_depth2( 1295; CHECK-NEXT: [[T0_NEG:%.*]] = sub i8 -21, [[X:%.*]] 1296; CHECK-NEXT: [[T1_NEG:%.*]] = mul i8 [[T0_NEG]], [[Y:%.*]] 1297; CHECK-NEXT: ret i8 [[T1_NEG]] 1298; 1299 %t0 = add i8 %x, 21 1300 %t1 = mul i8 %t0, %y 1301 %t2 = sub i8 0, %t1 1302 ret i8 %t2 1303} 1304 1305define i8 @negate_add_with_single_negatible_operand_extrause(i8 %x, i8 %y) { 1306; CHECK-LABEL: @negate_add_with_single_negatible_operand_extrause( 1307; CHECK-NEXT: [[T0:%.*]] = add i8 [[X:%.*]], 42 1308; CHECK-NEXT: call void @use8(i8 [[T0]]) 1309; CHECK-NEXT: [[T1:%.*]] = sub i8 -42, [[X]] 1310; CHECK-NEXT: ret i8 [[T1]] 1311; 1312 %t0 = add i8 %x, 42 1313 call void @use8(i8 %t0) 1314 %t1 = sub i8 0, %t0 1315 ret i8 %t1 1316} 1317; But don't do this if that means just sinking the negation. 1318define i8 @negate_add_with_single_negatible_operand_non_negation(i8 %x, i8 %y) { 1319; CHECK-LABEL: @negate_add_with_single_negatible_operand_non_negation( 1320; CHECK-NEXT: [[T0:%.*]] = add i8 [[X:%.*]], 42 1321; CHECK-NEXT: [[T1:%.*]] = sub i8 [[Y:%.*]], [[T0]] 1322; CHECK-NEXT: ret i8 [[T1]] 1323; 1324 %t0 = add i8 %x, 42 1325 %t1 = sub i8 %y, %t0 1326 ret i8 %t1 1327} 1328 1329; abs/nabs can be negated 1330define i8 @negate_abs(i8 %x, i8 %y) { 1331; CHECK-LABEL: @negate_abs( 1332; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[X:%.*]] 1333; CHECK-NEXT: call void @use8(i8 [[T0]]) 1334; CHECK-NEXT: [[T2:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false) 1335; CHECK-NEXT: [[T3:%.*]] = sub i8 [[Y:%.*]], [[T2]] 1336; CHECK-NEXT: ret i8 [[T3]] 1337; 1338 %t0 = sub i8 0, %x 1339 call void @use8(i8 %t0) 1340 %t1 = icmp slt i8 %x, 0 1341 %t2 = select i1 %t1, i8 %t0, i8 %x, !prof !0 1342 %t3 = sub i8 %y, %t2 1343 ret i8 %t3 1344} 1345define i8 @negate_nabs(i8 %x, i8 %y) { 1346; CHECK-LABEL: @negate_nabs( 1347; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[X:%.*]] 1348; CHECK-NEXT: call void @use8(i8 [[T0]]) 1349; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false) 1350; CHECK-NEXT: [[T3:%.*]] = add i8 [[Y:%.*]], [[TMP1]] 1351; CHECK-NEXT: ret i8 [[T3]] 1352; 1353 %t0 = sub i8 0, %x 1354 call void @use8(i8 %t0) 1355 %t1 = icmp slt i8 %x, 0 1356 %t2 = select i1 %t1, i8 %x, i8 %t0, !prof !0 1357 %t3 = sub i8 %y, %t2 1358 ret i8 %t3 1359} 1360 1361; And in general, if hands of select are known to be negation of each other, 1362; we can negate the select 1363define i8 @negate_select_of_op_vs_negated_op(i8 %x, i8 %y, i1 %c) { 1364; CHECK-LABEL: @negate_select_of_op_vs_negated_op( 1365; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[X:%.*]] 1366; CHECK-NEXT: call void @use8(i8 [[T0]]) 1367; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C:%.*]], i8 [[X]], i8 [[T0]], !prof [[PROF0:![0-9]+]] 1368; CHECK-NEXT: [[T2:%.*]] = add i8 [[TMP1]], [[Y:%.*]] 1369; CHECK-NEXT: ret i8 [[T2]] 1370; 1371 %t0 = sub i8 0, %x 1372 call void @use8(i8 %t0) 1373 %t1 = select i1 %c, i8 %t0, i8 %x, !prof !0 1374 %t2 = sub i8 %y, %t1 1375 ret i8 %t2 1376} 1377 1378define i8 @negate_select_of_op_vs_negated_op_nsw(i8 %x, i8 %y, i1 %c) { 1379; CHECK-LABEL: @negate_select_of_op_vs_negated_op_nsw( 1380; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[X:%.*]] 1381; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C:%.*]], i8 [[X]], i8 [[T0]] 1382; CHECK-NEXT: [[T2:%.*]] = add i8 [[TMP1]], [[Y:%.*]] 1383; CHECK-NEXT: ret i8 [[T2]] 1384; 1385 %t0 = sub nsw i8 0, %x 1386 %t1 = select i1 %c, i8 %t0, i8 %x 1387 %t2 = sub i8 %y, %t1 1388 ret i8 %t2 1389} 1390 1391define i8 @negate_select_of_op_vs_negated_op_nsw_commuted(i8 %x, i8 %y, i1 %c) { 1392; CHECK-LABEL: @negate_select_of_op_vs_negated_op_nsw_commuted( 1393; CHECK-NEXT: [[T0:%.*]] = sub i8 0, [[X:%.*]] 1394; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C:%.*]], i8 [[T0]], i8 [[X]] 1395; CHECK-NEXT: [[T2:%.*]] = add i8 [[TMP1]], [[Y:%.*]] 1396; CHECK-NEXT: ret i8 [[T2]] 1397; 1398 %t0 = sub nsw i8 0, %x 1399 %t1 = select i1 %c, i8 %x, i8 %t0 1400 %t2 = sub i8 %y, %t1 1401 ret i8 %t2 1402} 1403 1404define i8 @negate_select_of_op_vs_negated_op_nsw_xyyx(i8 %x, i8 %y, i8 %z, i1 %c) { 1405; CHECK-LABEL: @negate_select_of_op_vs_negated_op_nsw_xyyx( 1406; CHECK-NEXT: [[SUB1:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] 1407; CHECK-NEXT: [[SUB2:%.*]] = sub i8 [[Y]], [[X]] 1408; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C:%.*]], i8 [[SUB2]], i8 [[SUB1]] 1409; CHECK-NEXT: [[T2:%.*]] = add i8 [[TMP1]], [[Z:%.*]] 1410; CHECK-NEXT: ret i8 [[T2]] 1411; 1412 %sub1 = sub nsw i8 %x, %y 1413 %sub2 = sub nsw i8 %y, %x 1414 %t1 = select i1 %c, i8 %sub1, i8 %sub2 1415 %t2 = sub i8 %z, %t1 1416 ret i8 %t2 1417} 1418 1419define i8 @dont_negate_ordinary_select(i8 %x, i8 %y, i8 %z, i1 %c) { 1420; CHECK-LABEL: @dont_negate_ordinary_select( 1421; CHECK-NEXT: [[T0:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]] 1422; CHECK-NEXT: [[T1:%.*]] = sub i8 [[Z:%.*]], [[T0]] 1423; CHECK-NEXT: ret i8 [[T1]] 1424; 1425 %t0 = select i1 %c, i8 %x, i8 %y 1426 %t1 = sub i8 %z, %t0 1427 ret i8 %t1 1428} 1429 1430define <2 x i32> @negate_select_of_negation_poison(<2 x i1> %c, <2 x i32> %x) { 1431; CHECK-LABEL: @negate_select_of_negation_poison( 1432; CHECK-NEXT: [[NEG:%.*]] = sub <2 x i32> <i32 0, i32 poison>, [[X:%.*]] 1433; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i32> [[NEG]], <2 x i32> [[X]] 1434; CHECK-NEXT: [[NEG2:%.*]] = sub <2 x i32> zeroinitializer, [[SEL]] 1435; CHECK-NEXT: ret <2 x i32> [[NEG2]] 1436; 1437 %neg = sub <2 x i32> <i32 0, i32 poison>, %x 1438 %sel = select <2 x i1> %c, <2 x i32> %neg, <2 x i32> %x 1439 %neg2 = sub <2 x i32> zeroinitializer, %sel 1440 ret <2 x i32> %neg2 1441} 1442 1443; Freeze is transparent as far as negation is concerned 1444define i4 @negate_freeze(i4 %x, i4 %y, i4 %z) { 1445; CHECK-LABEL: @negate_freeze( 1446; CHECK-NEXT: [[T0_NEG:%.*]] = sub i4 [[Y:%.*]], [[X:%.*]] 1447; CHECK-NEXT: [[T1_NEG:%.*]] = freeze i4 [[T0_NEG]] 1448; CHECK-NEXT: [[T2:%.*]] = add i4 [[T1_NEG]], [[Z:%.*]] 1449; CHECK-NEXT: ret i4 [[T2]] 1450; 1451 %t0 = sub i4 %x, %y 1452 %t1 = freeze i4 %t0 1453 %t2 = sub i4 %z, %t1 1454 ret i4 %t2 1455} 1456define i4 @negate_freeze_extrause(i4 %x, i4 %y, i4 %z) { 1457; CHECK-LABEL: @negate_freeze_extrause( 1458; CHECK-NEXT: [[T0:%.*]] = sub i4 [[X:%.*]], [[Y:%.*]] 1459; CHECK-NEXT: [[T1:%.*]] = freeze i4 [[T0]] 1460; CHECK-NEXT: call void @use4(i4 [[T1]]) 1461; CHECK-NEXT: [[T2:%.*]] = sub i4 [[Z:%.*]], [[T1]] 1462; CHECK-NEXT: ret i4 [[T2]] 1463; 1464 %t0 = sub i4 %x, %y 1465 %t1 = freeze i4 %t0 1466 call void @use4(i4 %t1) 1467 %t2 = sub i4 %z, %t1 1468 ret i4 %t2 1469} 1470 1471; Due to the InstCombine's worklist management, there are no guarantees that 1472; each instruction we'll encounter has been visited by InstCombine already. 1473; In particular, most importantly for us, that means we have to canonicalize 1474; constants to RHS ourselves, since that is helpful sometimes. 1475; This used to cause an endless combine loop. 1476define void @noncanonical_mul_with_constant_as_first_operand() { 1477; CHECK-LABEL: @noncanonical_mul_with_constant_as_first_operand( 1478; CHECK-NEXT: entry: 1479; CHECK-NEXT: br label [[IF_END:%.*]] 1480; CHECK: if.end: 1481; CHECK-NEXT: br label [[IF_END]] 1482; 1483entry: 1484 br label %if.end 1485 1486if.end: 1487 %e.0 = phi i32 [ undef, %entry ], [ %div, %if.end ] 1488 %conv = trunc i32 %e.0 to i16 1489 %mul.i = mul nsw i16 -1, %conv 1490 %conv1 = sext i16 %mul.i to i32 1491 %div = sub nsw i32 0, %conv1 1492 br label %if.end 1493} 1494 1495; This would infinite loop because we failed to match a 1496; vector constant with constant expression elements as 1497; a constant expression. 1498 1499@g = external hidden global [1 x [1 x double]] 1500 1501define <1 x i64> @PR56601(<1 x i64> %x, <1 x i64> %y) { 1502; CHECK-LABEL: @PR56601( 1503; CHECK-NEXT: [[M1:%.*]] = mul nsw <1 x i64> [[X:%.*]], splat (i64 42) 1504; CHECK-NEXT: [[M2:%.*]] = mul nsw <1 x i64> [[Y:%.*]], splat (i64 12) 1505; CHECK-NEXT: [[A1:%.*]] = add <1 x i64> [[M1]], <i64 add (i64 ptrtoint (ptr @g to i64), i64 -4)> 1506; CHECK-NEXT: [[A2:%.*]] = add <1 x i64> [[M2]], <i64 add (i64 ptrtoint (ptr @g to i64), i64 -3)> 1507; CHECK-NEXT: [[R:%.*]] = sub <1 x i64> [[A1]], [[A2]] 1508; CHECK-NEXT: ret <1 x i64> [[R]] 1509; 1510 %m1 = mul nsw <1 x i64> %x, <i64 42> 1511 %m2 = mul nsw <1 x i64> %y, <i64 12> 1512 %a1 = add <1 x i64> %m1, <i64 add (i64 ptrtoint (ptr @g to i64), i64 -4)> 1513 %a2 = add <1 x i64> %m2, <i64 add (i64 ptrtoint (ptr @g to i64), i64 -3)> 1514 %r = sub <1 x i64> %a1, %a2 1515 ret <1 x i64> %r 1516} 1517 1518; CHECK: !0 = !{!"branch_weights", i32 40, i32 1} 1519!0 = !{!"branch_weights", i32 40, i32 1} 1520