1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2 ; RUN: opt < %s -instsimplify -S | FileCheck %s 3 4 define <2 x i8> @vsel_tvec(<2 x i8> %x, <2 x i8> %y) { 5 ; CHECK-LABEL: @vsel_tvec( 6 ; CHECK-NEXT: ret <2 x i8> %x 7 ; 8 %s = select <2 x i1><i1 true, i1 true>, <2 x i8> %x, <2 x i8> %y 9 ret <2 x i8> %s 10 } 11 12 define <2 x i8> @vsel_fvec(<2 x i8> %x, <2 x i8> %y) { 13 ; CHECK-LABEL: @vsel_fvec( 14 ; CHECK-NEXT: ret <2 x i8> %y 15 ; 16 %s = select <2 x i1><i1 false, i1 false>, <2 x i8> %x, <2 x i8> %y 17 ret <2 x i8> %s 18 } 19 20 define <2 x i8> @vsel_mixedvec() { 21 ; CHECK-LABEL: @vsel_mixedvec( 22 ; CHECK-NEXT: ret <2 x i8> <i8 0, i8 3> 23 ; 24 %s = select <2 x i1><i1 true, i1 false>, <2 x i8> <i8 0, i8 1>, <2 x i8> <i8 2, i8 3> 25 ret <2 x i8> %s 26 } 27 28 ; FIXME: Allow for undef elements in a constant vector condition. 29 30 define <3 x i8> @vsel_undef_true_op(<3 x i8> %x, <3 x i8> %y) { 31 ; CHECK-LABEL: @vsel_undef_true_op( 32 ; CHECK-NEXT: [[S:%.*]] = select <3 x i1> <i1 true, i1 undef, i1 true>, <3 x i8> [[X:%.*]], <3 x i8> [[Y:%.*]] 33 ; CHECK-NEXT: ret <3 x i8> [[S]] 34 ; 35 %s = select <3 x i1><i1 1, i1 undef, i1 1>, <3 x i8> %x, <3 x i8> %y 36 ret <3 x i8> %s 37 } 38 39 define <3 x i4> @vsel_undef_false_op(<3 x i4> %x, <3 x i4> %y) { 40 ; CHECK-LABEL: @vsel_undef_false_op( 41 ; CHECK-NEXT: [[S:%.*]] = select <3 x i1> <i1 false, i1 undef, i1 undef>, <3 x i4> [[X:%.*]], <3 x i4> [[Y:%.*]] 42 ; CHECK-NEXT: ret <3 x i4> [[S]] 43 ; 44 %s = select <3 x i1><i1 0, i1 undef, i1 undef>, <3 x i4> %x, <3 x i4> %y 45 ret <3 x i4> %s 46 } 47 48 define i32 @test1(i32 %x) { 49 ; CHECK-LABEL: @test1( 50 ; CHECK-NEXT: ret i32 %x 51 ; 52 %and = and i32 %x, 1 53 %cmp = icmp eq i32 %and, 0 54 %and1 = and i32 %x, -2 55 %and1.x = select i1 %cmp, i32 %and1, i32 %x 56 ret i32 %and1.x 57 } 58 59 define i32 @test2(i32 %x) { 60 ; CHECK-LABEL: @test2( 61 ; CHECK-NEXT: ret i32 %x 62 ; 63 %and = and i32 %x, 1 64 %cmp = icmp ne i32 %and, 0 65 %and1 = and i32 %x, -2 66 %and1.x = select i1 %cmp, i32 %x, i32 %and1 67 ret i32 %and1.x 68 } 69 70 define i32 @test3(i32 %x) { 71 ; CHECK-LABEL: @test3( 72 ; CHECK-NEXT: [[AND1:%.*]] = and i32 %x, -2 73 ; CHECK-NEXT: ret i32 [[AND1]] 74 ; 75 %and = and i32 %x, 1 76 %cmp = icmp ne i32 %and, 0 77 %and1 = and i32 %x, -2 78 %and1.x = select i1 %cmp, i32 %and1, i32 %x 79 ret i32 %and1.x 80 } 81 82 define i32 @test4(i32 %X) { 83 ; CHECK-LABEL: @test4( 84 ; CHECK-NEXT: [[OR:%.*]] = or i32 %X, -2147483648 85 ; CHECK-NEXT: ret i32 [[OR]] 86 ; 87 %cmp = icmp slt i32 %X, 0 88 %or = or i32 %X, -2147483648 89 %cond = select i1 %cmp, i32 %X, i32 %or 90 ret i32 %cond 91 } 92 93 ; Same as above, but the compare isn't canonical 94 define i32 @test4noncanon(i32 %X) { 95 ; CHECK-LABEL: @test4noncanon( 96 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], -2147483648 97 ; CHECK-NEXT: ret i32 [[OR]] 98 ; 99 %cmp = icmp sle i32 %X, -1 100 %or = or i32 %X, -2147483648 101 %cond = select i1 %cmp, i32 %X, i32 %or 102 ret i32 %cond 103 } 104 105 define i32 @test5(i32 %X) { 106 ; CHECK-LABEL: @test5( 107 ; CHECK-NEXT: ret i32 %X 108 ; 109 %cmp = icmp slt i32 %X, 0 110 %or = or i32 %X, -2147483648 111 %cond = select i1 %cmp, i32 %or, i32 %X 112 ret i32 %cond 113 } 114 115 define i32 @test6(i32 %X) { 116 ; CHECK-LABEL: @test6( 117 ; CHECK-NEXT: [[AND:%.*]] = and i32 %X, 2147483647 118 ; CHECK-NEXT: ret i32 [[AND]] 119 ; 120 %cmp = icmp slt i32 %X, 0 121 %and = and i32 %X, 2147483647 122 %cond = select i1 %cmp, i32 %and, i32 %X 123 ret i32 %cond 124 } 125 126 define i32 @test7(i32 %X) { 127 ; CHECK-LABEL: @test7( 128 ; CHECK-NEXT: ret i32 %X 129 ; 130 %cmp = icmp slt i32 %X, 0 131 %and = and i32 %X, 2147483647 132 %cond = select i1 %cmp, i32 %X, i32 %and 133 ret i32 %cond 134 } 135 136 define i32 @test8(i32 %X) { 137 ; CHECK-LABEL: @test8( 138 ; CHECK-NEXT: ret i32 %X 139 ; 140 %cmp = icmp sgt i32 %X, -1 141 %or = or i32 %X, -2147483648 142 %cond = select i1 %cmp, i32 %X, i32 %or 143 ret i32 %cond 144 } 145 146 define i32 @test9(i32 %X) { 147 ; CHECK-LABEL: @test9( 148 ; CHECK-NEXT: [[OR:%.*]] = or i32 %X, -2147483648 149 ; CHECK-NEXT: ret i32 [[OR]] 150 ; 151 %cmp = icmp sgt i32 %X, -1 152 %or = or i32 %X, -2147483648 153 %cond = select i1 %cmp, i32 %or, i32 %X 154 ret i32 %cond 155 } 156 157 ; Same as above, but the compare isn't canonical 158 define i32 @test9noncanon(i32 %X) { 159 ; CHECK-LABEL: @test9noncanon( 160 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], -2147483648 161 ; CHECK-NEXT: ret i32 [[OR]] 162 ; 163 %cmp = icmp sge i32 %X, 0 164 %or = or i32 %X, -2147483648 165 %cond = select i1 %cmp, i32 %or, i32 %X 166 ret i32 %cond 167 } 168 169 define i32 @test10(i32 %X) { 170 ; CHECK-LABEL: @test10( 171 ; CHECK-NEXT: ret i32 %X 172 ; 173 %cmp = icmp sgt i32 %X, -1 174 %and = and i32 %X, 2147483647 175 %cond = select i1 %cmp, i32 %and, i32 %X 176 ret i32 %cond 177 } 178 179 define i32 @test11(i32 %X) { 180 ; CHECK-LABEL: @test11( 181 ; CHECK-NEXT: [[AND:%.*]] = and i32 %X, 2147483647 182 ; CHECK-NEXT: ret i32 [[AND]] 183 ; 184 %cmp = icmp sgt i32 %X, -1 185 %and = and i32 %X, 2147483647 186 %cond = select i1 %cmp, i32 %X, i32 %and 187 ret i32 %cond 188 } 189 190 define <2 x i8> @test11vec(<2 x i8> %X) { 191 ; CHECK-LABEL: @test11vec( 192 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> %X, <i8 127, i8 127> 193 ; CHECK-NEXT: ret <2 x i8> [[AND]] 194 ; 195 %cmp = icmp sgt <2 x i8> %X, <i8 -1, i8 -1> 196 %and = and <2 x i8> %X, <i8 127, i8 127> 197 %sel = select <2 x i1> %cmp, <2 x i8> %X, <2 x i8> %and 198 ret <2 x i8> %sel 199 } 200 201 define i32 @test12(i32 %X) { 202 ; CHECK-LABEL: @test12( 203 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3 204 ; CHECK-NEXT: ret i32 [[AND]] 205 ; 206 %cmp = icmp ult i32 %X, 4 207 %and = and i32 %X, 3 208 %cond = select i1 %cmp, i32 %X, i32 %and 209 ret i32 %cond 210 } 211 212 ; Same as above, but the compare isn't canonical 213 define i32 @test12noncanon(i32 %X) { 214 ; CHECK-LABEL: @test12noncanon( 215 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3 216 ; CHECK-NEXT: ret i32 [[AND]] 217 ; 218 %cmp = icmp ule i32 %X, 3 219 %and = and i32 %X, 3 220 %cond = select i1 %cmp, i32 %X, i32 %and 221 ret i32 %cond 222 } 223 224 define i32 @test13(i32 %X) { 225 ; CHECK-LABEL: @test13( 226 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3 227 ; CHECK-NEXT: ret i32 [[AND]] 228 ; 229 %cmp = icmp ugt i32 %X, 3 230 %and = and i32 %X, 3 231 %cond = select i1 %cmp, i32 %and, i32 %X 232 ret i32 %cond 233 } 234 235 ; Same as above, but the compare isn't canonical 236 define i32 @test13noncanon(i32 %X) { 237 ; CHECK-LABEL: @test13noncanon( 238 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3 239 ; CHECK-NEXT: ret i32 [[AND]] 240 ; 241 %cmp = icmp uge i32 %X, 4 242 %and = and i32 %X, 3 243 %cond = select i1 %cmp, i32 %and, i32 %X 244 ret i32 %cond 245 } 246 247 define i32 @select_icmp_and_8_eq_0_or_8(i32 %x) { 248 ; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8( 249 ; CHECK-NEXT: [[OR:%.*]] = or i32 %x, 8 250 ; CHECK-NEXT: ret i32 [[OR]] 251 ; 252 %and = and i32 %x, 8 253 %cmp = icmp eq i32 %and, 0 254 %or = or i32 %x, 8 255 %sel = select i1 %cmp, i32 %or, i32 %x 256 ret i32 %sel 257 } 258 259 define i32 @select_icmp_and_8_eq_0_or_8_alt(i32 %x) { 260 ; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8_alt( 261 ; CHECK-NEXT: [[OR:%.*]] = or i32 %x, 8 262 ; CHECK-NEXT: ret i32 [[OR]] 263 ; 264 %and = and i32 %x, 8 265 %cmp = icmp ne i32 %and, 0 266 %or = or i32 %x, 8 267 %sel = select i1 %cmp, i32 %x, i32 %or 268 ret i32 %sel 269 } 270 271 define i32 @select_icmp_and_8_ne_0_or_8(i32 %x) { 272 ; CHECK-LABEL: @select_icmp_and_8_ne_0_or_8( 273 ; CHECK-NEXT: ret i32 %x 274 ; 275 %and = and i32 %x, 8 276 %cmp = icmp ne i32 %and, 0 277 %or = or i32 %x, 8 278 %sel = select i1 %cmp, i32 %or, i32 %x 279 ret i32 %sel 280 } 281 282 define i32 @select_icmp_and_8_ne_0_or_8_alt(i32 %x) { 283 ; CHECK-LABEL: @select_icmp_and_8_ne_0_or_8_alt( 284 ; CHECK-NEXT: ret i32 %x 285 ; 286 %and = and i32 %x, 8 287 %cmp = icmp eq i32 %and, 0 288 %or = or i32 %x, 8 289 %sel = select i1 %cmp, i32 %x, i32 %or 290 ret i32 %sel 291 } 292 293 define i32 @select_icmp_and_8_eq_0_and_not_8(i32 %x) { 294 ; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8( 295 ; CHECK-NEXT: [[AND1:%.*]] = and i32 %x, -9 296 ; CHECK-NEXT: ret i32 [[AND1]] 297 ; 298 %and = and i32 %x, 8 299 %cmp = icmp eq i32 %and, 0 300 %and1 = and i32 %x, -9 301 %sel = select i1 %cmp, i32 %x, i32 %and1 302 ret i32 %sel 303 } 304 305 define i32 @select_icmp_and_8_eq_0_and_not_8_alt(i32 %x) { 306 ; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8_alt( 307 ; CHECK-NEXT: [[AND1:%.*]] = and i32 %x, -9 308 ; CHECK-NEXT: ret i32 [[AND1]] 309 ; 310 %and = and i32 %x, 8 311 %cmp = icmp ne i32 %and, 0 312 %and1 = and i32 %x, -9 313 %sel = select i1 %cmp, i32 %and1, i32 %x 314 ret i32 %sel 315 } 316 317 define i32 @select_icmp_and_8_ne_0_and_not_8(i32 %x) { 318 ; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8( 319 ; CHECK-NEXT: ret i32 %x 320 ; 321 %and = and i32 %x, 8 322 %cmp = icmp ne i32 %and, 0 323 %and1 = and i32 %x, -9 324 %sel = select i1 %cmp, i32 %x, i32 %and1 325 ret i32 %sel 326 } 327 328 define i32 @select_icmp_and_8_ne_0_and_not_8_alt(i32 %x) { 329 ; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8_alt( 330 ; CHECK-NEXT: ret i32 %x 331 ; 332 %and = and i32 %x, 8 333 %cmp = icmp eq i32 %and, 0 334 %and1 = and i32 %x, -9 335 %sel = select i1 %cmp, i32 %and1, i32 %x 336 ret i32 %sel 337 } 338 339 ; PR28466: https://llvm.org/bugs/show_bug.cgi?id=28466 340 ; Each of the previous 8 patterns has a variant that replaces the 341 ; 'and' with a 'trunc' and the icmp eq/ne with icmp slt/sgt. 342 343 define i32 @select_icmp_trunc_8_ne_0_or_128(i32 %x) { 344 ; CHECK-LABEL: @select_icmp_trunc_8_ne_0_or_128( 345 ; CHECK-NEXT: [[OR:%.*]] = or i32 %x, 128 346 ; CHECK-NEXT: ret i32 [[OR]] 347 ; 348 %trunc = trunc i32 %x to i8 349 %cmp = icmp sgt i8 %trunc, -1 350 %or = or i32 %x, 128 351 %sel = select i1 %cmp, i32 %or, i32 %x 352 ret i32 %sel 353 } 354 355 define i32 @select_icmp_trunc_8_ne_0_or_128_alt(i32 %x) { 356 ; CHECK-LABEL: @select_icmp_trunc_8_ne_0_or_128_alt( 357 ; CHECK-NEXT: [[OR:%.*]] = or i32 %x, 128 358 ; CHECK-NEXT: ret i32 [[OR]] 359 ; 360 %trunc = trunc i32 %x to i8 361 %cmp = icmp slt i8 %trunc, 0 362 %or = or i32 %x, 128 363 %sel = select i1 %cmp, i32 %x, i32 %or 364 ret i32 %sel 365 } 366 367 define i32 @select_icmp_trunc_8_eq_0_or_128(i32 %x) { 368 ; CHECK-LABEL: @select_icmp_trunc_8_eq_0_or_128( 369 ; CHECK-NEXT: ret i32 %x 370 ; 371 %trunc = trunc i32 %x to i8 372 %cmp = icmp slt i8 %trunc, 0 373 %or = or i32 %x, 128 374 %sel = select i1 %cmp, i32 %or, i32 %x 375 ret i32 %sel 376 } 377 378 define i32 @select_icmp_trunc_8_eq_0_or_128_alt(i32 %x) { 379 ; CHECK-LABEL: @select_icmp_trunc_8_eq_0_or_128_alt( 380 ; CHECK-NEXT: ret i32 %x 381 ; 382 %trunc = trunc i32 %x to i8 383 %cmp = icmp sgt i8 %trunc, -1 384 %or = or i32 %x, 128 385 %sel = select i1 %cmp, i32 %x, i32 %or 386 ret i32 %sel 387 } 388 389 define i32 @select_icmp_trunc_8_eq_0_and_not_8(i32 %x) { 390 ; CHECK-LABEL: @select_icmp_trunc_8_eq_0_and_not_8( 391 ; CHECK-NEXT: [[AND:%.*]] = and i32 %x, -9 392 ; CHECK-NEXT: ret i32 [[AND]] 393 ; 394 %trunc = trunc i32 %x to i4 395 %cmp = icmp sgt i4 %trunc, -1 396 %and = and i32 %x, -9 397 %sel = select i1 %cmp, i32 %x, i32 %and 398 ret i32 %sel 399 } 400 401 define i32 @select_icmp_trunc_8_eq_0_and_not_8_alt(i32 %x) { 402 ; CHECK-LABEL: @select_icmp_trunc_8_eq_0_and_not_8_alt( 403 ; CHECK-NEXT: [[AND:%.*]] = and i32 %x, -9 404 ; CHECK-NEXT: ret i32 [[AND]] 405 ; 406 %trunc = trunc i32 %x to i4 407 %cmp = icmp slt i4 %trunc, 0 408 %and = and i32 %x, -9 409 %sel = select i1 %cmp, i32 %and, i32 %x 410 ret i32 %sel 411 } 412 413 define i32 @select_icmp_trunc_8_ne_0_and_not_8(i32 %x) { 414 ; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8( 415 ; CHECK-NEXT: ret i32 %x 416 ; 417 %trunc = trunc i32 %x to i4 418 %cmp = icmp slt i4 %trunc, 0 419 %and = and i32 %x, -9 420 %sel = select i1 %cmp, i32 %x, i32 %and 421 ret i32 %sel 422 } 423 424 define i32 @select_icmp_trunc_8_ne_0_and_not_8_alt(i32 %x) { 425 ; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8_alt( 426 ; CHECK-NEXT: ret i32 %x 427 ; 428 %trunc = trunc i32 %x to i4 429 %cmp = icmp sgt i4 %trunc, -1 430 %and = and i32 %x, -9 431 %sel = select i1 %cmp, i32 %and, i32 %x 432 ret i32 %sel 433 } 434 435 ; Make sure that at least a few of the same patterns are repeated with vector types. 436 437 define <2 x i32> @select_icmp_and_8_ne_0_and_not_8_vec(<2 x i32> %x) { 438 ; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8_vec( 439 ; CHECK-NEXT: ret <2 x i32> %x 440 ; 441 %and = and <2 x i32> %x, <i32 8, i32 8> 442 %cmp = icmp ne <2 x i32> %and, zeroinitializer 443 %and1 = and <2 x i32> %x, <i32 -9, i32 -9> 444 %sel = select <2 x i1> %cmp, <2 x i32> %x, <2 x i32> %and1 445 ret <2 x i32> %sel 446 } 447 448 define <2 x i32> @select_icmp_trunc_8_ne_0_and_not_8_alt_vec(<2 x i32> %x) { 449 ; CHECK-LABEL: @select_icmp_trunc_8_ne_0_and_not_8_alt_vec( 450 ; CHECK-NEXT: ret <2 x i32> %x 451 ; 452 %trunc = trunc <2 x i32> %x to <2 x i4> 453 %cmp = icmp sgt <2 x i4> %trunc, <i4 -1, i4 -1> 454 %and = and <2 x i32> %x, <i32 -9, i32 -9> 455 %sel = select <2 x i1> %cmp, <2 x i32> %and, <2 x i32> %x 456 ret <2 x i32> %sel 457 } 458 459 ; Insert a bit from x into y? This should be possible in InstCombine, but not InstSimplify? 460 461 define i32 @select_icmp_x_and_8_eq_0_y_and_not_8(i32 %x, i32 %y) { 462 ; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y_and_not_8( 463 ; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 8 464 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 465 ; CHECK-NEXT: [[AND1:%.*]] = and i32 %y, -9 466 ; CHECK-NEXT: [[Y_AND1:%.*]] = select i1 [[CMP]], i32 %y, i32 [[AND1]] 467 ; CHECK-NEXT: ret i32 [[Y_AND1]] 468 ; 469 %and = and i32 %x, 8 470 %cmp = icmp eq i32 %and, 0 471 %and1 = and i32 %y, -9 472 %y.and1 = select i1 %cmp, i32 %y, i32 %and1 473 ret i32 %y.and1 474 } 475 476 define i64 @select_icmp_x_and_8_eq_0_y64_and_not_8(i32 %x, i64 %y) { 477 ; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y64_and_not_8( 478 ; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 8 479 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 480 ; CHECK-NEXT: [[AND1:%.*]] = and i64 %y, -9 481 ; CHECK-NEXT: [[Y_AND1:%.*]] = select i1 [[CMP]], i64 %y, i64 [[AND1]] 482 ; CHECK-NEXT: ret i64 [[Y_AND1]] 483 ; 484 %and = and i32 %x, 8 485 %cmp = icmp eq i32 %and, 0 486 %and1 = and i64 %y, -9 487 %y.and1 = select i1 %cmp, i64 %y, i64 %and1 488 ret i64 %y.and1 489 } 490 491 define i64 @select_icmp_x_and_8_ne_0_y64_and_not_8(i32 %x, i64 %y) { 492 ; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y64_and_not_8( 493 ; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 8 494 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 495 ; CHECK-NEXT: [[AND1:%.*]] = and i64 %y, -9 496 ; CHECK-NEXT: [[AND1_Y:%.*]] = select i1 [[CMP]], i64 [[AND1]], i64 %y 497 ; CHECK-NEXT: ret i64 [[AND1_Y]] 498 ; 499 %and = and i32 %x, 8 500 %cmp = icmp eq i32 %and, 0 501 %and1 = and i64 %y, -9 502 %and1.y = select i1 %cmp, i64 %and1, i64 %y 503 ret i64 %and1.y 504 } 505 506 ; Don't crash on a pointer or aggregate type. 507 508 define i32* @select_icmp_pointers(i32* %x, i32* %y) { 509 ; CHECK-LABEL: @select_icmp_pointers( 510 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32* %x, null 511 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32* %x, i32* %y 512 ; CHECK-NEXT: ret i32* [[SEL]] 513 ; 514 %cmp = icmp slt i32* %x, null 515 %sel = select i1 %cmp, i32* %x, i32* %y 516 ret i32* %sel 517 } 518 519 ; If the condition is known, we don't need to select, but we're not 520 ; doing this fold here to avoid compile-time cost. 521 522 declare void @llvm.assume(i1) 523 524 define i8 @assume_sel_cond(i1 %cond, i8 %x, i8 %y) { 525 ; CHECK-LABEL: @assume_sel_cond( 526 ; CHECK-NEXT: call void @llvm.assume(i1 %cond) 527 ; CHECK-NEXT: [[SEL:%.*]] = select i1 %cond, i8 %x, i8 %y 528 ; CHECK-NEXT: ret i8 [[SEL]] 529 ; 530 call void @llvm.assume(i1 %cond) 531 %sel = select i1 %cond, i8 %x, i8 %y 532 ret i8 %sel 533 } 534 535 define i8 @do_not_assume_sel_cond(i1 %cond, i8 %x, i8 %y) { 536 ; CHECK-LABEL: @do_not_assume_sel_cond( 537 ; CHECK-NEXT: [[NOTCOND:%.*]] = icmp eq i1 %cond, false 538 ; CHECK-NEXT: call void @llvm.assume(i1 [[NOTCOND]]) 539 ; CHECK-NEXT: [[SEL:%.*]] = select i1 %cond, i8 %x, i8 %y 540 ; CHECK-NEXT: ret i8 [[SEL]] 541 ; 542 %notcond = icmp eq i1 %cond, false 543 call void @llvm.assume(i1 %notcond) 544 %sel = select i1 %cond, i8 %x, i8 %y 545 ret i8 %sel 546 } 547 548 define i32* @select_icmp_eq_0_gep_operand(i32* %base, i64 %n) { 549 ; CHECK-LABEL: @select_icmp_eq_0_gep_operand( 550 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr 551 ; CHECK-NEXT: ret i32* [[GEP]] 552 %cond = icmp eq i64 %n, 0 553 %gep = getelementptr i32, i32* %base, i64 %n 554 %r = select i1 %cond, i32* %base, i32* %gep 555 ret i32* %r 556 } 557 558 define i32* @select_icmp_ne_0_gep_operand(i32* %base, i64 %n) { 559 ; CHECK-LABEL: @select_icmp_ne_0_gep_operand( 560 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr 561 ; CHECK-NEXT: ret i32* [[GEP]] 562 %cond = icmp ne i64 %n, 0 563 %gep = getelementptr i32, i32* %base, i64 %n 564 %r = select i1 %cond, i32* %gep, i32* %base 565 ret i32* %r 566 } 567