1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instsimplify -S | FileCheck %s 3 4define i32 @test1(i32 %x) { 5; CHECK-LABEL: @test1( 6; CHECK-NEXT: ret i32 %x 7; 8 %and = and i32 %x, 1 9 %cmp = icmp eq i32 %and, 0 10 %and1 = and i32 %x, -2 11 %and1.x = select i1 %cmp, i32 %and1, i32 %x 12 ret i32 %and1.x 13} 14 15define i32 @test2(i32 %x) { 16; CHECK-LABEL: @test2( 17; CHECK-NEXT: ret i32 %x 18; 19 %and = and i32 %x, 1 20 %cmp = icmp ne i32 %and, 0 21 %and1 = and i32 %x, -2 22 %and1.x = select i1 %cmp, i32 %x, i32 %and1 23 ret i32 %and1.x 24} 25 26define i32 @test3(i32 %x) { 27; CHECK-LABEL: @test3( 28; CHECK-NEXT: [[AND1:%.*]] = and i32 %x, -2 29; CHECK-NEXT: ret i32 [[AND1]] 30; 31 %and = and i32 %x, 1 32 %cmp = icmp ne i32 %and, 0 33 %and1 = and i32 %x, -2 34 %and1.x = select i1 %cmp, i32 %and1, i32 %x 35 ret i32 %and1.x 36} 37 38define i32 @test4(i32 %X) { 39; CHECK-LABEL: @test4( 40; CHECK-NEXT: [[OR:%.*]] = or i32 %X, -2147483648 41; CHECK-NEXT: ret i32 [[OR]] 42; 43 %cmp = icmp slt i32 %X, 0 44 %or = or i32 %X, -2147483648 45 %cond = select i1 %cmp, i32 %X, i32 %or 46 ret i32 %cond 47} 48 49define i32 @test5(i32 %X) { 50; CHECK-LABEL: @test5( 51; CHECK-NEXT: ret i32 %X 52; 53 %cmp = icmp slt i32 %X, 0 54 %or = or i32 %X, -2147483648 55 %cond = select i1 %cmp, i32 %or, i32 %X 56 ret i32 %cond 57} 58 59define i32 @test6(i32 %X) { 60; CHECK-LABEL: @test6( 61; CHECK-NEXT: [[AND:%.*]] = and i32 %X, 2147483647 62; CHECK-NEXT: ret i32 [[AND]] 63; 64 %cmp = icmp slt i32 %X, 0 65 %and = and i32 %X, 2147483647 66 %cond = select i1 %cmp, i32 %and, i32 %X 67 ret i32 %cond 68} 69 70define i32 @test7(i32 %X) { 71; CHECK-LABEL: @test7( 72; CHECK-NEXT: ret i32 %X 73; 74 %cmp = icmp slt i32 %X, 0 75 %and = and i32 %X, 2147483647 76 %cond = select i1 %cmp, i32 %X, i32 %and 77 ret i32 %cond 78} 79 80define i32 @test8(i32 %X) { 81; CHECK-LABEL: @test8( 82; CHECK-NEXT: ret i32 %X 83; 84 %cmp = icmp sgt i32 %X, -1 85 %or = or i32 %X, -2147483648 86 %cond = select i1 %cmp, i32 %X, i32 %or 87 ret i32 %cond 88} 89 90define i32 @test9(i32 %X) { 91; CHECK-LABEL: @test9( 92; CHECK-NEXT: [[OR:%.*]] = or i32 %X, -2147483648 93; CHECK-NEXT: ret i32 [[OR]] 94; 95 %cmp = icmp sgt i32 %X, -1 96 %or = or i32 %X, -2147483648 97 %cond = select i1 %cmp, i32 %or, i32 %X 98 ret i32 %cond 99} 100 101define i32 @test10(i32 %X) { 102; CHECK-LABEL: @test10( 103; CHECK-NEXT: ret i32 %X 104; 105 %cmp = icmp sgt i32 %X, -1 106 %and = and i32 %X, 2147483647 107 %cond = select i1 %cmp, i32 %and, i32 %X 108 ret i32 %cond 109} 110 111define i32 @test11(i32 %X) { 112; CHECK-LABEL: @test11( 113; CHECK-NEXT: [[AND:%.*]] = and i32 %X, 2147483647 114; CHECK-NEXT: ret i32 [[AND]] 115; 116 %cmp = icmp sgt i32 %X, -1 117 %and = and i32 %X, 2147483647 118 %cond = select i1 %cmp, i32 %X, i32 %and 119 ret i32 %cond 120} 121 122define <2 x i8> @test11vec(<2 x i8> %X) { 123; CHECK-LABEL: @test11vec( 124; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> %X, <i8 127, i8 127> 125; CHECK-NEXT: ret <2 x i8> [[AND]] 126; 127 %cmp = icmp sgt <2 x i8> %X, <i8 -1, i8 -1> 128 %and = and <2 x i8> %X, <i8 127, i8 127> 129 %sel = select <2 x i1> %cmp, <2 x i8> %X, <2 x i8> %and 130 ret <2 x i8> %sel 131} 132 133define i32 @select_icmp_and_8_eq_0_or_8(i32 %x) { 134; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8( 135; CHECK-NEXT: [[OR:%.*]] = or i32 %x, 8 136; CHECK-NEXT: ret i32 [[OR]] 137; 138 %and = and i32 %x, 8 139 %cmp = icmp eq i32 %and, 0 140 %or = or i32 %x, 8 141 %sel = select i1 %cmp, i32 %or, i32 %x 142 ret i32 %sel 143} 144 145define i32 @select_icmp_and_8_eq_0_or_8_alt(i32 %x) { 146; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8_alt( 147; CHECK-NEXT: [[OR:%.*]] = or i32 %x, 8 148; CHECK-NEXT: ret i32 [[OR]] 149; 150 %and = and i32 %x, 8 151 %cmp = icmp ne i32 %and, 0 152 %or = or i32 %x, 8 153 %sel = select i1 %cmp, i32 %x, i32 %or 154 ret i32 %sel 155} 156 157define i32 @select_icmp_and_8_ne_0_or_8(i32 %x) { 158; CHECK-LABEL: @select_icmp_and_8_ne_0_or_8( 159; CHECK-NEXT: ret i32 %x 160; 161 %and = and i32 %x, 8 162 %cmp = icmp ne i32 %and, 0 163 %or = or i32 %x, 8 164 %sel = select i1 %cmp, i32 %or, i32 %x 165 ret i32 %sel 166} 167 168define i32 @select_icmp_and_8_ne_0_or_8_alt(i32 %x) { 169; CHECK-LABEL: @select_icmp_and_8_ne_0_or_8_alt( 170; CHECK-NEXT: ret i32 %x 171; 172 %and = and i32 %x, 8 173 %cmp = icmp eq i32 %and, 0 174 %or = or i32 %x, 8 175 %sel = select i1 %cmp, i32 %x, i32 %or 176 ret i32 %sel 177} 178 179define i32 @select_icmp_and_8_eq_0_and_not_8(i32 %x) { 180; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8( 181; CHECK-NEXT: [[AND1:%.*]] = and i32 %x, -9 182; CHECK-NEXT: ret i32 [[AND1]] 183; 184 %and = and i32 %x, 8 185 %cmp = icmp eq i32 %and, 0 186 %and1 = and i32 %x, -9 187 %sel = select i1 %cmp, i32 %x, i32 %and1 188 ret i32 %sel 189} 190 191define i32 @select_icmp_and_8_eq_0_and_not_8_alt(i32 %x) { 192; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8_alt( 193; CHECK-NEXT: [[AND1:%.*]] = and i32 %x, -9 194; CHECK-NEXT: ret i32 [[AND1]] 195; 196 %and = and i32 %x, 8 197 %cmp = icmp ne i32 %and, 0 198 %and1 = and i32 %x, -9 199 %sel = select i1 %cmp, i32 %and1, i32 %x 200 ret i32 %sel 201} 202 203define i32 @select_icmp_and_8_ne_0_and_not_8(i32 %x) { 204; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8( 205; CHECK-NEXT: ret i32 %x 206; 207 %and = and i32 %x, 8 208 %cmp = icmp ne i32 %and, 0 209 %and1 = and i32 %x, -9 210 %sel = select i1 %cmp, i32 %x, i32 %and1 211 ret i32 %sel 212} 213 214define i32 @select_icmp_and_8_ne_0_and_not_8_alt(i32 %x) { 215; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8_alt( 216; CHECK-NEXT: ret i32 %x 217; 218 %and = and i32 %x, 8 219 %cmp = icmp eq i32 %and, 0 220 %and1 = and i32 %x, -9 221 %sel = select i1 %cmp, i32 %and1, i32 %x 222 ret i32 %sel 223} 224 225; PR28466: https://llvm.org/bugs/show_bug.cgi?id=28466 226; Each of the previous 8 patterns has a variant that replaces the 227; 'and' with a 'trunc' and the icmp eq/ne with icmp slt/sgt. 228 229define i32 @select_icmp_trunc_8_ne_0_or_128(i32 %x) { 230; CHECK-LABEL: @select_icmp_trunc_8_ne_0_or_128( 231; CHECK-NEXT: [[OR:%.*]] = or i32 %x, 128 232; CHECK-NEXT: ret i32 [[OR]] 233; 234 %trunc = trunc i32 %x to i8 235 %cmp = icmp sgt i8 %trunc, -1 236 %or = or i32 %x, 128 237 %sel = select i1 %cmp, i32 %or, i32 %x 238 ret i32 %sel 239} 240 241define i32 @select_icmp_trunc_8_ne_0_or_128_alt(i32 %x) { 242; CHECK-LABEL: @select_icmp_trunc_8_ne_0_or_128_alt( 243; CHECK-NEXT: [[OR:%.*]] = or i32 %x, 128 244; CHECK-NEXT: ret i32 [[OR]] 245; 246 %trunc = trunc i32 %x to i8 247 %cmp = icmp slt i8 %trunc, 0 248 %or = or i32 %x, 128 249 %sel = select i1 %cmp, i32 %x, i32 %or 250 ret i32 %sel 251} 252 253define i32 @select_icmp_trunc_8_eq_0_or_128(i32 %x) { 254; CHECK-LABEL: @select_icmp_trunc_8_eq_0_or_128( 255; CHECK-NEXT: ret i32 %x 256; 257 %trunc = trunc i32 %x to i8 258 %cmp = icmp slt i8 %trunc, 0 259 %or = or i32 %x, 128 260 %sel = select i1 %cmp, i32 %or, i32 %x 261 ret i32 %sel 262} 263 264define i32 @select_icmp_trunc_8_eq_0_or_128_alt(i32 %x) { 265; CHECK-LABEL: @select_icmp_trunc_8_eq_0_or_128_alt( 266; CHECK-NEXT: ret i32 %x 267; 268 %trunc = trunc i32 %x to i8 269 %cmp = icmp sgt i8 %trunc, -1 270 %or = or i32 %x, 128 271 %sel = select i1 %cmp, i32 %x, i32 %or 272 ret i32 %sel 273} 274 275define i32 @select_icmp_trunc_8_eq_0_and_not_8(i32 %x) { 276; CHECK-LABEL: @select_icmp_trunc_8_eq_0_and_not_8( 277; CHECK-NEXT: [[AND:%.*]] = and i32 %x, -9 278; CHECK-NEXT: ret i32 [[AND]] 279; 280 %trunc = trunc i32 %x to i4 281 %cmp = icmp sgt i4 %trunc, -1 282 %and = and i32 %x, -9 283 %sel = select i1 %cmp, i32 %x, i32 %and 284 ret i32 %sel 285} 286 287define i32 @select_icmp_trunc_8_eq_0_and_not_8_alt(i32 %x) { 288; CHECK-LABEL: @select_icmp_trunc_8_eq_0_and_not_8_alt( 289; CHECK-NEXT: [[AND:%.*]] = and i32 %x, -9 290; CHECK-NEXT: ret i32 [[AND]] 291; 292 %trunc = trunc i32 %x to i4 293 %cmp = icmp slt i4 %trunc, 0 294 %and = and i32 %x, -9 295 %sel = select i1 %cmp, i32 %and, i32 %x 296 ret i32 %sel 297} 298 299define i32 @select_icmp_trunc_8_ne_0_and_not_8(i32 %x) { 300; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8( 301; CHECK-NEXT: ret i32 %x 302; 303 %trunc = trunc i32 %x to i4 304 %cmp = icmp slt i4 %trunc, 0 305 %and = and i32 %x, -9 306 %sel = select i1 %cmp, i32 %x, i32 %and 307 ret i32 %sel 308} 309 310define i32 @select_icmp_trunc_8_ne_0_and_not_8_alt(i32 %x) { 311; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8_alt( 312; CHECK-NEXT: ret i32 %x 313; 314 %trunc = trunc i32 %x to i4 315 %cmp = icmp sgt i4 %trunc, -1 316 %and = and i32 %x, -9 317 %sel = select i1 %cmp, i32 %and, i32 %x 318 ret i32 %sel 319} 320 321; Make sure that at least a few of the same patterns are repeated with vector types. 322 323define <2 x i32> @select_icmp_and_8_ne_0_and_not_8_vec(<2 x i32> %x) { 324; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8_vec( 325; CHECK-NEXT: ret <2 x i32> %x 326; 327 %and = and <2 x i32> %x, <i32 8, i32 8> 328 %cmp = icmp ne <2 x i32> %and, zeroinitializer 329 %and1 = and <2 x i32> %x, <i32 -9, i32 -9> 330 %sel = select <2 x i1> %cmp, <2 x i32> %x, <2 x i32> %and1 331 ret <2 x i32> %sel 332} 333 334define <2 x i32> @select_icmp_trunc_8_ne_0_and_not_8_alt_vec(<2 x i32> %x) { 335; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8_alt_vec( 336; CHECK-NEXT: ret <2 x i32> %x 337; 338 %trunc = trunc <2 x i32> %x to <2 x i4> 339 %cmp = icmp sgt <2 x i4> %trunc, <i4 -1, i4 -1> 340 %and = and <2 x i32> %x, <i32 -9, i32 -9> 341 %sel = select <2 x i1> %cmp, <2 x i32> %and, <2 x i32> %x 342 ret <2 x i32> %sel 343} 344 345; Insert a bit from x into y? This should be possible in InstCombine, but not InstSimplify? 346 347define i32 @select_icmp_x_and_8_eq_0_y_and_not_8(i32 %x, i32 %y) { 348; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y_and_not_8( 349; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 8 350; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 351; CHECK-NEXT: [[AND1:%.*]] = and i32 %y, -9 352; CHECK-NEXT: [[Y_AND1:%.*]] = select i1 [[CMP]], i32 %y, i32 [[AND1]] 353; CHECK-NEXT: ret i32 [[Y_AND1]] 354; 355 %and = and i32 %x, 8 356 %cmp = icmp eq i32 %and, 0 357 %and1 = and i32 %y, -9 358 %y.and1 = select i1 %cmp, i32 %y, i32 %and1 359 ret i32 %y.and1 360} 361 362define i64 @select_icmp_x_and_8_eq_0_y64_and_not_8(i32 %x, i64 %y) { 363; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y64_and_not_8( 364; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 8 365; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 366; CHECK-NEXT: [[AND1:%.*]] = and i64 %y, -9 367; CHECK-NEXT: [[Y_AND1:%.*]] = select i1 [[CMP]], i64 %y, i64 [[AND1]] 368; CHECK-NEXT: ret i64 [[Y_AND1]] 369; 370 %and = and i32 %x, 8 371 %cmp = icmp eq i32 %and, 0 372 %and1 = and i64 %y, -9 373 %y.and1 = select i1 %cmp, i64 %y, i64 %and1 374 ret i64 %y.and1 375} 376 377define i64 @select_icmp_x_and_8_ne_0_y64_and_not_8(i32 %x, i64 %y) { 378; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y64_and_not_8( 379; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 8 380; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 381; CHECK-NEXT: [[AND1:%.*]] = and i64 %y, -9 382; CHECK-NEXT: [[AND1_Y:%.*]] = select i1 [[CMP]], i64 [[AND1]], i64 %y 383; CHECK-NEXT: ret i64 [[AND1_Y]] 384; 385 %and = and i32 %x, 8 386 %cmp = icmp eq i32 %and, 0 387 %and1 = and i64 %y, -9 388 %and1.y = select i1 %cmp, i64 %and1, i64 %y 389 ret i64 %and1.y 390} 391 392; Don't crash on a pointer or aggregate type. 393 394define i32* @select_icmp_pointers(i32* %x, i32* %y) { 395; CHECK-LABEL: @select_icmp_pointers( 396; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32* %x, null 397; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32* %x, i32* %y 398; CHECK-NEXT: ret i32* [[SEL]] 399; 400 %cmp = icmp slt i32* %x, null 401 %sel = select i1 %cmp, i32* %x, i32* %y 402 ret i32* %sel 403} 404 405; FIXME: If the condition is known, we don't need to select. 406 407declare void @llvm.assume(i1) 408 409define i8 @assume_sel_cond(i1 %cond, i8 %x, i8 %y) { 410; CHECK-LABEL: @assume_sel_cond( 411; CHECK-NEXT: call void @llvm.assume(i1 %cond) 412; CHECK-NEXT: [[SEL:%.*]] = select i1 %cond, i8 %x, i8 %y 413; CHECK-NEXT: ret i8 [[SEL]] 414; 415 call void @llvm.assume(i1 %cond) 416 %sel = select i1 %cond, i8 %x, i8 %y 417 ret i8 %sel 418} 419 420define i8 @do_not_assume_sel_cond(i1 %cond, i8 %x, i8 %y) { 421; CHECK-LABEL: @do_not_assume_sel_cond( 422; CHECK-NEXT: [[NOTCOND:%.*]] = icmp eq i1 %cond, false 423; CHECK-NEXT: call void @llvm.assume(i1 [[NOTCOND]]) 424; CHECK-NEXT: [[SEL:%.*]] = select i1 %cond, i8 %x, i8 %y 425; CHECK-NEXT: ret i8 [[SEL]] 426; 427 %notcond = icmp eq i1 %cond, false 428 call void @llvm.assume(i1 %notcond) 429 %sel = select i1 %cond, i8 %x, i8 %y 430 ret i8 %sel 431} 432 433