1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s 3 4define i8 @test0(i8 %a, i8 %b) { 5; CHECK-LABEL: @test0( 6; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[A:%.*]], [[B:%.*]] 7; CHECK-NEXT: ret i8 [[SHL]] 8; 9 %shl = shl i8 %a, %b 10 ret i8 %shl 11} 12 13define i8 @test1(i8 %a, i8 %b) { 14; CHECK-LABEL: @test1( 15; CHECK-NEXT: entry: 16; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 8 17; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 18; CHECK: bb: 19; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[A:%.*]], [[B]] 20; CHECK-NEXT: ret i8 [[SHL]] 21; CHECK: exit: 22; CHECK-NEXT: ret i8 0 23; 24entry: 25 %cmp = icmp ult i8 %b, 8 26 br i1 %cmp, label %bb, label %exit 27 28bb: 29 %shl = shl i8 %a, %b 30 ret i8 %shl 31 32exit: 33 ret i8 0 34} 35 36define i8 @test2(i8 %a, i8 %b) { 37; CHECK-LABEL: @test2( 38; CHECK-NEXT: entry: 39; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 9 40; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 41; CHECK: bb: 42; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[A:%.*]], [[B]] 43; CHECK-NEXT: ret i8 [[SHL]] 44; CHECK: exit: 45; CHECK-NEXT: ret i8 0 46; 47entry: 48 %cmp = icmp ult i8 %b, 9 49 br i1 %cmp, label %bb, label %exit 50 51bb: 52 %shl = shl i8 %a, %b 53 ret i8 %shl 54 55exit: 56 ret i8 0 57} 58 59define i8 @test3(i8 %a, i8 %b) { 60; CHECK-LABEL: @test3( 61; CHECK-NEXT: entry: 62; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[B:%.*]], 6 63; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 64; CHECK: bb: 65; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[A:%.*]], [[B]] 66; CHECK-NEXT: ret i8 [[SHL]] 67; CHECK: exit: 68; CHECK-NEXT: ret i8 0 69; 70entry: 71 %cmp = icmp ugt i8 %b, 6 72 br i1 %cmp, label %bb, label %exit 73 74bb: 75 %shl = shl i8 %a, %b 76 ret i8 %shl 77 78exit: 79 ret i8 0 80} 81 82define i8 @test4(i8 %a, i8 %b) { 83; CHECK-LABEL: @test4( 84; CHECK-NEXT: entry: 85; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[B:%.*]], 7 86; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 87; CHECK: bb: 88; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i8 [[A:%.*]], [[B]] 89; CHECK-NEXT: ret i8 [[SHL]] 90; CHECK: exit: 91; CHECK-NEXT: ret i8 0 92; 93entry: 94 %cmp = icmp ugt i8 %b, 7 95 br i1 %cmp, label %bb, label %exit 96 97bb: 98 %shl = shl i8 %a, %b 99 ret i8 %shl 100 101exit: 102 ret i8 0 103} 104 105define i8 @test5(i8 %b) { 106; CHECK-LABEL: @test5( 107; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i8 0, [[B:%.*]] 108; CHECK-NEXT: ret i8 0 109; 110 %shl = shl i8 0, %b 111 ret i8 %shl 112} 113 114define i8 @test6(i8 %b) { 115; CHECK-LABEL: @test6( 116; CHECK-NEXT: [[SHL:%.*]] = shl nuw i8 1, [[B:%.*]] 117; CHECK-NEXT: ret i8 [[SHL]] 118; 119 %shl = shl i8 1, %b 120 ret i8 %shl 121} 122 123define i8 @test7(i8 %b) { 124; CHECK-LABEL: @test7( 125; CHECK-NEXT: entry: 126; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 7 127; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 128; CHECK: bb: 129; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i8 1, [[B]] 130; CHECK-NEXT: ret i8 [[SHL]] 131; CHECK: exit: 132; CHECK-NEXT: ret i8 0 133; 134entry: 135 %cmp = icmp ult i8 %b, 7 136 br i1 %cmp, label %bb, label %exit 137 138bb: 139 %shl = shl i8 1, %b 140 ret i8 %shl 141 142exit: 143 ret i8 0 144} 145 146define i8 @test8(i8 %b) { 147; CHECK-LABEL: @test8( 148; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 -1, [[B:%.*]] 149; CHECK-NEXT: ret i8 [[SHL]] 150; 151 %shl = shl i8 -1, %b 152 ret i8 %shl 153} 154 155define i8 @test9(i8 %b) { 156; CHECK-LABEL: @test9( 157; CHECK-NEXT: entry: 158; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[B:%.*]], 0 159; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 160; CHECK: bb: 161; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i8 -1, [[B]] 162; CHECK-NEXT: ret i8 -1 163; CHECK: exit: 164; CHECK-NEXT: ret i8 0 165; 166entry: 167 %cmp = icmp eq i8 %b, 0 168 br i1 %cmp, label %bb, label %exit 169 170bb: 171 %shl = shl i8 -1, %b 172 ret i8 %shl 173 174exit: 175 ret i8 0 176} 177 178define i8 @test10(i8 %b) { 179; CHECK-LABEL: @test10( 180; CHECK-NEXT: [[SHL:%.*]] = shl i8 42, [[B:%.*]] 181; CHECK-NEXT: ret i8 [[SHL]] 182; 183 %shl = shl i8 42, %b 184 ret i8 %shl 185} 186 187define i8 @test11(i8 %b) { 188; CHECK-LABEL: @test11( 189; CHECK-NEXT: entry: 190; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 2 191; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 192; CHECK: bb: 193; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i8 42, [[B]] 194; CHECK-NEXT: ret i8 [[SHL]] 195; CHECK: exit: 196; CHECK-NEXT: ret i8 0 197; 198entry: 199 %cmp = icmp ult i8 %b, 2 200 br i1 %cmp, label %bb, label %exit 201 202bb: 203 %shl = shl i8 42, %b 204 ret i8 %shl 205 206exit: 207 ret i8 0 208} 209 210define i8 @test12(i8 %b) { 211; CHECK-LABEL: @test12( 212; CHECK-NEXT: entry: 213; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 3 214; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 215; CHECK: bb: 216; CHECK-NEXT: [[SHL:%.*]] = shl nuw i8 42, [[B]] 217; CHECK-NEXT: ret i8 [[SHL]] 218; CHECK: exit: 219; CHECK-NEXT: ret i8 0 220; 221entry: 222 %cmp = icmp ult i8 %b, 3 223 br i1 %cmp, label %bb, label %exit 224 225bb: 226 %shl = shl i8 42, %b 227 ret i8 %shl 228 229exit: 230 ret i8 0 231} 232 233define i8 @test13(i8 %b) { 234; CHECK-LABEL: @test13( 235; CHECK-NEXT: entry: 236; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 4 237; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 238; CHECK: bb: 239; CHECK-NEXT: [[SHL:%.*]] = shl i8 42, [[B]] 240; CHECK-NEXT: ret i8 [[SHL]] 241; CHECK: exit: 242; CHECK-NEXT: ret i8 0 243; 244entry: 245 %cmp = icmp ult i8 %b, 4 246 br i1 %cmp, label %bb, label %exit 247 248bb: 249 %shl = shl i8 42, %b 250 ret i8 %shl 251 252exit: 253 ret i8 0 254} 255 256define i8 @test14(i8 %b) { 257; CHECK-LABEL: @test14( 258; CHECK-NEXT: [[SHL:%.*]] = shl i8 -42, [[B:%.*]] 259; CHECK-NEXT: ret i8 [[SHL]] 260; 261 %shl = shl i8 -42, %b 262 ret i8 %shl 263} 264 265define i8 @test15(i8 %b) { 266; CHECK-LABEL: @test15( 267; CHECK-NEXT: entry: 268; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 2 269; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 270; CHECK: bb: 271; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 -42, [[B]] 272; CHECK-NEXT: ret i8 [[SHL]] 273; CHECK: exit: 274; CHECK-NEXT: ret i8 0 275; 276entry: 277 %cmp = icmp ult i8 %b, 2 278 br i1 %cmp, label %bb, label %exit 279 280bb: 281 %shl = shl i8 -42, %b 282 ret i8 %shl 283 284exit: 285 ret i8 0 286} 287 288define i8 @test16(i8 %b) { 289; CHECK-LABEL: @test16( 290; CHECK-NEXT: entry: 291; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[B:%.*]], 3 292; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 293; CHECK: bb: 294; CHECK-NEXT: [[SHL:%.*]] = shl i8 -42, [[B]] 295; CHECK-NEXT: ret i8 [[SHL]] 296; CHECK: exit: 297; CHECK-NEXT: ret i8 0 298; 299entry: 300 %cmp = icmp ult i8 %b, 3 301 br i1 %cmp, label %bb, label %exit 302 303bb: 304 %shl = shl i8 -42, %b 305 ret i8 %shl 306 307exit: 308 ret i8 0 309} 310 311define i8 @test17(i8 %b) { 312; CHECK-LABEL: @test17( 313; CHECK-NEXT: entry: 314; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[B:%.*]], 2 315; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 316; CHECK: bb: 317; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i8 42, [[B]] 318; CHECK-NEXT: ret i8 [[SHL]] 319; CHECK: exit: 320; CHECK-NEXT: ret i8 0 321; 322entry: 323 %cmp = icmp slt i8 %b, 2 324 br i1 %cmp, label %bb, label %exit 325 326bb: 327 %shl = shl i8 42, %b 328 ret i8 %shl 329 330exit: 331 ret i8 0 332} 333 334define i8 @test18(i8 %b) { 335; CHECK-LABEL: @test18( 336; CHECK-NEXT: entry: 337; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[B:%.*]], 3 338; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 339; CHECK: bb: 340; CHECK-NEXT: [[SHL:%.*]] = shl nuw i8 42, [[B]] 341; CHECK-NEXT: ret i8 [[SHL]] 342; CHECK: exit: 343; CHECK-NEXT: ret i8 0 344; 345entry: 346 %cmp = icmp slt i8 %b, 3 347 br i1 %cmp, label %bb, label %exit 348 349bb: 350 %shl = shl i8 42, %b 351 ret i8 %shl 352 353exit: 354 ret i8 0 355} 356 357define i8 @test19(i8 %b) { 358; CHECK-LABEL: @test19( 359; CHECK-NEXT: entry: 360; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[B:%.*]], 4 361; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 362; CHECK: bb: 363; CHECK-NEXT: [[SHL:%.*]] = shl i8 42, [[B]] 364; CHECK-NEXT: ret i8 [[SHL]] 365; CHECK: exit: 366; CHECK-NEXT: ret i8 0 367; 368entry: 369 %cmp = icmp slt i8 %b, 4 370 br i1 %cmp, label %bb, label %exit 371 372bb: 373 %shl = shl i8 42, %b 374 ret i8 %shl 375 376exit: 377 ret i8 0 378} 379 380define i1 @nuw_range1(i8 %b) { 381; CHECK-LABEL: @nuw_range1( 382; CHECK-NEXT: entry: 383; CHECK-NEXT: [[C:%.*]] = add nuw nsw i8 [[B:%.*]], 1 384; CHECK-NEXT: [[SHL:%.*]] = shl nuw i8 [[C]], 2 385; CHECK-NEXT: ret i1 false 386; 387entry: 388 %c = add nuw nsw i8 %b, 1 389 %shl = shl nuw i8 %c, 2 390 %cmp = icmp eq i8 %shl, 0 391 ret i1 %cmp 392} 393 394define i1 @nuw_range2(i8 %b) { 395; CHECK-LABEL: @nuw_range2( 396; CHECK-NEXT: entry: 397; CHECK-NEXT: [[C:%.*]] = add nuw nsw i8 [[B:%.*]], 3 398; CHECK-NEXT: [[SHL:%.*]] = shl nuw i8 [[C]], 2 399; CHECK-NEXT: ret i1 false 400; 401entry: 402 %c = add nuw nsw i8 %b, 3 403 %shl = shl nuw i8 %c, 2 404 %cmp = icmp ult i8 %shl, 2 405 ret i1 %cmp 406} 407 408define i1 @nsw_range1(i8 %b) { 409; CHECK-LABEL: @nsw_range1( 410; CHECK-NEXT: entry: 411; CHECK-NEXT: [[C:%.*]] = add nuw nsw i8 [[B:%.*]], -3 412; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 [[C]], 2 413; CHECK-NEXT: ret i1 false 414; 415entry: 416 %c = add nuw nsw i8 %b, -3 417 %shl = shl nsw i8 %c, 2 418 %cmp = icmp slt i8 %c, %shl 419 ret i1 %cmp 420} 421 422define i64 @shl_nuw_nsw_test1(i32 %x) { 423; CHECK-LABEL: @shl_nuw_nsw_test1( 424; CHECK-NEXT: [[SHL1:%.*]] = shl nuw nsw i32 1, [[X:%.*]] 425; CHECK-NEXT: [[ADD1:%.*]] = add nsw i32 [[SHL1]], -1 426; CHECK-NEXT: [[EXT:%.*]] = zext nneg i32 [[ADD1]] to i64 427; CHECK-NEXT: [[SHL2:%.*]] = shl nuw nsw i64 [[EXT]], 2 428; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i64 [[SHL2]], 39 429; CHECK-NEXT: [[LSHR:%.*]] = lshr i64 [[ADD2]], 3 430; CHECK-NEXT: ret i64 [[LSHR]] 431; 432 %shl1 = shl nuw nsw i32 1, %x 433 %add1 = add nsw i32 %shl1, -1 434 %ext = sext i32 %add1 to i64 435 %shl2 = shl nsw i64 %ext, 2 436 %add2 = add nsw i64 %shl2, 39 437 %lshr = lshr i64 %add2, 3 438 %and = and i64 %lshr, 4294967295 439 ret i64 %and 440} 441 442define i32 @shl_nuw_nsw_test2(i32 range(i32 -2147483248, 1) %x) { 443; CHECK-LABEL: @shl_nuw_nsw_test2( 444; CHECK-NEXT: [[SHL:%.*]] = shl nsw i32 [[X:%.*]], 1 445; CHECK-NEXT: ret i32 200 446; 447 %shl = shl nsw i32 %x, 1 448 %smax = call i32 @llvm.smax.i32(i32 %shl, i32 200) 449 ret i32 %smax 450} 451 452define i64 @shl_nuw_nsw_test3(i1 %cond, i64 range(i64 1, 0) %x, i64 range(i64 3, 0) %y) { 453; CHECK-LABEL: @shl_nuw_nsw_test3( 454; CHECK-NEXT: [[SHL:%.*]] = shl nuw i64 1, [[X:%.*]] 455; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i64 [[Y:%.*]], i64 [[SHL]] 456; CHECK-NEXT: ret i64 [[SEL]] 457; 458 %shl = shl nuw i64 1, %x 459 %sel = select i1 %cond, i64 %y, i64 %shl 460 %umax = call i64 @llvm.umax.i64(i64 %sel, i64 2) 461 ret i64 %umax 462} 463 464define i1 @shl_nuw_nsw_test4(i32 %x, i32 range(i32 0, 32) %k) { 465; CHECK-LABEL: @shl_nuw_nsw_test4( 466; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[X:%.*]] to i64 467; CHECK-NEXT: [[SH_PROM:%.*]] = zext nneg i32 [[K:%.*]] to i64 468; CHECK-NEXT: [[SHL:%.*]] = shl nsw i64 [[CONV]], [[SH_PROM]] 469; CHECK-NEXT: ret i1 false 470; 471 %conv = sext i32 %x to i64 472 %sh_prom = zext nneg i32 %k to i64 473 %shl = shl nsw i64 %conv, %sh_prom 474 %cmp = icmp eq i64 %shl, -9223372036854775808 475 ret i1 %cmp 476} 477 478define i1 @shl_nuw_nsw_test5(i32 %x) { 479; CHECK-LABEL: @shl_nuw_nsw_test5( 480; CHECK-NEXT: entry: 481; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i32 768, [[X:%.*]] 482; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[SHL]], 1846 483; CHECK-NEXT: ret i1 true 484; 485entry: 486 %shl = shl nuw nsw i32 768, %x 487 %add = add nuw i32 %shl, 1846 488 %cmp = icmp sgt i32 %add, 0 489 ret i1 %cmp 490} 491