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