1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 5 6define i1 @lshr_eq_msb_low_last_zero(i8 %a) { 7; CHECK-LABEL: @lshr_eq_msb_low_last_zero( 8; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 %a, 6 9; CHECK-NEXT: ret i1 [[CMP]] 10; 11 %shr = lshr i8 127, %a 12 %cmp = icmp eq i8 %shr, 0 13 ret i1 %cmp 14} 15 16define <2 x i1> @lshr_eq_msb_low_last_zero_vec(<2 x i8> %a) { 17; CHECK-LABEL: @lshr_eq_msb_low_last_zero_vec( 18; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i8> %a, <i8 6, i8 6> 19; CHECK-NEXT: ret <2 x i1> [[CMP]] 20; 21 %shr = lshr <2 x i8> <i8 127, i8 127>, %a 22 %cmp = icmp eq <2 x i8> %shr, zeroinitializer 23 ret <2 x i1> %cmp 24} 25 26define i1 @ashr_eq_msb_low_second_zero(i8 %a) { 27; CHECK-LABEL: @ashr_eq_msb_low_second_zero( 28; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 %a, 6 29; CHECK-NEXT: ret i1 [[CMP]] 30; 31 %shr = ashr i8 127, %a 32 %cmp = icmp eq i8 %shr, 0 33 ret i1 %cmp 34} 35 36define i1 @lshr_ne_msb_low_last_zero(i8 %a) { 37; CHECK-LABEL: @lshr_ne_msb_low_last_zero( 38; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 %a, 7 39; CHECK-NEXT: ret i1 [[CMP]] 40; 41 %shr = lshr i8 127, %a 42 %cmp = icmp ne i8 %shr, 0 43 ret i1 %cmp 44} 45 46define i1 @ashr_ne_msb_low_second_zero(i8 %a) { 47; CHECK-LABEL: @ashr_ne_msb_low_second_zero( 48; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 %a, 7 49; CHECK-NEXT: ret i1 [[CMP]] 50; 51 %shr = ashr i8 127, %a 52 %cmp = icmp ne i8 %shr, 0 53 ret i1 %cmp 54} 55 56define i1 @ashr_eq_both_equal(i8 %a) { 57; CHECK-LABEL: @ashr_eq_both_equal( 58; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %a, 0 59; CHECK-NEXT: ret i1 [[CMP]] 60; 61 %shr = ashr i8 128, %a 62 %cmp = icmp eq i8 %shr, 128 63 ret i1 %cmp 64} 65 66define i1 @ashr_ne_both_equal(i8 %a) { 67; CHECK-LABEL: @ashr_ne_both_equal( 68; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %a, 0 69; CHECK-NEXT: ret i1 [[CMP]] 70; 71 %shr = ashr i8 128, %a 72 %cmp = icmp ne i8 %shr, 128 73 ret i1 %cmp 74} 75 76define i1 @lshr_eq_both_equal(i8 %a) { 77; CHECK-LABEL: @lshr_eq_both_equal( 78; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %a, 0 79; CHECK-NEXT: ret i1 [[CMP]] 80; 81 %shr = lshr i8 127, %a 82 %cmp = icmp eq i8 %shr, 127 83 ret i1 %cmp 84} 85 86define i1 @lshr_ne_both_equal(i8 %a) { 87; CHECK-LABEL: @lshr_ne_both_equal( 88; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %a, 0 89; CHECK-NEXT: ret i1 [[CMP]] 90; 91 %shr = lshr i8 127, %a 92 %cmp = icmp ne i8 %shr, 127 93 ret i1 %cmp 94} 95 96define i1 @exact_ashr_eq_both_equal(i8 %a) { 97; CHECK-LABEL: @exact_ashr_eq_both_equal( 98; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %a, 0 99; CHECK-NEXT: ret i1 [[CMP]] 100; 101 %shr = ashr exact i8 128, %a 102 %cmp = icmp eq i8 %shr, 128 103 ret i1 %cmp 104} 105 106define i1 @exact_ashr_ne_both_equal(i8 %a) { 107; CHECK-LABEL: @exact_ashr_ne_both_equal( 108; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %a, 0 109; CHECK-NEXT: ret i1 [[CMP]] 110; 111 %shr = ashr exact i8 128, %a 112 %cmp = icmp ne i8 %shr, 128 113 ret i1 %cmp 114} 115 116define i1 @exact_lshr_eq_both_equal(i8 %a) { 117; CHECK-LABEL: @exact_lshr_eq_both_equal( 118; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %a, 0 119; CHECK-NEXT: ret i1 [[CMP]] 120; 121 %shr = lshr exact i8 126, %a 122 %cmp = icmp eq i8 %shr, 126 123 ret i1 %cmp 124} 125 126define i1 @exact_lshr_ne_both_equal(i8 %a) { 127; CHECK-LABEL: @exact_lshr_ne_both_equal( 128; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %a, 0 129; CHECK-NEXT: ret i1 [[CMP]] 130; 131 %shr = lshr exact i8 126, %a 132 %cmp = icmp ne i8 %shr, 126 133 ret i1 %cmp 134} 135 136define i1 @exact_lshr_eq_opposite_msb(i8 %a) { 137; CHECK-LABEL: @exact_lshr_eq_opposite_msb( 138; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %a, 7 139; CHECK-NEXT: ret i1 [[CMP]] 140; 141 %shr = lshr exact i8 -128, %a 142 %cmp = icmp eq i8 %shr, 1 143 ret i1 %cmp 144} 145 146define i1 @lshr_eq_opposite_msb(i8 %a) { 147; CHECK-LABEL: @lshr_eq_opposite_msb( 148; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %a, 7 149; CHECK-NEXT: ret i1 [[CMP]] 150; 151 %shr = lshr i8 -128, %a 152 %cmp = icmp eq i8 %shr, 1 153 ret i1 %cmp 154} 155 156define i1 @exact_lshr_ne_opposite_msb(i8 %a) { 157; CHECK-LABEL: @exact_lshr_ne_opposite_msb( 158; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %a, 7 159; CHECK-NEXT: ret i1 [[CMP]] 160; 161 %shr = lshr exact i8 -128, %a 162 %cmp = icmp ne i8 %shr, 1 163 ret i1 %cmp 164} 165 166define i1 @lshr_ne_opposite_msb(i8 %a) { 167; CHECK-LABEL: @lshr_ne_opposite_msb( 168; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %a, 7 169; CHECK-NEXT: ret i1 [[CMP]] 170; 171 %shr = lshr i8 -128, %a 172 %cmp = icmp ne i8 %shr, 1 173 ret i1 %cmp 174} 175 176define i1 @exact_ashr_eq(i8 %a) { 177; CHECK-LABEL: @exact_ashr_eq( 178; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %a, 7 179; CHECK-NEXT: ret i1 [[CMP]] 180; 181 %shr = ashr exact i8 -128, %a 182 %cmp = icmp eq i8 %shr, -1 183 ret i1 %cmp 184} 185 186define i1 @exact_ashr_ne(i8 %a) { 187; CHECK-LABEL: @exact_ashr_ne( 188; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %a, 7 189; CHECK-NEXT: ret i1 [[CMP]] 190; 191 %shr = ashr exact i8 -128, %a 192 %cmp = icmp ne i8 %shr, -1 193 ret i1 %cmp 194} 195 196define i1 @exact_lshr_eq(i8 %a) { 197; CHECK-LABEL: @exact_lshr_eq( 198; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %a, 2 199; CHECK-NEXT: ret i1 [[CMP]] 200; 201 %shr = lshr exact i8 4, %a 202 %cmp = icmp eq i8 %shr, 1 203 ret i1 %cmp 204} 205 206define i1 @exact_lshr_ne(i8 %a) { 207; CHECK-LABEL: @exact_lshr_ne( 208; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %a, 2 209; CHECK-NEXT: ret i1 [[CMP]] 210; 211 %shr = lshr exact i8 4, %a 212 %cmp = icmp ne i8 %shr, 1 213 ret i1 %cmp 214} 215 216define i1 @nonexact_ashr_eq(i8 %a) { 217; CHECK-LABEL: @nonexact_ashr_eq( 218; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %a, 7 219; CHECK-NEXT: ret i1 [[CMP]] 220; 221 %shr = ashr i8 -128, %a 222 %cmp = icmp eq i8 %shr, -1 223 ret i1 %cmp 224} 225 226define i1 @nonexact_ashr_ne(i8 %a) { 227; CHECK-LABEL: @nonexact_ashr_ne( 228; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %a, 7 229; CHECK-NEXT: ret i1 [[CMP]] 230; 231 %shr = ashr i8 -128, %a 232 %cmp = icmp ne i8 %shr, -1 233 ret i1 %cmp 234} 235 236define i1 @nonexact_lshr_eq(i8 %a) { 237; CHECK-LABEL: @nonexact_lshr_eq( 238; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %a, 2 239; CHECK-NEXT: ret i1 [[CMP]] 240; 241 %shr = lshr i8 4, %a 242 %cmp = icmp eq i8 %shr, 1 243 ret i1 %cmp 244} 245 246define i1 @nonexact_lshr_ne(i8 %a) { 247; CHECK-LABEL: @nonexact_lshr_ne( 248; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %a, 2 249; CHECK-NEXT: ret i1 [[CMP]] 250; 251 %shr = lshr i8 4, %a 252 %cmp = icmp ne i8 %shr, 1 253 ret i1 %cmp 254} 255 256define i1 @exact_lshr_eq_exactdiv(i8 %a) { 257; CHECK-LABEL: @exact_lshr_eq_exactdiv( 258; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %a, 4 259; CHECK-NEXT: ret i1 [[CMP]] 260; 261 %shr = lshr exact i8 80, %a 262 %cmp = icmp eq i8 %shr, 5 263 ret i1 %cmp 264} 265 266define i1 @exact_lshr_ne_exactdiv(i8 %a) { 267; CHECK-LABEL: @exact_lshr_ne_exactdiv( 268; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %a, 4 269; CHECK-NEXT: ret i1 [[CMP]] 270; 271 %shr = lshr exact i8 80, %a 272 %cmp = icmp ne i8 %shr, 5 273 ret i1 %cmp 274} 275 276define i1 @nonexact_lshr_eq_exactdiv(i8 %a) { 277; CHECK-LABEL: @nonexact_lshr_eq_exactdiv( 278; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %a, 4 279; CHECK-NEXT: ret i1 [[CMP]] 280; 281 %shr = lshr i8 80, %a 282 %cmp = icmp eq i8 %shr, 5 283 ret i1 %cmp 284} 285 286define i1 @nonexact_lshr_ne_exactdiv(i8 %a) { 287; CHECK-LABEL: @nonexact_lshr_ne_exactdiv( 288; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %a, 4 289; CHECK-NEXT: ret i1 [[CMP]] 290; 291 %shr = lshr i8 80, %a 292 %cmp = icmp ne i8 %shr, 5 293 ret i1 %cmp 294} 295 296define i1 @exact_ashr_eq_exactdiv(i8 %a) { 297; CHECK-LABEL: @exact_ashr_eq_exactdiv( 298; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %a, 4 299; CHECK-NEXT: ret i1 [[CMP]] 300; 301 %shr = ashr exact i8 -80, %a 302 %cmp = icmp eq i8 %shr, -5 303 ret i1 %cmp 304} 305 306define i1 @exact_ashr_ne_exactdiv(i8 %a) { 307; CHECK-LABEL: @exact_ashr_ne_exactdiv( 308; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %a, 4 309; CHECK-NEXT: ret i1 [[CMP]] 310; 311 %shr = ashr exact i8 -80, %a 312 %cmp = icmp ne i8 %shr, -5 313 ret i1 %cmp 314} 315 316define i1 @nonexact_ashr_eq_exactdiv(i8 %a) { 317; CHECK-LABEL: @nonexact_ashr_eq_exactdiv( 318; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %a, 4 319; CHECK-NEXT: ret i1 [[CMP]] 320; 321 %shr = ashr i8 -80, %a 322 %cmp = icmp eq i8 %shr, -5 323 ret i1 %cmp 324} 325 326define i1 @nonexact_ashr_ne_exactdiv(i8 %a) { 327; CHECK-LABEL: @nonexact_ashr_ne_exactdiv( 328; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %a, 4 329; CHECK-NEXT: ret i1 [[CMP]] 330; 331 %shr = ashr i8 -80, %a 332 %cmp = icmp ne i8 %shr, -5 333 ret i1 %cmp 334} 335 336define i1 @exact_lshr_eq_noexactdiv(i8 %a) { 337; CHECK-LABEL: @exact_lshr_eq_noexactdiv( 338; CHECK-NEXT: ret i1 false 339; 340 %shr = lshr exact i8 80, %a 341 %cmp = icmp eq i8 %shr, 31 342 ret i1 %cmp 343} 344 345define i1 @exact_lshr_ne_noexactdiv(i8 %a) { 346; CHECK-LABEL: @exact_lshr_ne_noexactdiv( 347; CHECK-NEXT: ret i1 true 348; 349 %shr = lshr exact i8 80, %a 350 %cmp = icmp ne i8 %shr, 31 351 ret i1 %cmp 352} 353 354define i1 @nonexact_lshr_eq_noexactdiv(i8 %a) { 355; CHECK-LABEL: @nonexact_lshr_eq_noexactdiv( 356; CHECK-NEXT: ret i1 false 357; 358 %shr = lshr i8 80, %a 359 %cmp = icmp eq i8 %shr, 31 360 ret i1 %cmp 361} 362 363define i1 @nonexact_lshr_ne_noexactdiv(i8 %a) { 364; CHECK-LABEL: @nonexact_lshr_ne_noexactdiv( 365; CHECK-NEXT: ret i1 true 366; 367 %shr = lshr i8 80, %a 368 %cmp = icmp ne i8 %shr, 31 369 ret i1 %cmp 370} 371 372define i1 @exact_ashr_eq_noexactdiv(i8 %a) { 373; CHECK-LABEL: @exact_ashr_eq_noexactdiv( 374; CHECK-NEXT: ret i1 false 375; 376 %shr = ashr exact i8 -80, %a 377 %cmp = icmp eq i8 %shr, -31 378 ret i1 %cmp 379} 380 381define i1 @exact_ashr_ne_noexactdiv(i8 %a) { 382; CHECK-LABEL: @exact_ashr_ne_noexactdiv( 383; CHECK-NEXT: ret i1 true 384; 385 %shr = ashr exact i8 -80, %a 386 %cmp = icmp ne i8 %shr, -31 387 ret i1 %cmp 388} 389 390define i1 @nonexact_ashr_eq_noexactdiv(i8 %a) { 391; CHECK-LABEL: @nonexact_ashr_eq_noexactdiv( 392; CHECK-NEXT: ret i1 false 393; 394 %shr = ashr i8 -80, %a 395 %cmp = icmp eq i8 %shr, -31 396 ret i1 %cmp 397} 398 399define i1 @nonexact_ashr_ne_noexactdiv(i8 %a) { 400; CHECK-LABEL: @nonexact_ashr_ne_noexactdiv( 401; CHECK-NEXT: ret i1 true 402; 403 %shr = ashr i8 -80, %a 404 %cmp = icmp ne i8 %shr, -31 405 ret i1 %cmp 406} 407 408define i1 @nonexact_lshr_eq_noexactlog(i8 %a) { 409; CHECK-LABEL: @nonexact_lshr_eq_noexactlog( 410; CHECK-NEXT: ret i1 false 411; 412 %shr = lshr i8 90, %a 413 %cmp = icmp eq i8 %shr, 30 414 ret i1 %cmp 415} 416 417define i1 @nonexact_lshr_ne_noexactlog(i8 %a) { 418; CHECK-LABEL: @nonexact_lshr_ne_noexactlog( 419; CHECK-NEXT: ret i1 true 420; 421 %shr = lshr i8 90, %a 422 %cmp = icmp ne i8 %shr, 30 423 ret i1 %cmp 424} 425 426define i1 @nonexact_ashr_eq_noexactlog(i8 %a) { 427; CHECK-LABEL: @nonexact_ashr_eq_noexactlog( 428; CHECK-NEXT: ret i1 false 429; 430 %shr = ashr i8 -90, %a 431 %cmp = icmp eq i8 %shr, -30 432 ret i1 %cmp 433} 434 435define i1 @nonexact_ashr_ne_noexactlog(i8 %a) { 436; CHECK-LABEL: @nonexact_ashr_ne_noexactlog( 437; CHECK-NEXT: ret i1 true 438; 439 %shr = ashr i8 -90, %a 440 %cmp = icmp ne i8 %shr, -30 441 ret i1 %cmp 442} 443 444; Don't try to fold the entire body of function @PR20945 into a 445; single `ret i1 true` statement. 446; If %B is equal to 1, then this function would return false. 447; As a consequence, the instruction combiner is not allowed to fold %cmp 448; to 'true'. Instead, it should replace %cmp with a simpler comparison 449; between %B and 1. 450 451define i1 @PR20945(i32 %B) { 452; CHECK-LABEL: @PR20945( 453; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 %B, 1 454; CHECK-NEXT: ret i1 [[CMP]] 455; 456 %shr = ashr i32 -9, %B 457 %cmp = icmp ne i32 %shr, -5 458 ret i1 %cmp 459} 460 461define i1 @PR21222(i32 %B) { 462; CHECK-LABEL: @PR21222( 463; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 %B, 6 464; CHECK-NEXT: ret i1 [[CMP]] 465; 466 %shr = ashr i32 -93, %B 467 %cmp = icmp eq i32 %shr, -2 468 ret i1 %cmp 469} 470 471define i1 @PR24873(i64 %V) { 472; CHECK-LABEL: @PR24873( 473; CHECK-NEXT: [[ICMP:%.*]] = icmp ugt i64 %V, 61 474; CHECK-NEXT: ret i1 [[ICMP]] 475; 476 %ashr = ashr i64 -4611686018427387904, %V 477 %icmp = icmp eq i64 %ashr, -1 478 ret i1 %icmp 479} 480 481declare void @foo(i32) 482 483define i1 @exact_multiuse(i32 %x) { 484; CHECK-LABEL: @exact_multiuse( 485; CHECK-NEXT: [[SH:%.*]] = lshr exact i32 %x, 7 486; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 %x, 131072 487; CHECK-NEXT: call void @foo(i32 [[SH]]) 488; CHECK-NEXT: ret i1 [[CMP]] 489; 490 %sh = lshr exact i32 %x, 7 491 %cmp = icmp eq i32 %sh, 1024 492 call void @foo(i32 %sh) 493 ret i1 %cmp 494} 495 496declare void @foo2(<2 x i32>) 497define <2 x i1> @exact_eq0_multiuse(<2 x i32> %x, <2 x i32> %y) { 498; CHECK-LABEL: @exact_eq0_multiuse( 499; CHECK-NEXT: [[SH:%.*]] = ashr exact <2 x i32> %x, %y 500; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[SH]], zeroinitializer 501; CHECK-NEXT: call void @foo2(<2 x i32> [[SH]]) 502; CHECK-NEXT: ret <2 x i1> [[CMP]] 503; 504 %sh = ashr exact <2 x i32> %x, %y 505 %cmp = icmp eq <2 x i32> %sh, zeroinitializer 506 call void @foo2(<2 x i32> %sh) 507 ret <2 x i1> %cmp 508} 509 510