1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4; PR1822 5 6target datalayout = "e-p:64:64-p1:16:16-p2:32:32:32-p3:64:64:64" 7 8define i1 @test5(i1 %C) { 9; CHECK-LABEL: @test5( 10; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C:%.*]], true 11; CHECK-NEXT: ret i1 [[NOT_C]] 12; 13 %V = select i1 %C, i1 false, i1 true 14 ret i1 %V 15} 16 17define i32 @test6(i1 %C) { 18; CHECK-LABEL: @test6( 19; CHECK-NEXT: [[V:%.*]] = zext i1 [[C:%.*]] to i32 20; CHECK-NEXT: ret i32 [[V]] 21; 22 %V = select i1 %C, i32 1, i32 0 23 ret i32 %V 24} 25 26define i1 @trueval_is_true(i1 %C, i1 %X) { 27; CHECK-LABEL: @trueval_is_true( 28; CHECK-NEXT: [[R:%.*]] = or i1 [[C:%.*]], [[X:%.*]] 29; CHECK-NEXT: ret i1 [[R]] 30; 31 %R = select i1 %C, i1 true, i1 %X 32 ret i1 %R 33} 34 35define <2 x i1> @trueval_is_true_vec(<2 x i1> %C, <2 x i1> %X) { 36; CHECK-LABEL: @trueval_is_true_vec( 37; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[C:%.*]], [[X:%.*]] 38; CHECK-NEXT: ret <2 x i1> [[R]] 39; 40 %R = select <2 x i1> %C, <2 x i1> <i1 true, i1 true>, <2 x i1> %X 41 ret <2 x i1> %R 42} 43 44define <2 x i1> @trueval_is_true_vec_undef_elt(<2 x i1> %C, <2 x i1> %X) { 45; CHECK-LABEL: @trueval_is_true_vec_undef_elt( 46; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[C:%.*]], [[X:%.*]] 47; CHECK-NEXT: ret <2 x i1> [[R]] 48; 49 %R = select <2 x i1> %C, <2 x i1> <i1 undef, i1 true>, <2 x i1> %X 50 ret <2 x i1> %R 51} 52 53define i1 @test8(i1 %C, i1 %X) { 54; CHECK-LABEL: @test8( 55; CHECK-NEXT: [[R:%.*]] = and i1 [[C:%.*]], [[X:%.*]] 56; CHECK-NEXT: ret i1 [[R]] 57; 58 %R = select i1 %C, i1 %X, i1 false 59 ret i1 %R 60} 61 62define <2 x i1> @test8vec(<2 x i1> %C, <2 x i1> %X) { 63; CHECK-LABEL: @test8vec( 64; CHECK-NEXT: [[R:%.*]] = and <2 x i1> [[C:%.*]], [[X:%.*]] 65; CHECK-NEXT: ret <2 x i1> [[R]] 66; 67 %R = select <2 x i1> %C, <2 x i1> %X, <2 x i1> <i1 false, i1 false> 68 ret <2 x i1> %R 69} 70 71define <vscale x 2 x i1> @test8vvec(<vscale x 2 x i1> %C, <vscale x 2 x i1> %X) { 72; CHECK-LABEL: @test8vvec( 73; CHECK-NEXT: [[R:%.*]] = and <vscale x 2 x i1> [[C:%.*]], [[X:%.*]] 74; CHECK-NEXT: ret <vscale x 2 x i1> [[R]] 75; 76 %R = select <vscale x 2 x i1> %C, <vscale x 2 x i1> %X, <vscale x 2 x i1> zeroinitializer 77 ret <vscale x 2 x i1> %R 78} 79 80define i1 @test9(i1 %C, i1 %X) { 81; CHECK-LABEL: @test9( 82; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C:%.*]], true 83; CHECK-NEXT: [[R:%.*]] = and i1 [[NOT_C]], [[X:%.*]] 84; CHECK-NEXT: ret i1 [[R]] 85; 86 %R = select i1 %C, i1 false, i1 %X 87 ret i1 %R 88} 89 90define <2 x i1> @test9vec(<2 x i1> %C, <2 x i1> %X) { 91; CHECK-LABEL: @test9vec( 92; CHECK-NEXT: [[NOT_C:%.*]] = xor <2 x i1> [[C:%.*]], <i1 true, i1 true> 93; CHECK-NEXT: [[R:%.*]] = and <2 x i1> [[NOT_C]], [[X:%.*]] 94; CHECK-NEXT: ret <2 x i1> [[R]] 95; 96 %R = select <2 x i1> %C, <2 x i1> <i1 false, i1 false>, <2 x i1> %X 97 ret <2 x i1> %R 98} 99 100define <vscale x 2 x i1> @test9vvec(<vscale x 2 x i1> %C, <vscale x 2 x i1> %X) { 101; CHECK-LABEL: @test9vvec( 102; CHECK-NEXT: [[NOT_C:%.*]] = xor <vscale x 2 x i1> [[C:%.*]], shufflevector (<vscale x 2 x i1> insertelement (<vscale x 2 x i1> undef, i1 true, i32 0), <vscale x 2 x i1> undef, <vscale x 2 x i32> zeroinitializer) 103; CHECK-NEXT: [[R:%.*]] = and <vscale x 2 x i1> [[NOT_C]], [[X:%.*]] 104; CHECK-NEXT: ret <vscale x 2 x i1> [[R]] 105; 106 %R = select <vscale x 2 x i1> %C, <vscale x 2 x i1> zeroinitializer, <vscale x 2 x i1> %X 107 ret <vscale x 2 x i1> %R 108} 109 110define i1 @test10(i1 %C, i1 %X) { 111; CHECK-LABEL: @test10( 112; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C:%.*]], true 113; CHECK-NEXT: [[R:%.*]] = or i1 [[NOT_C]], [[X:%.*]] 114; CHECK-NEXT: ret i1 [[R]] 115; 116 %R = select i1 %C, i1 %X, i1 true 117 ret i1 %R 118} 119 120define <2 x i1> @test10vec(<2 x i1> %C, <2 x i1> %X) { 121; CHECK-LABEL: @test10vec( 122; CHECK-NEXT: [[NOT_C:%.*]] = xor <2 x i1> [[C:%.*]], <i1 true, i1 true> 123; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[NOT_C]], [[X:%.*]] 124; CHECK-NEXT: ret <2 x i1> [[R]] 125; 126 %R = select <2 x i1> %C, <2 x i1> %X, <2 x i1> <i1 true, i1 true> 127 ret <2 x i1> %R 128} 129 130define i1 @test23(i1 %a, i1 %b) { 131; CHECK-LABEL: @test23( 132; CHECK-NEXT: [[C:%.*]] = and i1 [[A:%.*]], [[B:%.*]] 133; CHECK-NEXT: ret i1 [[C]] 134; 135 %c = select i1 %a, i1 %b, i1 %a 136 ret i1 %c 137} 138 139define <2 x i1> @test23vec(<2 x i1> %a, <2 x i1> %b) { 140; CHECK-LABEL: @test23vec( 141; CHECK-NEXT: [[C:%.*]] = and <2 x i1> [[A:%.*]], [[B:%.*]] 142; CHECK-NEXT: ret <2 x i1> [[C]] 143; 144 %c = select <2 x i1> %a, <2 x i1> %b, <2 x i1> %a 145 ret <2 x i1> %c 146} 147 148define i1 @test24(i1 %a, i1 %b) { 149; CHECK-LABEL: @test24( 150; CHECK-NEXT: [[C:%.*]] = or i1 [[A:%.*]], [[B:%.*]] 151; CHECK-NEXT: ret i1 [[C]] 152; 153 %c = select i1 %a, i1 %a, i1 %b 154 ret i1 %c 155} 156 157define <2 x i1> @test24vec(<2 x i1> %a, <2 x i1> %b) { 158; CHECK-LABEL: @test24vec( 159; CHECK-NEXT: [[C:%.*]] = or <2 x i1> [[A:%.*]], [[B:%.*]] 160; CHECK-NEXT: ret <2 x i1> [[C]] 161; 162 %c = select <2 x i1> %a, <2 x i1> %a, <2 x i1> %b 163 ret <2 x i1> %c 164} 165 166define i1 @test62(i1 %A, i1 %B) { 167; CHECK-LABEL: @test62( 168; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[A:%.*]], true 169; CHECK-NEXT: [[C:%.*]] = and i1 [[NOT]], [[B:%.*]] 170; CHECK-NEXT: ret i1 [[C]] 171; 172 %not = xor i1 %A, true 173 %C = select i1 %A, i1 %not, i1 %B 174 ret i1 %C 175} 176 177define <2 x i1> @test62vec(<2 x i1> %A, <2 x i1> %B) { 178; CHECK-LABEL: @test62vec( 179; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i1> [[A:%.*]], <i1 true, i1 true> 180; CHECK-NEXT: [[C:%.*]] = and <2 x i1> [[NOT]], [[B:%.*]] 181; CHECK-NEXT: ret <2 x i1> [[C]] 182; 183 %not = xor <2 x i1> %A, <i1 true, i1 true> 184 %C = select <2 x i1> %A, <2 x i1> %not, <2 x i1> %B 185 ret <2 x i1> %C 186} 187 188define i1 @test63(i1 %A, i1 %B) { 189; CHECK-LABEL: @test63( 190; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[A:%.*]], true 191; CHECK-NEXT: [[C:%.*]] = or i1 [[NOT]], [[B:%.*]] 192; CHECK-NEXT: ret i1 [[C]] 193; 194 %not = xor i1 %A, true 195 %C = select i1 %A, i1 %B, i1 %not 196 ret i1 %C 197} 198 199define <2 x i1> @test63vec(<2 x i1> %A, <2 x i1> %B) { 200; CHECK-LABEL: @test63vec( 201; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i1> [[A:%.*]], <i1 true, i1 true> 202; CHECK-NEXT: [[C:%.*]] = or <2 x i1> [[NOT]], [[B:%.*]] 203; CHECK-NEXT: ret <2 x i1> [[C]] 204; 205 %not = xor <2 x i1> %A, <i1 true, i1 true> 206 %C = select <2 x i1> %A, <2 x i1> %B, <2 x i1> %not 207 ret <2 x i1> %C 208} 209 210define i32 @test11(i32 %a) { 211; CHECK-LABEL: @test11( 212; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A:%.*]], 0 213; CHECK-NEXT: [[R:%.*]] = zext i1 [[C]] to i32 214; CHECK-NEXT: ret i32 [[R]] 215; 216 %C = icmp eq i32 %a, 0 217 %R = select i1 %C, i32 0, i32 1 218 ret i32 %R 219} 220 221define i32 @test12(i1 %cond, i32 %a) { 222; CHECK-LABEL: @test12( 223; CHECK-NEXT: [[B:%.*]] = zext i1 [[COND:%.*]] to i32 224; CHECK-NEXT: [[C:%.*]] = or i32 [[B]], [[A:%.*]] 225; CHECK-NEXT: ret i32 [[C]] 226; 227 %b = or i32 %a, 1 228 %c = select i1 %cond, i32 %b, i32 %a 229 ret i32 %c 230} 231 232define <2 x i32> @test12vec(<2 x i1> %cond, <2 x i32> %a) { 233; CHECK-LABEL: @test12vec( 234; CHECK-NEXT: [[B:%.*]] = zext <2 x i1> [[COND:%.*]] to <2 x i32> 235; CHECK-NEXT: [[C:%.*]] = or <2 x i32> [[B]], [[A:%.*]] 236; CHECK-NEXT: ret <2 x i32> [[C]] 237; 238 %b = or <2 x i32> %a, <i32 1, i32 1> 239 %c = select <2 x i1> %cond, <2 x i32> %b, <2 x i32> %a 240 ret <2 x i32> %c 241} 242 243define i32 @test12a(i1 %cond, i32 %a) { 244; CHECK-LABEL: @test12a( 245; CHECK-NEXT: [[B:%.*]] = zext i1 [[COND:%.*]] to i32 246; CHECK-NEXT: [[C:%.*]] = ashr i32 [[A:%.*]], [[B]] 247; CHECK-NEXT: ret i32 [[C]] 248; 249 %b = ashr i32 %a, 1 250 %c = select i1 %cond, i32 %b, i32 %a 251 ret i32 %c 252} 253 254define <2 x i32> @test12avec(<2 x i1> %cond, <2 x i32> %a) { 255; CHECK-LABEL: @test12avec( 256; CHECK-NEXT: [[B:%.*]] = zext <2 x i1> [[COND:%.*]] to <2 x i32> 257; CHECK-NEXT: [[C:%.*]] = ashr <2 x i32> [[A:%.*]], [[B]] 258; CHECK-NEXT: ret <2 x i32> [[C]] 259; 260 %b = ashr <2 x i32> %a, <i32 1, i32 1> 261 %c = select <2 x i1> %cond, <2 x i32> %b, <2 x i32> %a 262 ret <2 x i32> %c 263} 264 265define i32 @test12b(i1 %cond, i32 %a) { 266; CHECK-LABEL: @test12b( 267; CHECK-NEXT: [[NOT_COND:%.*]] = xor i1 [[COND:%.*]], true 268; CHECK-NEXT: [[B:%.*]] = zext i1 [[NOT_COND]] to i32 269; CHECK-NEXT: [[D:%.*]] = ashr i32 [[A:%.*]], [[B]] 270; CHECK-NEXT: ret i32 [[D]] 271; 272 %b = ashr i32 %a, 1 273 %d = select i1 %cond, i32 %a, i32 %b 274 ret i32 %d 275} 276 277define <2 x i32> @test12bvec(<2 x i1> %cond, <2 x i32> %a) { 278; CHECK-LABEL: @test12bvec( 279; CHECK-NEXT: [[NOT_COND:%.*]] = xor <2 x i1> [[COND:%.*]], <i1 true, i1 true> 280; CHECK-NEXT: [[B:%.*]] = zext <2 x i1> [[NOT_COND]] to <2 x i32> 281; CHECK-NEXT: [[D:%.*]] = ashr <2 x i32> [[A:%.*]], [[B]] 282; CHECK-NEXT: ret <2 x i32> [[D]] 283; 284 %b = ashr <2 x i32> %a, <i32 1, i32 1> 285 %d = select <2 x i1> %cond, <2 x i32> %a, <2 x i32> %b 286 ret <2 x i32> %d 287} 288 289define i32 @test13(i32 %a, i32 %b) { 290; CHECK-LABEL: @test13( 291; CHECK-NEXT: ret i32 [[B:%.*]] 292; 293 %C = icmp eq i32 %a, %b 294 %V = select i1 %C, i32 %a, i32 %b 295 ret i32 %V 296} 297 298define i32 @test13a(i32 %a, i32 %b) { 299; CHECK-LABEL: @test13a( 300; CHECK-NEXT: ret i32 [[A:%.*]] 301; 302 %C = icmp ne i32 %a, %b 303 %V = select i1 %C, i32 %a, i32 %b 304 ret i32 %V 305} 306 307define i32 @test13b(i32 %a, i32 %b) { 308; CHECK-LABEL: @test13b( 309; CHECK-NEXT: ret i32 [[A:%.*]] 310; 311 %C = icmp eq i32 %a, %b 312 %V = select i1 %C, i32 %b, i32 %a 313 ret i32 %V 314} 315 316define i1 @test14a(i1 %C, i32 %X) { 317; CHECK-LABEL: @test14a( 318; CHECK-NEXT: [[R1:%.*]] = icmp slt i32 [[X:%.*]], 1 319; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C:%.*]], true 320; CHECK-NEXT: [[R:%.*]] = or i1 [[R1]], [[NOT_C]] 321; CHECK-NEXT: ret i1 [[R]] 322; 323 %V = select i1 %C, i32 %X, i32 0 324 ; (X < 1) | !C 325 %R = icmp slt i32 %V, 1 326 ret i1 %R 327} 328 329define i1 @test14b(i1 %C, i32 %X) { 330; CHECK-LABEL: @test14b( 331; CHECK-NEXT: [[R1:%.*]] = icmp slt i32 [[X:%.*]], 1 332; CHECK-NEXT: [[R:%.*]] = or i1 [[R1]], [[C:%.*]] 333; CHECK-NEXT: ret i1 [[R]] 334; 335 %V = select i1 %C, i32 0, i32 %X 336 ; (X < 1) | C 337 %R = icmp slt i32 %V, 1 338 ret i1 %R 339} 340 341define i32 @test16(i1 %C, i32* %P) { 342; CHECK-LABEL: @test16( 343; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[P:%.*]], align 4 344; CHECK-NEXT: ret i32 [[V]] 345; 346 %P2 = select i1 %C, i32* %P, i32* null 347 %V = load i32, i32* %P2 348 ret i32 %V 349} 350 351;; It may be legal to load from a null address in a non-zero address space 352define i32 @test16_neg(i1 %C, i32 addrspace(1)* %P) { 353; CHECK-LABEL: @test16_neg( 354; CHECK-NEXT: [[P2:%.*]] = select i1 [[C:%.*]], i32 addrspace(1)* [[P:%.*]], i32 addrspace(1)* null 355; CHECK-NEXT: [[V:%.*]] = load i32, i32 addrspace(1)* [[P2]], align 4 356; CHECK-NEXT: ret i32 [[V]] 357; 358 %P2 = select i1 %C, i32 addrspace(1)* %P, i32 addrspace(1)* null 359 %V = load i32, i32 addrspace(1)* %P2 360 ret i32 %V 361} 362 363define i32 @test16_neg2(i1 %C, i32 addrspace(1)* %P) { 364; CHECK-LABEL: @test16_neg2( 365; CHECK-NEXT: [[P2:%.*]] = select i1 [[C:%.*]], i32 addrspace(1)* null, i32 addrspace(1)* [[P:%.*]] 366; CHECK-NEXT: [[V:%.*]] = load i32, i32 addrspace(1)* [[P2]], align 4 367; CHECK-NEXT: ret i32 [[V]] 368; 369 %P2 = select i1 %C, i32 addrspace(1)* null, i32 addrspace(1)* %P 370 %V = load i32, i32 addrspace(1)* %P2 371 ret i32 %V 372} 373 374;; It may be legal to load from a null address with null pointer valid attribute. 375define i32 @test16_no_null_opt(i1 %C, i32* %P) #0 { 376; CHECK-LABEL: @test16_no_null_opt( 377; CHECK-NEXT: [[P2:%.*]] = select i1 [[C:%.*]], i32* [[P:%.*]], i32* null 378; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[P2]], align 4 379; CHECK-NEXT: ret i32 [[V]] 380; 381 %P2 = select i1 %C, i32* %P, i32* null 382 %V = load i32, i32* %P2 383 ret i32 %V 384} 385 386define i32 @test16_no_null_opt_2(i1 %C, i32* %P) #0 { 387; CHECK-LABEL: @test16_no_null_opt_2( 388; CHECK-NEXT: [[P2:%.*]] = select i1 [[C:%.*]], i32* null, i32* [[P:%.*]] 389; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[P2]], align 4 390; CHECK-NEXT: ret i32 [[V]] 391; 392 %P2 = select i1 %C, i32* null, i32* %P 393 %V = load i32, i32* %P2 394 ret i32 %V 395} 396 397attributes #0 = { null_pointer_is_valid } 398 399define i1 @test17(i32* %X, i1 %C) { 400; CHECK-LABEL: @test17( 401; CHECK-NEXT: [[RV1:%.*]] = icmp eq i32* [[X:%.*]], null 402; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C:%.*]], true 403; CHECK-NEXT: [[RV:%.*]] = or i1 [[RV1]], [[NOT_C]] 404; CHECK-NEXT: ret i1 [[RV]] 405; 406 %R = select i1 %C, i32* %X, i32* null 407 %RV = icmp eq i32* %R, null 408 ret i1 %RV 409} 410 411define i32 @test18(i32 %X, i32 %Y, i1 %C) { 412; CHECK-LABEL: @test18( 413; CHECK-NEXT: [[V:%.*]] = sdiv i32 [[Y:%.*]], [[X:%.*]] 414; CHECK-NEXT: ret i32 [[V]] 415; 416 %R = select i1 %C, i32 %X, i32 0 417 %V = sdiv i32 %Y, %R 418 ret i32 %V 419} 420 421define i32 @test19(i32 %x) { 422; CHECK-LABEL: @test19( 423; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31 424; CHECK-NEXT: ret i32 [[X_LOBIT]] 425; 426 %tmp = icmp ugt i32 %x, 2147483647 427 %retval = select i1 %tmp, i32 -1, i32 0 428 ret i32 %retval 429} 430 431define i32 @test20(i32 %x) { 432; CHECK-LABEL: @test20( 433; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31 434; CHECK-NEXT: ret i32 [[X_LOBIT]] 435; 436 %tmp = icmp slt i32 %x, 0 437 %retval = select i1 %tmp, i32 -1, i32 0 438 ret i32 %retval 439} 440 441define i64 @test21(i32 %x) { 442; CHECK-LABEL: @test21( 443; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31 444; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[X_LOBIT]] to i64 445; CHECK-NEXT: ret i64 [[TMP1]] 446; 447 %tmp = icmp slt i32 %x, 0 448 %retval = select i1 %tmp, i64 -1, i64 0 449 ret i64 %retval 450} 451 452define i16 @test22(i32 %x) { 453; CHECK-LABEL: @test22( 454; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31 455; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X_LOBIT]] to i16 456; CHECK-NEXT: ret i16 [[TMP1]] 457; 458 %tmp = icmp slt i32 %x, 0 459 %retval = select i1 %tmp, i16 -1, i16 0 460 ret i16 %retval 461} 462 463define i32 @test25(i1 %c) { 464; CHECK-LABEL: @test25( 465; CHECK-NEXT: entry: 466; CHECK-NEXT: br i1 [[C:%.*]], label [[JUMP:%.*]], label [[RET:%.*]] 467; CHECK: jump: 468; CHECK-NEXT: br label [[RET]] 469; CHECK: ret: 470; CHECK-NEXT: [[B:%.*]] = phi i32 [ 10, [[JUMP]] ], [ 20, [[ENTRY:%.*]] ] 471; CHECK-NEXT: ret i32 [[B]] 472; 473entry: 474 br i1 %c, label %jump, label %ret 475jump: 476 br label %ret 477ret: 478 %a = phi i1 [true, %jump], [false, %entry] 479 %b = select i1 %a, i32 10, i32 20 480 ret i32 %b 481} 482 483define i32 @test26(i1 %cond) { 484; CHECK-LABEL: @test26( 485; CHECK-NEXT: entry: 486; CHECK-NEXT: br i1 [[COND:%.*]], label [[JUMP:%.*]], label [[RET:%.*]] 487; CHECK: jump: 488; CHECK-NEXT: br label [[RET]] 489; CHECK: ret: 490; CHECK-NEXT: [[B:%.*]] = phi i32 [ 10, [[JUMP]] ], [ 20, [[ENTRY:%.*]] ] 491; CHECK-NEXT: ret i32 [[B]] 492; 493entry: 494 br i1 %cond, label %jump, label %ret 495jump: 496 %c = or i1 false, false 497 br label %ret 498ret: 499 %a = phi i1 [true, %entry], [%c, %jump] 500 %b = select i1 %a, i32 20, i32 10 501 ret i32 %b 502} 503 504define i32 @test26_logical(i1 %cond) { 505; CHECK-LABEL: @test26_logical( 506; CHECK-NEXT: entry: 507; CHECK-NEXT: br i1 [[COND:%.*]], label [[JUMP:%.*]], label [[RET:%.*]] 508; CHECK: jump: 509; CHECK-NEXT: br label [[RET]] 510; CHECK: ret: 511; CHECK-NEXT: [[B:%.*]] = phi i32 [ 10, [[JUMP]] ], [ 20, [[ENTRY:%.*]] ] 512; CHECK-NEXT: ret i32 [[B]] 513; 514entry: 515 br i1 %cond, label %jump, label %ret 516jump: 517 %c = select i1 false, i1 true, i1 false 518 br label %ret 519ret: 520 %a = phi i1 [true, %entry], [%c, %jump] 521 %b = select i1 %a, i32 20, i32 10 522 ret i32 %b 523} 524 525define i32 @test27(i1 %c, i32 %A, i32 %B) { 526; CHECK-LABEL: @test27( 527; CHECK-NEXT: entry: 528; CHECK-NEXT: br i1 [[C:%.*]], label [[JUMP:%.*]], label [[RET:%.*]] 529; CHECK: jump: 530; CHECK-NEXT: br label [[RET]] 531; CHECK: ret: 532; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[A:%.*]], [[JUMP]] ], [ [[B:%.*]], [[ENTRY:%.*]] ] 533; CHECK-NEXT: ret i32 [[S]] 534; 535entry: 536 br i1 %c, label %jump, label %ret 537jump: 538 br label %ret 539ret: 540 %p = phi i1 [true, %jump], [false, %entry] 541 %s = select i1 %p, i32 %A, i32 %B 542 ret i32 %s 543} 544 545define i32 @test28(i1 %cond, i32 %A, i32 %B) { 546; CHECK-LABEL: @test28( 547; CHECK-NEXT: entry: 548; CHECK-NEXT: br i1 [[COND:%.*]], label [[JUMP:%.*]], label [[RET:%.*]] 549; CHECK: jump: 550; CHECK-NEXT: br label [[RET]] 551; CHECK: ret: 552; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[A:%.*]], [[JUMP]] ], [ [[B:%.*]], [[ENTRY:%.*]] ] 553; CHECK-NEXT: ret i32 [[S]] 554; 555entry: 556 br i1 %cond, label %jump, label %ret 557jump: 558 br label %ret 559ret: 560 %c = phi i32 [%A, %jump], [%B, %entry] 561 %p = phi i1 [true, %jump], [false, %entry] 562 %s = select i1 %p, i32 %A, i32 %c 563 ret i32 %s 564} 565 566define i32 @test29(i1 %cond, i32 %A, i32 %B) { 567; CHECK-LABEL: @test29( 568; CHECK-NEXT: entry: 569; CHECK-NEXT: br i1 [[COND:%.*]], label [[JUMP:%.*]], label [[RET:%.*]] 570; CHECK: jump: 571; CHECK-NEXT: br label [[RET]] 572; CHECK: ret: 573; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[A:%.*]], [[JUMP]] ], [ [[B:%.*]], [[ENTRY:%.*]] ] 574; CHECK-NEXT: br label [[NEXT:%.*]] 575; CHECK: next: 576; CHECK-NEXT: ret i32 [[S]] 577; 578entry: 579 br i1 %cond, label %jump, label %ret 580jump: 581 br label %ret 582ret: 583 %c = phi i32 [%A, %jump], [%B, %entry] 584 %p = phi i1 [true, %jump], [false, %entry] 585 br label %next 586 587next: 588 %s = select i1 %p, i32 %A, i32 %c 589 ret i32 %s 590} 591 592; SMAX(SMAX(x, y), x) -> SMAX(x, y) 593define i32 @test30(i32 %x, i32 %y) { 594; CHECK-LABEL: @test30( 595; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]] 596; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[Y]] 597; CHECK-NEXT: ret i32 [[COND]] 598; 599 %cmp = icmp sgt i32 %x, %y 600 %cond = select i1 %cmp, i32 %x, i32 %y 601 %cmp5 = icmp sgt i32 %cond, %x 602 %retval = select i1 %cmp5, i32 %cond, i32 %x 603 ret i32 %retval 604} 605 606; UMAX(UMAX(x, y), x) -> UMAX(x, y) 607define i32 @test31(i32 %x, i32 %y) { 608; CHECK-LABEL: @test31( 609; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]] 610; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[Y]] 611; CHECK-NEXT: ret i32 [[COND]] 612; 613 %cmp = icmp ugt i32 %x, %y 614 %cond = select i1 %cmp, i32 %x, i32 %y 615 %cmp5 = icmp ugt i32 %cond, %x 616 %retval = select i1 %cmp5, i32 %cond, i32 %x 617 ret i32 %retval 618} 619 620; SMIN(SMIN(x, y), x) -> SMIN(x, y) 621define i32 @test32(i32 %x, i32 %y) { 622; CHECK-LABEL: @test32( 623; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]] 624; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[X]] 625; CHECK-NEXT: ret i32 [[COND]] 626; 627 %cmp = icmp sgt i32 %x, %y 628 %cond = select i1 %cmp, i32 %y, i32 %x 629 %cmp5 = icmp sgt i32 %cond, %x 630 %retval = select i1 %cmp5, i32 %x, i32 %cond 631 ret i32 %retval 632} 633 634; MAX(MIN(x, y), x) -> x 635define i32 @test33(i32 %x, i32 %y) { 636; CHECK-LABEL: @test33( 637; CHECK-NEXT: ret i32 [[X:%.*]] 638; 639 %cmp = icmp sgt i32 %x, %y 640 %cond = select i1 %cmp, i32 %y, i32 %x 641 %cmp5 = icmp sgt i32 %cond, %x 642 %retval = select i1 %cmp5, i32 %cond, i32 %x 643 ret i32 %retval 644} 645 646; MIN(MAX(x, y), x) -> x 647define i32 @test34(i32 %x, i32 %y) { 648; CHECK-LABEL: @test34( 649; CHECK-NEXT: ret i32 [[X:%.*]] 650; 651 %cmp = icmp sgt i32 %x, %y 652 %cond = select i1 %cmp, i32 %x, i32 %y 653 %cmp5 = icmp sgt i32 %cond, %x 654 %retval = select i1 %cmp5, i32 %x, i32 %cond 655 ret i32 %retval 656} 657 658define i1 @test38(i1 %cond) { 659; CHECK-LABEL: @test38( 660; CHECK-NEXT: ret i1 false 661; 662 %zero = alloca i32 663 %one = alloca i32 664 %ptr = select i1 %cond, i32* %zero, i32* %one 665 %isnull = icmp eq i32* %ptr, null 666 ret i1 %isnull 667} 668 669define i1 @test39(i1 %cond, double %x) { 670; CHECK-LABEL: @test39( 671; CHECK-NEXT: ret i1 true 672; 673 %s = select i1 %cond, double %x, double 0x7FF0000000000000 ; RHS = +infty 674 %cmp = fcmp ule double %x, %s 675 ret i1 %cmp 676} 677 678define i1 @test40(i1 %cond) { 679; CHECK-LABEL: @test40( 680; CHECK-NEXT: ret i1 false 681; 682 %a = alloca i32 683 %b = alloca i32 684 %c = alloca i32 685 %s = select i1 %cond, i32* %a, i32* %b 686 %r = icmp eq i32* %s, %c 687 ret i1 %r 688} 689 690define i32 @test41(i1 %cond, i32 %x, i32 %y) { 691; CHECK-LABEL: @test41( 692; CHECK-NEXT: [[R:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 693; CHECK-NEXT: ret i32 [[R]] 694; 695 %z = and i32 %x, %y 696 %s = select i1 %cond, i32 %y, i32 %z 697 %r = and i32 %x, %s 698 ret i32 %r 699} 700 701define i32 @test42(i32 %x, i32 %y) { 702; CHECK-LABEL: @test42( 703; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[X:%.*]], 0 704; CHECK-NEXT: [[B:%.*]] = sext i1 [[COND]] to i32 705; CHECK-NEXT: [[C:%.*]] = add i32 [[B]], [[Y:%.*]] 706; CHECK-NEXT: ret i32 [[C]] 707; 708 %b = add i32 %y, -1 709 %cond = icmp eq i32 %x, 0 710 %c = select i1 %cond, i32 %b, i32 %y 711 ret i32 %c 712} 713 714define <2 x i32> @test42vec(<2 x i32> %x, <2 x i32> %y) { 715; CHECK-LABEL: @test42vec( 716; CHECK-NEXT: [[COND:%.*]] = icmp eq <2 x i32> [[X:%.*]], zeroinitializer 717; CHECK-NEXT: [[B:%.*]] = sext <2 x i1> [[COND]] to <2 x i32> 718; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[B]], [[Y:%.*]] 719; CHECK-NEXT: ret <2 x i32> [[C]] 720; 721 %b = add <2 x i32> %y, <i32 -1, i32 -1> 722 %cond = icmp eq <2 x i32> %x, zeroinitializer 723 %c = select <2 x i1> %cond, <2 x i32> %b, <2 x i32> %y 724 ret <2 x i32> %c 725} 726 727; PR8994 728 729; This select instruction can't be eliminated because trying to do so would 730; change the number of vector elements. This used to assert. 731define i48 @test51(<3 x i1> %icmp, <3 x i16> %tmp) { 732; CHECK-LABEL: @test51( 733; CHECK-NEXT: [[SELECT:%.*]] = select <3 x i1> [[ICMP:%.*]], <3 x i16> zeroinitializer, <3 x i16> [[TMP:%.*]] 734; CHECK-NEXT: [[TMP2:%.*]] = bitcast <3 x i16> [[SELECT]] to i48 735; CHECK-NEXT: ret i48 [[TMP2]] 736; 737 %select = select <3 x i1> %icmp, <3 x i16> zeroinitializer, <3 x i16> %tmp 738 %tmp2 = bitcast <3 x i16> %select to i48 739 ret i48 %tmp2 740} 741 742define <vscale x 4 x float> @bitcast_select_bitcast(<vscale x 4 x i1> %icmp, <vscale x 4 x i32> %a, <vscale x 4 x float> %b) { 743; CHECK-LABEL: @bitcast_select_bitcast( 744; CHECK-NEXT: [[TMP1:%.*]] = bitcast <vscale x 4 x i32> [[A:%.*]] to <vscale x 4 x float> 745; CHECK-NEXT: [[BC2:%.*]] = select <vscale x 4 x i1> [[ICMP:%.*]], <vscale x 4 x float> [[B:%.*]], <vscale x 4 x float> [[TMP1]] 746; CHECK-NEXT: ret <vscale x 4 x float> [[BC2]] 747; 748 %bc1 = bitcast <vscale x 4 x float> %b to <vscale x 4 x i32> 749 %select = select <vscale x 4 x i1> %icmp, <vscale x 4 x i32> %bc1, <vscale x 4 x i32> %a 750 %bc2 = bitcast <vscale x 4 x i32> %select to <vscale x 4 x float> 751 ret <vscale x 4 x float> %bc2 752} 753 754define void @select_oneuse_bitcast(<vscale x 4 x float> %a, <vscale x 4 x float> %b, <vscale x 4 x i32> %c, <vscale x 4 x i32> %d, <vscale x 4 x i32>* %ptr1) { 755; CHECK-LABEL: @select_oneuse_bitcast( 756; CHECK-NEXT: [[CMP:%.*]] = icmp ult <vscale x 4 x i32> [[C:%.*]], [[D:%.*]] 757; CHECK-NEXT: [[SEL1_V:%.*]] = select <vscale x 4 x i1> [[CMP]], <vscale x 4 x float> [[A:%.*]], <vscale x 4 x float> [[B:%.*]] 758; CHECK-NEXT: [[TMP1:%.*]] = bitcast <vscale x 4 x i32>* [[PTR1:%.*]] to <vscale x 4 x float>* 759; CHECK-NEXT: store <vscale x 4 x float> [[SEL1_V]], <vscale x 4 x float>* [[TMP1]], align 16 760; CHECK-NEXT: ret void 761; 762 %cmp = icmp ult <vscale x 4 x i32> %c, %d 763 %bc1 = bitcast <vscale x 4 x float> %a to <vscale x 4 x i32> 764 %bc2 = bitcast <vscale x 4 x float> %b to <vscale x 4 x i32> 765 %sel1 = select <vscale x 4 x i1> %cmp, <vscale x 4 x i32> %bc1, <vscale x 4 x i32> %bc2 766 store <vscale x 4 x i32> %sel1, <vscale x 4 x i32>* %ptr1 767 ret void 768} 769 770; Allow select promotion even if there are multiple uses of bitcasted ops. 771; Hoisting the selects allows later pattern matching to see that these are min/max ops. 772 773define void @min_max_bitcast(<4 x float> %a, <4 x float> %b, <4 x i32>* %ptr1, <4 x i32>* %ptr2) { 774; CHECK-LABEL: @min_max_bitcast( 775; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <4 x float> [[A:%.*]], [[B:%.*]] 776; CHECK-NEXT: [[SEL1_V:%.*]] = select <4 x i1> [[CMP]], <4 x float> [[A]], <4 x float> [[B]] 777; CHECK-NEXT: [[SEL2_V:%.*]] = select <4 x i1> [[CMP]], <4 x float> [[B]], <4 x float> [[A]] 778; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i32>* [[PTR1:%.*]] to <4 x float>* 779; CHECK-NEXT: store <4 x float> [[SEL1_V]], <4 x float>* [[TMP1]], align 16 780; CHECK-NEXT: [[TMP2:%.*]] = bitcast <4 x i32>* [[PTR2:%.*]] to <4 x float>* 781; CHECK-NEXT: store <4 x float> [[SEL2_V]], <4 x float>* [[TMP2]], align 16 782; CHECK-NEXT: ret void 783; 784 %cmp = fcmp olt <4 x float> %a, %b 785 %bc1 = bitcast <4 x float> %a to <4 x i32> 786 %bc2 = bitcast <4 x float> %b to <4 x i32> 787 %sel1 = select <4 x i1> %cmp, <4 x i32> %bc1, <4 x i32> %bc2 788 %sel2 = select <4 x i1> %cmp, <4 x i32> %bc2, <4 x i32> %bc1 789 store <4 x i32> %sel1, <4 x i32>* %ptr1 790 store <4 x i32> %sel2, <4 x i32>* %ptr2 791 ret void 792} 793 794define void @min_max_bitcast1(<vscale x 4 x float> %a, <vscale x 4 x float> %b, <vscale x 4 x i32>* %ptr1, <vscale x 4 x i32>* %ptr2) { 795; CHECK-LABEL: @min_max_bitcast1( 796; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <vscale x 4 x float> [[A:%.*]], [[B:%.*]] 797; CHECK-NEXT: [[SEL1_V:%.*]] = select <vscale x 4 x i1> [[CMP]], <vscale x 4 x float> [[A]], <vscale x 4 x float> [[B]] 798; CHECK-NEXT: [[SEL2_V:%.*]] = select <vscale x 4 x i1> [[CMP]], <vscale x 4 x float> [[B]], <vscale x 4 x float> [[A]] 799; CHECK-NEXT: [[TMP1:%.*]] = bitcast <vscale x 4 x i32>* [[PTR1:%.*]] to <vscale x 4 x float>* 800; CHECK-NEXT: store <vscale x 4 x float> [[SEL1_V]], <vscale x 4 x float>* [[TMP1]], align 16 801; CHECK-NEXT: [[TMP2:%.*]] = bitcast <vscale x 4 x i32>* [[PTR2:%.*]] to <vscale x 4 x float>* 802; CHECK-NEXT: store <vscale x 4 x float> [[SEL2_V]], <vscale x 4 x float>* [[TMP2]], align 16 803; CHECK-NEXT: ret void 804; 805 %cmp = fcmp olt <vscale x 4 x float> %a, %b 806 %bc1 = bitcast <vscale x 4 x float> %a to <vscale x 4 x i32> 807 %bc2 = bitcast <vscale x 4 x float> %b to <vscale x 4 x i32> 808 %sel1 = select <vscale x 4 x i1> %cmp, <vscale x 4 x i32> %bc1, <vscale x 4 x i32> %bc2 809 %sel2 = select <vscale x 4 x i1> %cmp, <vscale x 4 x i32> %bc2, <vscale x 4 x i32> %bc1 810 store <vscale x 4 x i32> %sel1, <vscale x 4 x i32>* %ptr1 811 store <vscale x 4 x i32> %sel2, <vscale x 4 x i32>* %ptr2 812 ret void 813} 814 815; To avoid potential backend problems, we don't do the same transform for other casts. 816 817define void @truncs_before_selects(<4 x float> %f1, <4 x float> %f2, <4 x i64> %a, <4 x i64> %b, <4 x i32>* %ptr1, <4 x i32>* %ptr2) { 818; CHECK-LABEL: @truncs_before_selects( 819; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <4 x float> [[F1:%.*]], [[F2:%.*]] 820; CHECK-NEXT: [[BC1:%.*]] = trunc <4 x i64> [[A:%.*]] to <4 x i32> 821; CHECK-NEXT: [[BC2:%.*]] = trunc <4 x i64> [[B:%.*]] to <4 x i32> 822; CHECK-NEXT: [[SEL1:%.*]] = select <4 x i1> [[CMP]], <4 x i32> [[BC1]], <4 x i32> [[BC2]] 823; CHECK-NEXT: [[SEL2:%.*]] = select <4 x i1> [[CMP]], <4 x i32> [[BC2]], <4 x i32> [[BC1]] 824; CHECK-NEXT: store <4 x i32> [[SEL1]], <4 x i32>* [[PTR1:%.*]], align 16 825; CHECK-NEXT: store <4 x i32> [[SEL2]], <4 x i32>* [[PTR2:%.*]], align 16 826; CHECK-NEXT: ret void 827; 828 %cmp = fcmp olt <4 x float> %f1, %f2 829 %bc1 = trunc <4 x i64> %a to <4 x i32> 830 %bc2 = trunc <4 x i64> %b to <4 x i32> 831 %sel1 = select <4 x i1> %cmp, <4 x i32> %bc1, <4 x i32> %bc2 832 %sel2 = select <4 x i1> %cmp, <4 x i32> %bc2, <4 x i32> %bc1 833 store <4 x i32> %sel1, <4 x i32>* %ptr1, align 16 834 store <4 x i32> %sel2, <4 x i32>* %ptr2, align 16 835 ret void 836} 837 838; PR8575 839 840define i32 @test52(i32 %n, i32 %m) { 841; CHECK-LABEL: @test52( 842; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], [[M:%.*]] 843; CHECK-NEXT: [[STOREMERGE:%.*]] = select i1 [[CMP]], i32 1, i32 6 844; CHECK-NEXT: ret i32 [[STOREMERGE]] 845; 846 %cmp = icmp sgt i32 %n, %m 847 %. = select i1 %cmp, i32 1, i32 3 848 %add = add nsw i32 %., 3 849 %storemerge = select i1 %cmp, i32 %., i32 %add 850 ret i32 %storemerge 851} 852 853; PR9454 854 855define i32 @test53(i32 %x) { 856; CHECK-LABEL: @test53( 857; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 2 858; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], [[X]] 859; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 2, i32 1 860; CHECK-NEXT: ret i32 [[SEL]] 861; 862 %and = and i32 %x, 2 863 %cmp = icmp eq i32 %and, %x 864 %sel = select i1 %cmp, i32 2, i32 1 865 ret i32 %sel 866} 867 868define i32 @test54(i32 %X, i32 %Y) { 869; CHECK-LABEL: @test54( 870; CHECK-NEXT: [[B:%.*]] = icmp ne i32 [[X:%.*]], 0 871; CHECK-NEXT: [[C:%.*]] = zext i1 [[B]] to i32 872; CHECK-NEXT: ret i32 [[C]] 873; 874 %A = ashr exact i32 %X, %Y 875 %B = icmp eq i32 %A, 0 876 %C = select i1 %B, i32 %A, i32 1 877 ret i32 %C 878} 879 880define i1 @test55(i1 %X, i32 %Y, i32 %Z) { 881; CHECK-LABEL: @test55( 882; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[Y:%.*]], 0 883; CHECK-NEXT: ret i1 [[C]] 884; 885 %A = ashr exact i32 %Y, %Z 886 %B = select i1 %X, i32 %Y, i32 %A 887 %C = icmp eq i32 %B, 0 888 ret i1 %C 889} 890 891define i32 @test56(i16 %x) { 892; CHECK-LABEL: @test56( 893; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[X:%.*]] to i32 894; CHECK-NEXT: ret i32 [[CONV]] 895; 896 %tobool = icmp eq i16 %x, 0 897 %conv = zext i16 %x to i32 898 %cond = select i1 %tobool, i32 0, i32 %conv 899 ret i32 %cond 900} 901 902define i32 @test57(i32 %x, i32 %y) { 903; CHECK-LABEL: @test57( 904; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 905; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X]], 0 906; CHECK-NEXT: [[DOTAND:%.*]] = select i1 [[TOBOOL]], i32 0, i32 [[AND]] 907; CHECK-NEXT: ret i32 [[DOTAND]] 908; 909 %and = and i32 %x, %y 910 %tobool = icmp eq i32 %x, 0 911 %.and = select i1 %tobool, i32 0, i32 %and 912 ret i32 %.and 913} 914 915define i32 @test58(i16 %x) { 916; CHECK-LABEL: @test58( 917; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[X:%.*]] to i32 918; CHECK-NEXT: ret i32 [[CONV]] 919; 920 %tobool = icmp ne i16 %x, 1 921 %conv = zext i16 %x to i32 922 %cond = select i1 %tobool, i32 %conv, i32 1 923 ret i32 %cond 924} 925 926define i32 @test59(i32 %x, i32 %y) { 927; CHECK-LABEL: @test59( 928; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 929; CHECK-NEXT: ret i32 [[AND]] 930; 931 %and = and i32 %x, %y 932 %tobool = icmp ne i32 %x, %y 933 %.and = select i1 %tobool, i32 %and, i32 %y 934 ret i32 %.and 935} 936 937define i1 @test60(i32 %x, i1* %y) { 938; CHECK-LABEL: @test60( 939; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0 940; CHECK-NEXT: [[LOAD:%.*]] = load i1, i1* [[Y:%.*]], align 1 941; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[X]], 1 942; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i1 [[LOAD]], i1 [[CMP1]] 943; CHECK-NEXT: ret i1 [[SEL]] 944; 945 %cmp = icmp eq i32 %x, 0 946 %load = load i1, i1* %y, align 1 947 %cmp1 = icmp slt i32 %x, 1 948 %sel = select i1 %cmp, i1 %load, i1 %cmp1 949 ret i1 %sel 950} 951 952@glbl = constant i32 10 953define i32 @test61(i32* %ptr) { 954; CHECK-LABEL: @test61( 955; CHECK-NEXT: ret i32 10 956; 957 %A = load i32, i32* %ptr 958 %B = icmp eq i32* %ptr, @glbl 959 %C = select i1 %B, i32 %A, i32 10 960 ret i32 %C 961} 962 963; PR14131 964define void @test64(i32 %p, i16 %b) noreturn { 965; CHECK-LABEL: @test64( 966; CHECK-NEXT: entry: 967; CHECK-NEXT: br i1 undef, label [[LOR_RHS:%.*]], label [[LOR_END:%.*]] 968; CHECK: lor.rhs: 969; CHECK-NEXT: br label [[LOR_END]] 970; CHECK: lor.end: 971; CHECK-NEXT: br i1 true, label [[COND_END17:%.*]], label [[COND_FALSE16:%.*]] 972; CHECK: cond.false16: 973; CHECK-NEXT: br label [[COND_END17]] 974; CHECK: cond.end17: 975; CHECK-NEXT: br label [[WHILE_BODY:%.*]] 976; CHECK: while.body: 977; CHECK-NEXT: br label [[WHILE_BODY]] 978; 979entry: 980 %p.addr.0.insert.mask = and i32 %p, -65536 981 %conv2 = and i32 %p, 65535 982 br i1 undef, label %lor.rhs, label %lor.end 983 984lor.rhs: 985 %p.addr.0.extract.trunc = trunc i32 %p.addr.0.insert.mask to i16 986 %phitmp = zext i16 %p.addr.0.extract.trunc to i32 987 br label %lor.end 988 989lor.end: 990 %t.1 = phi i32 [ 0, %entry ], [ %phitmp, %lor.rhs ] 991 %conv6 = zext i16 %b to i32 992 %div = udiv i32 %conv6, %t.1 993 %tobool8 = icmp eq i32 %div, 0 994 %cmp = icmp eq i32 %t.1, 0 995 %cmp12 = icmp ult i32 %conv2, 2 996 %cmp.sink = select i1 %tobool8, i1 %cmp12, i1 %cmp 997 br i1 %cmp.sink, label %cond.end17, label %cond.false16 998 999cond.false16: 1000 br label %cond.end17 1001 1002cond.end17: 1003 br label %while.body 1004 1005while.body: 1006 br label %while.body 1007} 1008 1009@under_aligned = external global i32, align 1 1010 1011; The load here must not be speculated around the select. One side of the 1012; select is trivially dereferenceable but may have a lower alignment than the 1013; load does. 1014define i32 @test76(i1 %flag, i32* %x) { 1015; CHECK-LABEL: @test76( 1016; CHECK-NEXT: store i32 0, i32* [[X:%.*]], align 4 1017; CHECK-NEXT: [[P:%.*]] = select i1 [[FLAG:%.*]], i32* @under_aligned, i32* [[X]] 1018; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[P]], align 4 1019; CHECK-NEXT: ret i32 [[V]] 1020; 1021 store i32 0, i32* %x 1022 %p = select i1 %flag, i32* @under_aligned, i32* %x 1023 %v = load i32, i32* %p 1024 ret i32 %v 1025} 1026 1027declare void @scribble_on_i32(i32*) 1028 1029; The load here must not be speculated around the select. One side of the 1030; select is trivially dereferenceable but may have a lower alignment than the 1031; load does. 1032 1033define i32 @test77(i1 %flag, i32* %x) { 1034; CHECK-LABEL: @test77( 1035; CHECK-NEXT: [[UNDER_ALIGNED:%.*]] = alloca i32, align 1 1036; CHECK-NEXT: call void @scribble_on_i32(i32* nonnull [[UNDER_ALIGNED]]) 1037; CHECK-NEXT: store i32 0, i32* [[X:%.*]], align 4 1038; CHECK-NEXT: [[P:%.*]] = select i1 [[FLAG:%.*]], i32* [[UNDER_ALIGNED]], i32* [[X]] 1039; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[P]], align 4 1040; CHECK-NEXT: ret i32 [[V]] 1041; 1042 %under_aligned = alloca i32, align 1 1043 call void @scribble_on_i32(i32* %under_aligned) 1044 store i32 0, i32* %x 1045 %p = select i1 %flag, i32* %under_aligned, i32* %x 1046 %v = load i32, i32* %p 1047 ret i32 %v 1048} 1049 1050define i32 @test78(i1 %flag, i32* %x, i32* %y, i32* %z) { 1051; Test that we can speculate the loads around the select even when we can't 1052; fold the load completely away. 1053; CHECK-LABEL: @test78( 1054; CHECK-NEXT: entry: 1055; CHECK-NEXT: store i32 0, i32* [[X:%.*]], align 4 1056; CHECK-NEXT: store i32 0, i32* [[Y:%.*]], align 4 1057; CHECK-NEXT: store i32 42, i32* [[Z:%.*]], align 4 1058; CHECK-NEXT: [[X_VAL:%.*]] = load i32, i32* [[X]], align 4 1059; CHECK-NEXT: [[Y_VAL:%.*]] = load i32, i32* [[Y]], align 4 1060; CHECK-NEXT: [[V:%.*]] = select i1 [[FLAG:%.*]], i32 [[X_VAL]], i32 [[Y_VAL]] 1061; CHECK-NEXT: ret i32 [[V]] 1062; 1063entry: 1064 store i32 0, i32* %x 1065 store i32 0, i32* %y 1066 ; Block forwarding by storing to %z which could alias either %x or %y. 1067 store i32 42, i32* %z 1068 %p = select i1 %flag, i32* %x, i32* %y 1069 %v = load i32, i32* %p 1070 ret i32 %v 1071} 1072 1073; Test that we can speculate the loads around the select even when we can't 1074; fold the load completely away. 1075define i32 @test78_deref(i1 %flag, i32* dereferenceable(4) align 4 %x, i32* dereferenceable(4) align 4 %y, i32* %z) { 1076; CHECK-LABEL: @test78_deref( 1077; CHECK-NEXT: [[X_VAL:%.*]] = load i32, i32* [[X:%.*]], align 4 1078; CHECK-NEXT: [[Y_VAL:%.*]] = load i32, i32* [[Y:%.*]], align 4 1079; CHECK-NEXT: [[V:%.*]] = select i1 [[FLAG:%.*]], i32 [[X_VAL]], i32 [[Y_VAL]] 1080; CHECK-NEXT: ret i32 [[V]] 1081; 1082 %p = select i1 %flag, i32* %x, i32* %y 1083 %v = load i32, i32* %p 1084 ret i32 %v 1085} 1086 1087; The same as @test78 but we can't speculate the load because it can trap 1088; if under-aligned. 1089define i32 @test78_neg(i1 %flag, i32* %x, i32* %y, i32* %z) { 1090; CHECK-LABEL: @test78_neg( 1091; CHECK-NEXT: store i32 0, i32* [[X:%.*]], align 4 1092; CHECK-NEXT: store i32 0, i32* [[Y:%.*]], align 4 1093; CHECK-NEXT: store i32 42, i32* [[Z:%.*]], align 4 1094; CHECK-NEXT: [[P:%.*]] = select i1 [[FLAG:%.*]], i32* [[X]], i32* [[Y]] 1095; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[P]], align 16 1096; CHECK-NEXT: ret i32 [[V]] 1097; 1098 store i32 0, i32* %x 1099 store i32 0, i32* %y 1100 ; Block forwarding by storing to %z which could alias either %x or %y. 1101 store i32 42, i32* %z 1102 %p = select i1 %flag, i32* %x, i32* %y 1103 %v = load i32, i32* %p, align 16 1104 ret i32 %v 1105} 1106 1107; The same as @test78_deref but we can't speculate the load because 1108; one of the arguments is not sufficiently dereferenceable. 1109define i32 @test78_deref_neg(i1 %flag, i32* dereferenceable(2) %x, i32* dereferenceable(4) %y, i32* %z) { 1110; CHECK-LABEL: @test78_deref_neg( 1111; CHECK-NEXT: [[P:%.*]] = select i1 [[FLAG:%.*]], i32* [[X:%.*]], i32* [[Y:%.*]] 1112; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[P]], align 4 1113; CHECK-NEXT: ret i32 [[V]] 1114; 1115 %p = select i1 %flag, i32* %x, i32* %y 1116 %v = load i32, i32* %p 1117 ret i32 %v 1118} 1119 1120; Test that we can speculate the loads around the select even when we can't 1121; fold the load completely away. 1122define float @test79(i1 %flag, float* %x, i32* %y, i32* %z) { 1123; CHECK-LABEL: @test79( 1124; CHECK-NEXT: [[X1:%.*]] = bitcast float* [[X:%.*]] to i32* 1125; CHECK-NEXT: [[Y1:%.*]] = bitcast i32* [[Y:%.*]] to float* 1126; CHECK-NEXT: store i32 0, i32* [[X1]], align 4 1127; CHECK-NEXT: store i32 0, i32* [[Y]], align 4 1128; CHECK-NEXT: store i32 42, i32* [[Z:%.*]], align 4 1129; CHECK-NEXT: [[X_VAL:%.*]] = load float, float* [[X]], align 4 1130; CHECK-NEXT: [[Y1_VAL:%.*]] = load float, float* [[Y1]], align 4 1131; CHECK-NEXT: [[V:%.*]] = select i1 [[FLAG:%.*]], float [[X_VAL]], float [[Y1_VAL]] 1132; CHECK-NEXT: ret float [[V]] 1133; 1134 %x1 = bitcast float* %x to i32* 1135 %y1 = bitcast i32* %y to float* 1136 store i32 0, i32* %x1 1137 store i32 0, i32* %y 1138 ; Block forwarding by storing to %z which could alias either %x or %y. 1139 store i32 42, i32* %z 1140 %p = select i1 %flag, float* %x, float* %y1 1141 %v = load float, float* %p 1142 ret float %v 1143} 1144 1145; Test that when we speculate the loads around the select they fold throug 1146; load->load folding and load->store folding. 1147define i32 @test80(i1 %flag) { 1148; CHECK-LABEL: @test80( 1149; CHECK-NEXT: [[X:%.*]] = alloca i32, align 4 1150; CHECK-NEXT: [[Y:%.*]] = alloca i32, align 4 1151; CHECK-NEXT: call void @scribble_on_i32(i32* nonnull [[X]]) 1152; CHECK-NEXT: call void @scribble_on_i32(i32* nonnull [[Y]]) 1153; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[X]], align 4 1154; CHECK-NEXT: store i32 [[TMP]], i32* [[Y]], align 4 1155; CHECK-NEXT: ret i32 [[TMP]] 1156; 1157 %x = alloca i32 1158 %y = alloca i32 1159 call void @scribble_on_i32(i32* %x) 1160 call void @scribble_on_i32(i32* %y) 1161 %tmp = load i32, i32* %x 1162 store i32 %tmp, i32* %y 1163 %p = select i1 %flag, i32* %x, i32* %y 1164 %v = load i32, i32* %p 1165 ret i32 %v 1166} 1167 1168; Test that we can speculate the load around the select even though they use 1169; differently typed pointers. 1170define float @test81(i1 %flag) { 1171; CHECK-LABEL: @test81( 1172; CHECK-NEXT: [[X:%.*]] = alloca i32, align 4 1173; CHECK-NEXT: [[Y:%.*]] = alloca i32, align 4 1174; CHECK-NEXT: call void @scribble_on_i32(i32* nonnull [[X]]) 1175; CHECK-NEXT: call void @scribble_on_i32(i32* nonnull [[Y]]) 1176; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[X]], align 4 1177; CHECK-NEXT: store i32 [[TMP]], i32* [[Y]], align 4 1178; CHECK-NEXT: [[V:%.*]] = bitcast i32 [[TMP]] to float 1179; CHECK-NEXT: ret float [[V]] 1180; 1181 %x = alloca float 1182 %y = alloca i32 1183 %x1 = bitcast float* %x to i32* 1184 %y1 = bitcast i32* %y to float* 1185 call void @scribble_on_i32(i32* %x1) 1186 call void @scribble_on_i32(i32* %y) 1187 %tmp = load i32, i32* %x1 1188 store i32 %tmp, i32* %y 1189 %p = select i1 %flag, float* %x, float* %y1 1190 %v = load float, float* %p 1191 ret float %v 1192} 1193 1194; Test that we can speculate the load around the select even though they use 1195; differently typed pointers. 1196define i32 @test82(i1 %flag) { 1197; CHECK-LABEL: @test82( 1198; CHECK-NEXT: [[X:%.*]] = alloca float, align 4 1199; CHECK-NEXT: [[Y:%.*]] = alloca i32, align 4 1200; CHECK-NEXT: [[X1:%.*]] = bitcast float* [[X]] to i32* 1201; CHECK-NEXT: [[Y1:%.*]] = bitcast i32* [[Y]] to float* 1202; CHECK-NEXT: call void @scribble_on_i32(i32* nonnull [[X1]]) 1203; CHECK-NEXT: call void @scribble_on_i32(i32* nonnull [[Y]]) 1204; CHECK-NEXT: [[TMP:%.*]] = load float, float* [[X]], align 4 1205; CHECK-NEXT: store float [[TMP]], float* [[Y1]], align 4 1206; CHECK-NEXT: [[V:%.*]] = bitcast float [[TMP]] to i32 1207; CHECK-NEXT: ret i32 [[V]] 1208; 1209 %x = alloca float 1210 %y = alloca i32 1211 %x1 = bitcast float* %x to i32* 1212 %y1 = bitcast i32* %y to float* 1213 call void @scribble_on_i32(i32* %x1) 1214 call void @scribble_on_i32(i32* %y) 1215 %tmp = load float, float* %x 1216 store float %tmp, float* %y1 1217 %p = select i1 %flag, i32* %x1, i32* %y 1218 %v = load i32, i32* %p 1219 ret i32 %v 1220} 1221 1222declare void @scribble_on_i64(i64*) 1223declare void @scribble_on_i128(i128*) 1224 1225; Test that we can speculate the load around the select even though they use 1226; differently typed pointers and requires inttoptr casts. 1227define i8* @test83(i1 %flag) { 1228; CHECK-LABEL: @test83( 1229; CHECK-NEXT: [[X:%.*]] = alloca i8*, align 8 1230; CHECK-NEXT: [[Y:%.*]] = alloca i8*, align 8 1231; CHECK-NEXT: [[TMPCAST:%.*]] = bitcast i8** [[Y]] to i64* 1232; CHECK-NEXT: [[X1:%.*]] = bitcast i8** [[X]] to i64* 1233; CHECK-NEXT: call void @scribble_on_i64(i64* nonnull [[X1]]) 1234; CHECK-NEXT: call void @scribble_on_i64(i64* nonnull [[TMPCAST]]) 1235; CHECK-NEXT: [[TMP:%.*]] = load i64, i64* [[X1]], align 8 1236; CHECK-NEXT: store i64 [[TMP]], i64* [[TMPCAST]], align 8 1237; CHECK-NEXT: [[V:%.*]] = inttoptr i64 [[TMP]] to i8* 1238; CHECK-NEXT: ret i8* [[V]] 1239; 1240 %x = alloca i8* 1241 %y = alloca i64 1242 %x1 = bitcast i8** %x to i64* 1243 %y1 = bitcast i64* %y to i8** 1244 call void @scribble_on_i64(i64* %x1) 1245 call void @scribble_on_i64(i64* %y) 1246 %tmp = load i64, i64* %x1 1247 store i64 %tmp, i64* %y 1248 %p = select i1 %flag, i8** %x, i8** %y1 1249 %v = load i8*, i8** %p 1250 ret i8* %v 1251} 1252 1253; Test that we can speculate the load around the select even though they use 1254; differently typed pointers and requires a ptrtoint cast. 1255define i64 @test84(i1 %flag) { 1256; CHECK-LABEL: @test84( 1257; CHECK-NEXT: [[X:%.*]] = alloca i8*, align 8 1258; CHECK-NEXT: [[Y:%.*]] = alloca i8*, align 8 1259; CHECK-NEXT: [[TMPCAST:%.*]] = bitcast i8** [[Y]] to i64* 1260; CHECK-NEXT: [[X1:%.*]] = bitcast i8** [[X]] to i64* 1261; CHECK-NEXT: call void @scribble_on_i64(i64* nonnull [[X1]]) 1262; CHECK-NEXT: call void @scribble_on_i64(i64* nonnull [[TMPCAST]]) 1263; CHECK-NEXT: [[TMP:%.*]] = load i8*, i8** [[X]], align 8 1264; CHECK-NEXT: store i8* [[TMP]], i8** [[Y]], align 8 1265; CHECK-NEXT: [[V:%.*]] = ptrtoint i8* [[TMP]] to i64 1266; CHECK-NEXT: ret i64 [[V]] 1267; 1268 %x = alloca i8* 1269 %y = alloca i64 1270 %x1 = bitcast i8** %x to i64* 1271 %y1 = bitcast i64* %y to i8** 1272 call void @scribble_on_i64(i64* %x1) 1273 call void @scribble_on_i64(i64* %y) 1274 %tmp = load i8*, i8** %x 1275 store i8* %tmp, i8** %y1 1276 %p = select i1 %flag, i64* %x1, i64* %y 1277 %v = load i64, i64* %p 1278 ret i64 %v 1279} 1280 1281; Test that we can't speculate the load around the select. The load of the 1282; pointer doesn't load all of the stored integer bits. We could fix this, but it 1283; would require endianness checks and other nastiness. 1284define i8* @test85(i1 %flag) { 1285; CHECK-LABEL: @test85( 1286; CHECK-NEXT: [[X1:%.*]] = alloca [2 x i8*], align 8 1287; CHECK-NEXT: [[Y:%.*]] = alloca i128, align 8 1288; CHECK-NEXT: [[X1_SUB:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[X1]], i64 0, i64 0 1289; CHECK-NEXT: [[X2:%.*]] = bitcast [2 x i8*]* [[X1]] to i128* 1290; CHECK-NEXT: [[Y1:%.*]] = bitcast i128* [[Y]] to i8** 1291; CHECK-NEXT: call void @scribble_on_i128(i128* nonnull [[X2]]) 1292; CHECK-NEXT: call void @scribble_on_i128(i128* nonnull [[Y]]) 1293; CHECK-NEXT: [[TMP:%.*]] = load i128, i128* [[X2]], align 8 1294; CHECK-NEXT: store i128 [[TMP]], i128* [[Y]], align 8 1295; CHECK-NEXT: [[X1_SUB_VAL:%.*]] = load i8*, i8** [[X1_SUB]], align 8 1296; CHECK-NEXT: [[Y1_VAL:%.*]] = load i8*, i8** [[Y1]], align 8 1297; CHECK-NEXT: [[V:%.*]] = select i1 [[FLAG:%.*]], i8* [[X1_SUB_VAL]], i8* [[Y1_VAL]] 1298; CHECK-NEXT: ret i8* [[V]] 1299; 1300 %x = alloca [2 x i8*] 1301 %y = alloca i128 1302 %x1 = bitcast [2 x i8*]* %x to i8** 1303 %x2 = bitcast i8** %x1 to i128* 1304 %y1 = bitcast i128* %y to i8** 1305 call void @scribble_on_i128(i128* %x2) 1306 call void @scribble_on_i128(i128* %y) 1307 %tmp = load i128, i128* %x2 1308 store i128 %tmp, i128* %y 1309 %p = select i1 %flag, i8** %x1, i8** %y1 1310 %v = load i8*, i8** %p 1311 ret i8* %v 1312} 1313 1314; Test that we can't speculate the load around the select when the integer size 1315; is larger than the pointer size. The store of the pointer doesn't store to all 1316; the bits of the integer. 1317define i128 @test86(i1 %flag) { 1318; CHECK-LABEL: @test86( 1319; CHECK-NEXT: [[X1:%.*]] = alloca [2 x i8*], align 8 1320; CHECK-NEXT: [[Y:%.*]] = alloca i128, align 8 1321; CHECK-NEXT: [[X1_SUB:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[X1]], i64 0, i64 0 1322; CHECK-NEXT: [[X2:%.*]] = bitcast [2 x i8*]* [[X1]] to i128* 1323; CHECK-NEXT: [[Y1:%.*]] = bitcast i128* [[Y]] to i8** 1324; CHECK-NEXT: call void @scribble_on_i128(i128* nonnull [[X2]]) 1325; CHECK-NEXT: call void @scribble_on_i128(i128* nonnull [[Y]]) 1326; CHECK-NEXT: [[TMP:%.*]] = load i8*, i8** [[X1_SUB]], align 8 1327; CHECK-NEXT: store i8* [[TMP]], i8** [[Y1]], align 8 1328; CHECK-NEXT: [[X2_VAL:%.*]] = load i128, i128* [[X2]], align 8 1329; CHECK-NEXT: [[Y_VAL:%.*]] = load i128, i128* [[Y]], align 8 1330; CHECK-NEXT: [[V:%.*]] = select i1 [[FLAG:%.*]], i128 [[X2_VAL]], i128 [[Y_VAL]] 1331; CHECK-NEXT: ret i128 [[V]] 1332; 1333 %x = alloca [2 x i8*] 1334 %y = alloca i128 1335 %x1 = bitcast [2 x i8*]* %x to i8** 1336 %x2 = bitcast i8** %x1 to i128* 1337 %y1 = bitcast i128* %y to i8** 1338 call void @scribble_on_i128(i128* %x2) 1339 call void @scribble_on_i128(i128* %y) 1340 %tmp = load i8*, i8** %x1 1341 store i8* %tmp, i8** %y1 1342 %p = select i1 %flag, i128* %x2, i128* %y 1343 %v = load i128, i128* %p 1344 ret i128 %v 1345} 1346 1347define i32 @test_select_select0(i32 %a, i32 %r0, i32 %r1, i32 %v1, i32 %v2) { 1348; CHECK-LABEL: @test_select_select0( 1349; CHECK-NEXT: [[C0_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[V1:%.*]] 1350; CHECK-NEXT: [[S0:%.*]] = select i1 [[C0_NOT]], i32 [[R1:%.*]], i32 [[R0:%.*]] 1351; CHECK-NEXT: [[C1:%.*]] = icmp slt i32 [[A]], [[V2:%.*]] 1352; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1]], i32 [[S0]], i32 [[R1]] 1353; CHECK-NEXT: ret i32 [[S1]] 1354; 1355 %c0 = icmp sge i32 %a, %v1 1356 %s0 = select i1 %c0, i32 %r0, i32 %r1 1357 %c1 = icmp slt i32 %a, %v2 1358 %s1 = select i1 %c1, i32 %s0, i32 %r1 1359 ret i32 %s1 1360} 1361 1362define i32 @test_select_select1(i32 %a, i32 %r0, i32 %r1, i32 %v1, i32 %v2) { 1363; CHECK-LABEL: @test_select_select1( 1364; CHECK-NEXT: [[C0_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[V1:%.*]] 1365; CHECK-NEXT: [[S0:%.*]] = select i1 [[C0_NOT]], i32 [[R1:%.*]], i32 [[R0:%.*]] 1366; CHECK-NEXT: [[C1:%.*]] = icmp slt i32 [[A]], [[V2:%.*]] 1367; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1]], i32 [[R0]], i32 [[S0]] 1368; CHECK-NEXT: ret i32 [[S1]] 1369; 1370 %c0 = icmp sge i32 %a, %v1 1371 %s0 = select i1 %c0, i32 %r0, i32 %r1 1372 %c1 = icmp slt i32 %a, %v2 1373 %s1 = select i1 %c1, i32 %r0, i32 %s0 1374 ret i32 %s1 1375} 1376 1377define i32 @PR23757(i32 %x) { 1378; CHECK-LABEL: @PR23757( 1379; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], 1 1380; CHECK-NEXT: ret i32 [[ADD]] 1381; 1382 %cmp = icmp eq i32 %x, 2147483647 1383 %add = add nsw i32 %x, 1 1384 %sel = select i1 %cmp, i32 -2147483648, i32 %add 1385 ret i32 %sel 1386} 1387 1388define i32 @PR23757_swapped(i32 %x) { 1389; CHECK-LABEL: @PR23757_swapped( 1390; CHECK-NEXT: ret i32 -2147483648 1391; 1392 %cmp = icmp eq i32 %x, 2147483647 1393 %add = add nsw i32 %x, 1 1394 %sel = select i1 %cmp, i32 %add, i32 -2147483648 1395 ret i32 %sel 1396} 1397 1398define i32 @PR23757_ne(i32 %x, i1* %p) { 1399; CHECK-LABEL: @PR23757_ne( 1400; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 2147483647 1401; CHECK-NEXT: store i1 [[CMP]], i1* [[P:%.*]], align 1 1402; CHECK-NEXT: ret i32 -2147483648 1403; 1404 %cmp = icmp ne i32 %x, 2147483647 1405 store i1 %cmp, i1* %p ; thwart predicate canonicalization 1406 %add = add nsw i32 %x, 1 1407 %sel = select i1 %cmp, i32 -2147483648, i32 %add 1408 ret i32 %sel 1409} 1410 1411define i32 @PR23757_ne_swapped(i32 %x, i1* %p) { 1412; CHECK-LABEL: @PR23757_ne_swapped( 1413; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 2147483647 1414; CHECK-NEXT: store i1 [[CMP]], i1* [[P:%.*]], align 1 1415; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X]], 1 1416; CHECK-NEXT: ret i32 [[ADD]] 1417; 1418 %cmp = icmp ne i32 %x, 2147483647 1419 store i1 %cmp, i1* %p ; thwart predicate canonicalization 1420 %add = add nsw i32 %x, 1 1421 %sel = select i1 %cmp, i32 %add, i32 -2147483648 1422 ret i32 %sel 1423} 1424 1425; max(max(~a, -1), -1) --> ~min(a, 0) 1426 1427define i32 @PR27137(i32 %a) { 1428; CHECK-LABEL: @PR27137( 1429; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[A:%.*]], 0 1430; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[A]], i32 0 1431; CHECK-NEXT: [[S1:%.*]] = xor i32 [[TMP2]], -1 1432; CHECK-NEXT: ret i32 [[S1]] 1433; 1434 %not_a = xor i32 %a, -1 1435 %c0 = icmp slt i32 %a, 0 1436 %s0 = select i1 %c0, i32 %not_a, i32 -1 1437 %c1 = icmp sgt i32 %s0, -1 1438 %s1 = select i1 %c1, i32 %s0, i32 -1 1439 ret i32 %s1 1440} 1441 1442; ub-safe negation pattern 1443define i32 @PR27817(i32 %x) { 1444; CHECK-LABEL: @PR27817( 1445; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[X:%.*]] 1446; CHECK-NEXT: ret i32 [[SUB]] 1447; 1448 %cmp = icmp eq i32 %x, -2147483648 1449 %sub = sub i32 0, %x 1450 %sel = select i1 %cmp, i32 -2147483648, i32 %sub 1451 ret i32 %sel 1452} 1453 1454define i32 @PR27817_nsw(i32 %x) { 1455; CHECK-LABEL: @PR27817_nsw( 1456; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[X:%.*]] 1457; CHECK-NEXT: ret i32 [[SUB]] 1458; 1459 %cmp = icmp eq i32 %x, -2147483648 1460 %sub = sub nsw i32 0, %x 1461 %sel = select i1 %cmp, i32 -2147483648, i32 %sub 1462 ret i32 %sel 1463} 1464 1465define i32 @select_icmp_slt0_xor(i32 %x) { 1466; CHECK-LABEL: @select_icmp_slt0_xor( 1467; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[X:%.*]], -2147483648 1468; CHECK-NEXT: ret i32 [[TMP1]] 1469; 1470 %cmp = icmp slt i32 %x, zeroinitializer 1471 %xor = xor i32 %x, 2147483648 1472 %x.xor = select i1 %cmp, i32 %x, i32 %xor 1473 ret i32 %x.xor 1474} 1475 1476define <2 x i32> @select_icmp_slt0_xor_vec(<2 x i32> %x) { 1477; CHECK-LABEL: @select_icmp_slt0_xor_vec( 1478; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[X:%.*]], <i32 -2147483648, i32 -2147483648> 1479; CHECK-NEXT: ret <2 x i32> [[TMP1]] 1480; 1481 %cmp = icmp slt <2 x i32> %x, zeroinitializer 1482 %xor = xor <2 x i32> %x, <i32 2147483648, i32 2147483648> 1483 %x.xor = select <2 x i1> %cmp, <2 x i32> %x, <2 x i32> %xor 1484 ret <2 x i32> %x.xor 1485} 1486 1487define <4 x i32> @canonicalize_to_shuffle(<4 x i32> %a, <4 x i32> %b) { 1488; CHECK-LABEL: @canonicalize_to_shuffle( 1489; CHECK-NEXT: [[SEL:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], <4 x i32> <i32 0, i32 5, i32 6, i32 3> 1490; CHECK-NEXT: ret <4 x i32> [[SEL]] 1491; 1492 %sel = select <4 x i1> <i1 true, i1 false, i1 false, i1 true>, <4 x i32> %a, <4 x i32> %b 1493 ret <4 x i32> %sel 1494} 1495 1496; Undef elements of the select condition may not be translated into undef elements of a shuffle mask 1497; because undef in a shuffle mask means we can return anything, not just one of the selected values. 1498; https://bugs.llvm.org/show_bug.cgi?id=32486 1499 1500define <4 x i32> @undef_elts_in_condition(<4 x i32> %a, <4 x i32> %b) { 1501; CHECK-LABEL: @undef_elts_in_condition( 1502; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> <i1 true, i1 undef, i1 false, i1 undef>, <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]] 1503; CHECK-NEXT: ret <4 x i32> [[SEL]] 1504; 1505 %sel = select <4 x i1> <i1 true, i1 undef, i1 false, i1 undef>, <4 x i32> %a, <4 x i32> %b 1506 ret <4 x i32> %sel 1507} 1508 1509; Don't die or try if the condition mask is a constant expression or contains a constant expression. 1510 1511@g = global i32 0 1512 1513define <4 x i32> @cannot_canonicalize_to_shuffle1(<4 x i32> %a, <4 x i32> %b) { 1514; CHECK-LABEL: @cannot_canonicalize_to_shuffle1( 1515; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> bitcast (i4 ptrtoint (i32* @g to i4) to <4 x i1>), <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]] 1516; CHECK-NEXT: ret <4 x i32> [[SEL]] 1517; 1518 %sel = select <4 x i1> bitcast (i4 ptrtoint (i32* @g to i4) to <4 x i1>), <4 x i32> %a, <4 x i32> %b 1519 ret <4 x i32> %sel 1520} 1521 1522define <4 x i32> @cannot_canonicalize_to_shuffle2(<4 x i32> %a, <4 x i32> %b) { 1523; CHECK-LABEL: @cannot_canonicalize_to_shuffle2( 1524; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> <i1 true, i1 undef, i1 false, i1 icmp sle (i16 ptrtoint (i32* @g to i16), i16 4)>, <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]] 1525; CHECK-NEXT: ret <4 x i32> [[SEL]] 1526; 1527 %sel = select <4 x i1> <i1 true, i1 undef, i1 false, i1 icmp sle (i16 ptrtoint (i32* @g to i16), i16 4)>, <4 x i32> %a, <4 x i32> %b 1528 ret <4 x i32> %sel 1529} 1530 1531declare void @llvm.assume(i1) 1532 1533define i8 @assume_cond_true(i1 %cond, i8 %x, i8 %y) { 1534; CHECK-LABEL: @assume_cond_true( 1535; CHECK-NEXT: call void @llvm.assume(i1 [[COND:%.*]]) 1536; CHECK-NEXT: ret i8 [[X:%.*]] 1537; 1538 call void @llvm.assume(i1 %cond) 1539 %sel = select i1 %cond, i8 %x, i8 %y 1540 ret i8 %sel 1541} 1542 1543; computeKnownBitsFromAssume() understands the 'not' of an assumed condition. 1544 1545define i8 @assume_cond_false(i1 %cond, i8 %x, i8 %y) { 1546; CHECK-LABEL: @assume_cond_false( 1547; CHECK-NEXT: [[NOTCOND:%.*]] = xor i1 [[COND:%.*]], true 1548; CHECK-NEXT: call void @llvm.assume(i1 [[NOTCOND]]) 1549; CHECK-NEXT: ret i8 [[Y:%.*]] 1550; 1551 %notcond = xor i1 %cond, true 1552 call void @llvm.assume(i1 %notcond) 1553 %sel = select i1 %cond, i8 %x, i8 %y 1554 ret i8 %sel 1555} 1556 1557; Test case to make sure we don't consider an all ones float values for converting the select into a sext. 1558define <4 x float> @PR33721(<4 x float> %w) { 1559; CHECK-LABEL: @PR33721( 1560; CHECK-NEXT: entry: 1561; CHECK-NEXT: [[TMP0:%.*]] = fcmp ole <4 x float> [[W:%.*]], zeroinitializer 1562; CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> [[TMP0]], <4 x float> <float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000>, <4 x float> zeroinitializer 1563; CHECK-NEXT: ret <4 x float> [[TMP1]] 1564; 1565entry: 1566 %0 = fcmp ole <4 x float> %w, zeroinitializer 1567 %1 = select <4 x i1> %0, <4 x float> <float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000>, <4 x float> zeroinitializer 1568 ret <4 x float> %1 1569} 1570 1571; select(C, binop(select(C, X, Y), W), Z) -> select(C, binop(X, W), Z) 1572define i8 @test87(i1 %cond, i8 %w, i8 %x, i8 %y, i8 %z) { 1573; CHECK-LABEL: @test87( 1574; CHECK-NEXT: [[B:%.*]] = add i8 [[X:%.*]], [[W:%.*]] 1575; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], i8 [[B]], i8 [[Z:%.*]] 1576; CHECK-NEXT: ret i8 [[C]] 1577; 1578 %a = select i1 %cond, i8 %x, i8 %y 1579 %b = add i8 %a, %w 1580 %c = select i1 %cond, i8 %b, i8 %z 1581 ret i8 %c 1582} 1583 1584; select(C, binop(select(C, X, Y), W), Z) -> select(C, Z, binop(Y, W)) 1585define i8 @test88(i1 %cond, i8 %w, i8 %x, i8 %y, i8 %z) { 1586; CHECK-LABEL: @test88( 1587; CHECK-NEXT: [[B:%.*]] = sub i8 [[Y:%.*]], [[W:%.*]] 1588; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], i8 [[Z:%.*]], i8 [[B]] 1589; CHECK-NEXT: ret i8 [[C]] 1590; 1591 %a = select i1 %cond, i8 %x, i8 %y 1592 %b = sub i8 %a, %w 1593 %c = select i1 %cond, i8 %z, i8 %b 1594 ret i8 %c 1595} 1596 1597; select(C, Z, binop(W, select(C, X, Y))) -> select(C, binop(X, W), Z) 1598define i8 @test89(i1 %cond, i8 %w, i8 %x, i8 %y, i8 %z) { 1599; CHECK-LABEL: @test89( 1600; CHECK-NEXT: [[B:%.*]] = and i8 [[X:%.*]], [[W:%.*]] 1601; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], i8 [[B]], i8 [[Z:%.*]] 1602; CHECK-NEXT: ret i8 [[C]] 1603; 1604 %a = select i1 %cond, i8 %x, i8 %y 1605 %b = and i8 %w, %a 1606 %c = select i1 %cond, i8 %b, i8 %z 1607 ret i8 %c 1608} 1609 1610; select(C, Z, binop(W, select(C, X, Y))) -> select(C, Z, binop(W, Y)) 1611define i8 @test90(i1 %cond, i8 %w, i8 %x, i8 %y, i8 %z) { 1612; CHECK-LABEL: @test90( 1613; CHECK-NEXT: [[B:%.*]] = or i8 [[Y:%.*]], [[W:%.*]] 1614; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], i8 [[Z:%.*]], i8 [[B]] 1615; CHECK-NEXT: ret i8 [[C]] 1616; 1617 %a = select i1 %cond, i8 %x, i8 %y 1618 %b = or i8 %w, %a 1619 %c = select i1 %cond, i8 %z, i8 %b 1620 ret i8 %c 1621} 1622 1623define i32 @test_shl_zext_bool(i1 %t) { 1624; CHECK-LABEL: @test_shl_zext_bool( 1625; CHECK-NEXT: [[R:%.*]] = select i1 [[T:%.*]], i32 4, i32 0 1626; CHECK-NEXT: ret i32 [[R]] 1627; 1628 %r = select i1 %t, i32 4, i32 0 1629 ret i32 %r 1630} 1631 1632define <2 x i32> @test_shl_zext_bool_splat(<2 x i1> %t) { 1633; CHECK-LABEL: @test_shl_zext_bool_splat( 1634; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T:%.*]], <2 x i32> <i32 8, i32 8>, <2 x i32> zeroinitializer 1635; CHECK-NEXT: ret <2 x i32> [[R]] 1636; 1637 %r = select <2 x i1> %t, <2 x i32> <i32 8, i32 8>, <2 x i32> zeroinitializer 1638 ret <2 x i32> %r 1639} 1640 1641define <2 x i32> @test_shl_zext_bool_vec(<2 x i1> %t) { 1642; CHECK-LABEL: @test_shl_zext_bool_vec( 1643; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T:%.*]], <2 x i32> <i32 4, i32 8>, <2 x i32> zeroinitializer 1644; CHECK-NEXT: ret <2 x i32> [[R]] 1645; 1646 %r = select <2 x i1> %t, <2 x i32> <i32 4, i32 8>, <2 x i32> zeroinitializer 1647 ret <2 x i32> %r 1648} 1649 1650define float @copysign1(float %x) { 1651; CHECK-LABEL: @copysign1( 1652; CHECK-NEXT: [[R:%.*]] = call float @llvm.copysign.f32(float 1.000000e+00, float [[X:%.*]]) 1653; CHECK-NEXT: ret float [[R]] 1654; 1655 %i = bitcast float %x to i32 1656 %ispos = icmp sgt i32 %i, -1 1657 %r = select i1 %ispos, float 1.0, float -1.0 1658 ret float %r 1659} 1660 1661define <2 x float> @copysign2(<2 x float> %x) { 1662; CHECK-LABEL: @copysign2( 1663; CHECK-NEXT: [[TMP1:%.*]] = fneg nsz <2 x float> [[X:%.*]] 1664; CHECK-NEXT: [[R:%.*]] = call nsz <2 x float> @llvm.copysign.v2f32(<2 x float> <float 4.200000e+01, float 4.200000e+01>, <2 x float> [[TMP1]]) 1665; CHECK-NEXT: ret <2 x float> [[R]] 1666; 1667 %i = bitcast <2 x float> %x to <2 x i32> 1668 %isneg = icmp slt <2 x i32> %i, zeroinitializer 1669 %r = select nsz <2 x i1> %isneg, <2 x float> <float 42.0, float 42.0>, <2 x float> <float -42.0, float -42.0> 1670 ret <2 x float> %r 1671} 1672 1673define float @copysign3(float %x) { 1674; CHECK-LABEL: @copysign3( 1675; CHECK-NEXT: [[TMP1:%.*]] = fneg fast float [[X:%.*]] 1676; CHECK-NEXT: [[R:%.*]] = call fast float @llvm.copysign.f32(float 4.300000e+01, float [[TMP1]]) 1677; CHECK-NEXT: ret float [[R]] 1678; 1679 %i = bitcast float %x to i32 1680 %ispos = icmp ult i32 %i, 2147483648 1681 %r = select fast i1 %ispos, float -43.0, float 43.0 1682 ret float %r 1683} 1684 1685; TODO: Allow undefs when matching vectors. 1686 1687define <2 x float> @copysign4(<2 x float> %x) { 1688; CHECK-LABEL: @copysign4( 1689; CHECK-NEXT: [[I:%.*]] = bitcast <2 x float> [[X:%.*]] to <2 x i32> 1690; CHECK-NEXT: [[ISNEG:%.*]] = icmp slt <2 x i32> [[I]], zeroinitializer 1691; CHECK-NEXT: [[R:%.*]] = select nnan arcp <2 x i1> [[ISNEG]], <2 x float> <float 4.200000e+01, float undef>, <2 x float> <float -4.200000e+01, float -4.200000e+01> 1692; CHECK-NEXT: ret <2 x float> [[R]] 1693; 1694 %i = bitcast <2 x float> %x to <2 x i32> 1695 %isneg = icmp ugt <2 x i32> %i, <i32 2147483647, i32 2147483647> 1696 %r = select arcp nnan <2 x i1> %isneg, <2 x float> <float 42.0, float undef>, <2 x float> <float -42.0, float -42.0> 1697 ret <2 x float> %r 1698} 1699 1700declare void @use1(i1) 1701 1702; Negative test 1703 1704define float @copysign_extra_use(float %x) { 1705; CHECK-LABEL: @copysign_extra_use( 1706; CHECK-NEXT: [[I:%.*]] = bitcast float [[X:%.*]] to i32 1707; CHECK-NEXT: [[ISNEG:%.*]] = icmp slt i32 [[I]], 0 1708; CHECK-NEXT: call void @use1(i1 [[ISNEG]]) 1709; CHECK-NEXT: [[R:%.*]] = select i1 [[ISNEG]], float -4.400000e+01, float 4.400000e+01 1710; CHECK-NEXT: ret float [[R]] 1711; 1712 %i = bitcast float %x to i32 1713 %isneg = icmp ugt i32 %i, 2147483647 1714 call void @use1(i1 %isneg) 1715 %r = select i1 %isneg, float -44.0, float 44.0 1716 ret float %r 1717} 1718 1719; Negative test 1720 1721define float @copysign_type_mismatch(double %x) { 1722; CHECK-LABEL: @copysign_type_mismatch( 1723; CHECK-NEXT: [[I:%.*]] = bitcast double [[X:%.*]] to i64 1724; CHECK-NEXT: [[ISPOS:%.*]] = icmp sgt i64 [[I]], -1 1725; CHECK-NEXT: [[R:%.*]] = select i1 [[ISPOS]], float 1.000000e+00, float -1.000000e+00 1726; CHECK-NEXT: ret float [[R]] 1727; 1728 %i = bitcast double %x to i64 1729 %ispos = icmp sgt i64 %i, -1 1730 %r = select i1 %ispos, float 1.0, float -1.0 1731 ret float %r 1732} 1733 1734; Negative test 1735 1736define float @copysign_wrong_cmp(float %x) { 1737; CHECK-LABEL: @copysign_wrong_cmp( 1738; CHECK-NEXT: [[I:%.*]] = bitcast float [[X:%.*]] to i32 1739; CHECK-NEXT: [[ISPOS:%.*]] = icmp sgt i32 [[I]], 0 1740; CHECK-NEXT: [[R:%.*]] = select i1 [[ISPOS]], float 1.000000e+00, float -1.000000e+00 1741; CHECK-NEXT: ret float [[R]] 1742; 1743 %i = bitcast float %x to i32 1744 %ispos = icmp sgt i32 %i, 0 1745 %r = select i1 %ispos, float 1.0, float -1.0 1746 ret float %r 1747} 1748 1749; Negative test 1750 1751define float @copysign_wrong_const(float %x) { 1752; CHECK-LABEL: @copysign_wrong_const( 1753; CHECK-NEXT: [[I:%.*]] = bitcast float [[X:%.*]] to i32 1754; CHECK-NEXT: [[ISPOS:%.*]] = icmp sgt i32 [[I]], -1 1755; CHECK-NEXT: [[R:%.*]] = select i1 [[ISPOS]], float 2.000000e+00, float -1.000000e+00 1756; CHECK-NEXT: ret float [[R]] 1757; 1758 %i = bitcast float %x to i32 1759 %ispos = icmp sgt i32 %i, -1 1760 %r = select i1 %ispos, float 2.0, float -1.0 1761 ret float %r 1762} 1763 1764; TODO: we can replace select with a Phi. 1765define i32 @select_dominating_cond(i1 %cond, i32 %x, i32 %y) { 1766; CHECK-LABEL: @select_dominating_cond( 1767; CHECK-NEXT: entry: 1768; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 1769; CHECK: if.true: 1770; CHECK-NEXT: br label [[MERGE:%.*]] 1771; CHECK: if.false: 1772; CHECK-NEXT: br label [[MERGE]] 1773; CHECK: merge: 1774; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[Y:%.*]], [[IF_FALSE]] ], [ [[X:%.*]], [[IF_TRUE]] ] 1775; CHECK-NEXT: ret i32 [[S]] 1776; 1777entry: 1778 br i1 %cond, label %if.true, label %if.false 1779 1780if.true: 1781 br label %merge 1782 1783if.false: 1784 br label %merge 1785 1786merge: 1787 %s = select i1 %cond, i32 %x, i32 %y 1788 ret i32 %s 1789} 1790 1791define i32 @select_dominating_inverted(i1 %cond, i32 %x, i32 %y) { 1792; CHECK-LABEL: @select_dominating_inverted( 1793; CHECK-NEXT: entry: 1794; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]] 1795; CHECK: if.true: 1796; CHECK-NEXT: br label [[MERGE:%.*]] 1797; CHECK: if.false: 1798; CHECK-NEXT: br label [[MERGE]] 1799; CHECK: merge: 1800; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[X:%.*]], [[IF_FALSE]] ], [ [[Y:%.*]], [[IF_TRUE]] ] 1801; CHECK-NEXT: ret i32 [[S]] 1802; 1803entry: 1804 %inverted = xor i1 %cond, 1 1805 br i1 %inverted, label %if.true, label %if.false 1806 1807if.true: 1808 br label %merge 1809 1810if.false: 1811 br label %merge 1812 1813merge: 1814 %s = select i1 %cond, i32 %x, i32 %y 1815 ret i32 %s 1816} 1817 1818; More complex CFG: the block with select has multiple predecessors. 1819define i32 @select_dominating_cond_multiple_preds(i1 %cond, i1 %cond2, i1 %cond3, i32 %x, i32 %y) { 1820; CHECK-LABEL: @select_dominating_cond_multiple_preds( 1821; CHECK-NEXT: entry: 1822; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 1823; CHECK: if.true: 1824; CHECK-NEXT: br i1 [[COND2:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_TRUE_2:%.*]] 1825; CHECK: if.true.1: 1826; CHECK-NEXT: br label [[MERGE:%.*]] 1827; CHECK: if.true.2: 1828; CHECK-NEXT: br label [[MERGE]] 1829; CHECK: if.false: 1830; CHECK-NEXT: br i1 [[COND3:%.*]], label [[IF_FALSE_1:%.*]], label [[EXIT:%.*]] 1831; CHECK: if.false.1: 1832; CHECK-NEXT: br label [[MERGE]] 1833; CHECK: merge: 1834; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[Y:%.*]], [[IF_FALSE_1]] ], [ [[X:%.*]], [[IF_TRUE_2]] ], [ [[X]], [[IF_TRUE_1]] ] 1835; CHECK-NEXT: ret i32 [[S]] 1836; CHECK: exit: 1837; CHECK-NEXT: ret i32 0 1838; 1839entry: 1840 br i1 %cond, label %if.true, label %if.false 1841 1842if.true: 1843 br i1 %cond2, label %if.true.1, label %if.true.2 1844 1845if.true.1: 1846 br label %merge 1847 1848if.true.2: 1849 br label %merge 1850 1851if.false: 1852 br i1 %cond3, label %if.false.1, label %exit 1853 1854if.false.1: 1855 br label %merge 1856 1857merge: 1858 %s = select i1 %cond, i32 %x, i32 %y 1859 ret i32 %s 1860 1861exit: 1862 ret i32 0 1863} 1864 1865; More complex CFG for inverted case: the block with select has multiple predecessors. 1866define i32 @select_dominating_cond_inverted_multiple_preds(i1 %cond, i1 %cond2, i1 %cond3, i32 %x, i32 %y) { 1867; CHECK-LABEL: @select_dominating_cond_inverted_multiple_preds( 1868; CHECK-NEXT: entry: 1869; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]] 1870; CHECK: if.true: 1871; CHECK-NEXT: br i1 [[COND2:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_TRUE_2:%.*]] 1872; CHECK: if.true.1: 1873; CHECK-NEXT: br label [[MERGE:%.*]] 1874; CHECK: if.true.2: 1875; CHECK-NEXT: br label [[MERGE]] 1876; CHECK: if.false: 1877; CHECK-NEXT: br i1 [[COND3:%.*]], label [[IF_FALSE_1:%.*]], label [[EXIT:%.*]] 1878; CHECK: if.false.1: 1879; CHECK-NEXT: br label [[MERGE]] 1880; CHECK: merge: 1881; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[X:%.*]], [[IF_FALSE_1]] ], [ [[Y:%.*]], [[IF_TRUE_2]] ], [ [[Y]], [[IF_TRUE_1]] ] 1882; CHECK-NEXT: ret i32 [[S]] 1883; CHECK: exit: 1884; CHECK-NEXT: ret i32 0 1885; 1886entry: 1887 %inverted = xor i1 %cond, 1 1888 br i1 %inverted, label %if.true, label %if.false 1889 1890if.true: 1891 br i1 %cond2, label %if.true.1, label %if.true.2 1892 1893if.true.1: 1894 br label %merge 1895 1896if.true.2: 1897 br label %merge 1898 1899if.false: 1900 br i1 %cond3, label %if.false.1, label %exit 1901 1902if.false.1: 1903 br label %merge 1904 1905merge: 1906 %s = select i1 %cond, i32 %x, i32 %y 1907 ret i32 %s 1908 1909exit: 1910 ret i32 0 1911} 1912 1913; More complex CFG for inverted case: the block with select has multiple predecessors that can duplicate. 1914define i32 @select_dominating_cond_inverted_multiple_duplicating_preds(i1 %cond, i32 %cond2, i1 %cond3, i32 %x, i32 %y) { 1915; CHECK-LABEL: @select_dominating_cond_inverted_multiple_duplicating_preds( 1916; CHECK-NEXT: entry: 1917; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]] 1918; CHECK: if.true: 1919; CHECK-NEXT: switch i32 [[COND2:%.*]], label [[SWITCH_CASE_1:%.*]] [ 1920; CHECK-NEXT: i32 1, label [[MERGE:%.*]] 1921; CHECK-NEXT: i32 2, label [[MERGE]] 1922; CHECK-NEXT: i32 3, label [[MERGE]] 1923; CHECK-NEXT: ] 1924; CHECK: switch.case.1: 1925; CHECK-NEXT: br label [[MERGE]] 1926; CHECK: if.false: 1927; CHECK-NEXT: br i1 [[COND3:%.*]], label [[IF_FALSE_1:%.*]], label [[EXIT:%.*]] 1928; CHECK: if.false.1: 1929; CHECK-NEXT: br label [[MERGE]] 1930; CHECK: merge: 1931; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[X:%.*]], [[IF_FALSE_1]] ], [ [[Y:%.*]], [[SWITCH_CASE_1]] ], [ [[Y]], [[IF_TRUE]] ], [ [[Y]], [[IF_TRUE]] ], [ [[Y]], [[IF_TRUE]] ] 1932; CHECK-NEXT: ret i32 [[S]] 1933; CHECK: exit: 1934; CHECK-NEXT: ret i32 0 1935; 1936entry: 1937 %inverted = xor i1 %cond, 1 1938 br i1 %inverted, label %if.true, label %if.false 1939 1940if.true: 1941 switch i32 %cond2, label %switch.case.1 [ 1942 i32 1, label %merge 1943 i32 2, label %merge 1944 i32 3, label %merge 1945 ] 1946 1947switch.case.1: 1948 br label %merge 1949 1950if.false: 1951 br i1 %cond3, label %if.false.1, label %exit 1952 1953if.false.1: 1954 br label %merge 1955 1956merge: 1957 %s = select i1 %cond, i32 %x, i32 %y 1958 ret i32 %s 1959 1960exit: 1961 ret i32 0 1962} 1963 1964; Negative test: currently we take condition from IDom, but might be willing to expand it in the future. 1965define i32 @select_not_imm_dominating_cond_neg(i1 %cond, i32 %x, i32 %y) { 1966; CHECK-LABEL: @select_not_imm_dominating_cond_neg( 1967; CHECK-NEXT: entry: 1968; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 1969; CHECK: if.true: 1970; CHECK-NEXT: br label [[MERGE:%.*]] 1971; CHECK: if.false: 1972; CHECK-NEXT: br label [[MERGE]] 1973; CHECK: merge: 1974; CHECK-NEXT: br label [[EXIT:%.*]] 1975; CHECK: exit: 1976; CHECK-NEXT: [[S:%.*]] = select i1 [[COND]], i32 [[X:%.*]], i32 [[Y:%.*]] 1977; CHECK-NEXT: ret i32 [[S]] 1978; 1979entry: 1980 br i1 %cond, label %if.true, label %if.false 1981 1982if.true: 1983 br label %merge 1984 1985if.false: 1986 br label %merge 1987 1988merge: 1989 br label %exit 1990 1991exit: 1992 %s = select i1 %cond, i32 %x, i32 %y 1993 ret i32 %s 1994} 1995 1996; Shows how we can leverage dominance to eliminate duplicating selects. 1997define i32 @select_dominance_chain(i1 %cond, i32 %x, i32 %y) { 1998; CHECK-LABEL: @select_dominance_chain( 1999; CHECK-NEXT: entry: 2000; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_FALSE_1:%.*]] 2001; CHECK: if.true.1: 2002; CHECK-NEXT: br label [[MERGE_1:%.*]] 2003; CHECK: if.false.1: 2004; CHECK-NEXT: br label [[MERGE_1]] 2005; CHECK: merge.1: 2006; CHECK-NEXT: br i1 [[COND]], label [[IF_TRUE_2:%.*]], label [[IF_FALSE_2:%.*]] 2007; CHECK: if.true.2: 2008; CHECK-NEXT: br label [[MERGE_2:%.*]] 2009; CHECK: if.false.2: 2010; CHECK-NEXT: br label [[MERGE_2]] 2011; CHECK: merge.2: 2012; CHECK-NEXT: br i1 [[COND]], label [[IF_TRUE_3:%.*]], label [[IF_FALSE_3:%.*]] 2013; CHECK: if.true.3: 2014; CHECK-NEXT: br label [[MERGE_3:%.*]] 2015; CHECK: if.false.3: 2016; CHECK-NEXT: br label [[MERGE_3]] 2017; CHECK: merge.3: 2018; CHECK-NEXT: [[S_1:%.*]] = phi i32 [ [[Y:%.*]], [[IF_FALSE_3]] ], [ [[X:%.*]], [[IF_TRUE_3]] ] 2019; CHECK-NEXT: [[SUM_2:%.*]] = mul i32 [[S_1]], 3 2020; CHECK-NEXT: ret i32 [[SUM_2]] 2021; 2022entry: 2023 br i1 %cond, label %if.true.1, label %if.false.1 2024 2025if.true.1: 2026 br label %merge.1 2027 2028if.false.1: 2029 br label %merge.1 2030 2031merge.1: 2032 %s.1 = select i1 %cond, i32 %x, i32 %y 2033 br i1 %cond, label %if.true.2, label %if.false.2 2034 2035if.true.2: 2036 br label %merge.2 2037 2038if.false.2: 2039 br label %merge.2 2040 2041merge.2: 2042 %s.2 = select i1 %cond, i32 %x, i32 %y 2043 br i1 %cond, label %if.true.3, label %if.false.3 2044 2045if.true.3: 2046 br label %merge.3 2047 2048if.false.3: 2049 br label %merge.3 2050 2051merge.3: 2052 %s.3 = select i1 %cond, i32 %x, i32 %y 2053 %sum.1 = add i32 %s.1, %s.2 2054 %sum.2 = add i32 %sum.1, %s.3 2055 ret i32 %sum.2 2056} 2057 2058; TODO: We can replace select with a Phi and then sink a and b to respective 2059; branches. 2060define i32 @select_dominating_cond_and_sink(i1 %cond, i32 %x, i32 %y) { 2061; CHECK-LABEL: @select_dominating_cond_and_sink( 2062; CHECK-NEXT: entry: 2063; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 2064; CHECK: if.true: 2065; CHECK-NEXT: br label [[MERGE:%.*]] 2066; CHECK: if.false: 2067; CHECK-NEXT: br label [[MERGE]] 2068; CHECK: merge: 2069; CHECK-NEXT: [[B:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]] 2070; CHECK-NEXT: [[A:%.*]] = add i32 [[X]], [[Y]] 2071; CHECK-NEXT: [[S:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]] 2072; CHECK-NEXT: ret i32 [[S]] 2073; 2074entry: 2075 %a = add i32 %x, %y 2076 %b = mul i32 %x, %y 2077 br i1 %cond, label %if.true, label %if.false 2078 2079if.true: 2080 br label %merge 2081 2082if.false: 2083 br label %merge 2084 2085merge: 2086 %s = select i1 %cond, i32 %a, i32 %b 2087 ret i32 %s 2088} 2089 2090define i32 @select_dominating_cond_same_labels(i1 %cond) { 2091; CHECK-LABEL: @select_dominating_cond_same_labels( 2092; CHECK-NEXT: entry: 2093; CHECK-NEXT: br i1 false, label [[EXIT:%.*]], label [[EXIT]] 2094; CHECK: exit: 2095; CHECK-NEXT: [[RESULT:%.*]] = select i1 [[COND:%.*]], i32 123, i32 456 2096; CHECK-NEXT: ret i32 [[RESULT]] 2097; 2098entry: 2099 %result = select i1 %cond, i32 123, i32 456 2100 br i1 %cond, label %exit, label %exit 2101exit: 2102 ret i32 %result 2103} 2104 2105define i32 @select_phi_same_condition(i1 %cond, i32 %x, i32 %y, i32 %z) { 2106; CHECK-LABEL: @select_phi_same_condition( 2107; CHECK-NEXT: entry: 2108; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 2109; CHECK: if.true: 2110; CHECK-NEXT: br label [[MERGE:%.*]] 2111; CHECK: if.false: 2112; CHECK-NEXT: br label [[MERGE]] 2113; CHECK: merge: 2114; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[Z:%.*]], [[IF_FALSE]] ], [ [[X:%.*]], [[IF_TRUE]] ] 2115; CHECK-NEXT: ret i32 [[S]] 2116; 2117entry: 2118 br i1 %cond, label %if.true, label %if.false 2119 2120if.true: 2121 br label %merge 2122 2123if.false: 2124 br label %merge 2125 2126merge: 2127 %phi = phi i32 [0, %if.true], [%z, %if.false] 2128 %s = select i1 %cond, i32 %x, i32 %phi 2129 ret i32 %s 2130} 2131 2132 2133; TODO: Replace with phi[a, c] and sink them to respective branches. 2134define i32 @select_phi_same_condition_sink(i1 %cond, i32 %x, i32 %y, i32 %z) { 2135; CHECK-LABEL: @select_phi_same_condition_sink( 2136; CHECK-NEXT: entry: 2137; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 2138; CHECK: if.true: 2139; CHECK-NEXT: br label [[MERGE:%.*]] 2140; CHECK: if.false: 2141; CHECK-NEXT: [[B:%.*]] = mul i32 [[X:%.*]], [[Z:%.*]] 2142; CHECK-NEXT: br label [[MERGE]] 2143; CHECK: merge: 2144; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[IF_TRUE]] ], [ [[B]], [[IF_FALSE]] ] 2145; CHECK-NEXT: [[A:%.*]] = add i32 [[X]], [[Y:%.*]] 2146; CHECK-NEXT: [[S:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[PHI]] 2147; CHECK-NEXT: ret i32 [[S]] 2148; 2149entry: 2150 %a = add i32 %x, %y 2151 %b = mul i32 %x, %z 2152 br i1 %cond, label %if.true, label %if.false 2153 2154if.true: 2155 br label %merge 2156 2157if.false: 2158 br label %merge 2159 2160merge: 2161 %phi = phi i32 [0, %if.true], [%b, %if.false] 2162 %s = select i1 %cond, i32 %a, i32 %phi 2163 ret i32 %s 2164} 2165 2166declare i32 @__gxx_personality_v0(...) 2167declare i1 @foo() 2168 2169define i32 @test_invoke_neg(i32 %x, i32 %y) nounwind uwtable ssp personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 2170; CHECK-LABEL: @test_invoke_neg( 2171; CHECK-NEXT: entry: 2172; CHECK-NEXT: [[COND:%.*]] = invoke i1 @foo() 2173; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 2174; CHECK: invoke.cont: 2175; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i32 [[X:%.*]], i32 [[Y:%.*]] 2176; CHECK-NEXT: ret i32 [[SEL]] 2177; CHECK: lpad: 2178; CHECK-NEXT: [[LP:%.*]] = landingpad { i1, i32 } 2179; CHECK-NEXT: filter [0 x i1] zeroinitializer 2180; CHECK-NEXT: unreachable 2181; 2182entry: 2183 %cond = invoke i1 @foo() 2184 to label %invoke.cont unwind label %lpad 2185 2186invoke.cont: 2187 %sel = select i1 %cond, i32 %x, i32 %y 2188 ret i32 %sel 2189 2190lpad: 2191 %lp = landingpad { i1, i32 } 2192 filter [0 x i1] zeroinitializer 2193 unreachable 2194} 2195 2196declare i32 @bar() 2197 2198define i32 @test_invoke_2_neg(i1 %cond, i32 %x, i32 %y) nounwind uwtable ssp personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 2199; CHECK-LABEL: @test_invoke_2_neg( 2200; CHECK-NEXT: entry: 2201; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 2202; CHECK: if.true: 2203; CHECK-NEXT: br label [[MERGE:%.*]] 2204; CHECK: if.false: 2205; CHECK-NEXT: [[RESULT:%.*]] = invoke i32 @bar() 2206; CHECK-NEXT: to label [[MERGE]] unwind label [[LPAD:%.*]] 2207; CHECK: merge: 2208; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[IF_TRUE]] ], [ [[RESULT]], [[IF_FALSE]] ] 2209; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i32 1, i32 [[PHI]] 2210; CHECK-NEXT: ret i32 [[SEL]] 2211; CHECK: lpad: 2212; CHECK-NEXT: [[LP:%.*]] = landingpad { i1, i32 } 2213; CHECK-NEXT: filter [0 x i1] zeroinitializer 2214; CHECK-NEXT: unreachable 2215; 2216entry: 2217 br i1 %cond, label %if.true, label %if.false 2218 2219if.true: 2220 br label %merge 2221 2222if.false: 2223 %result = invoke i32 @bar() 2224 to label %merge unwind label %lpad 2225 2226merge: 2227 %phi = phi i32 [ 0, %if.true ], [ %result, %if.false ] 2228 %sel = select i1 %cond, i32 1, i32 %phi 2229 ret i32 %sel 2230 2231lpad: 2232 %lp = landingpad { i1, i32 } 2233 filter [0 x i1] zeroinitializer 2234 unreachable 2235} 2236 2237define i32 @select_phi_same_condition_switch(i1 %cond, i32 %x, i32 %y) { 2238; CHECK-LABEL: @select_phi_same_condition_switch( 2239; CHECK-NEXT: entry: 2240; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 2241; CHECK: if.true: 2242; CHECK-NEXT: switch i32 [[X:%.*]], label [[EXIT:%.*]] [ 2243; CHECK-NEXT: i32 1, label [[MERGE:%.*]] 2244; CHECK-NEXT: i32 2, label [[MERGE]] 2245; CHECK-NEXT: ] 2246; CHECK: exit: 2247; CHECK-NEXT: ret i32 0 2248; CHECK: if.false: 2249; CHECK-NEXT: br label [[MERGE]] 2250; CHECK: merge: 2251; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[Y:%.*]], [[IF_FALSE]] ], [ [[X]], [[IF_TRUE]] ], [ [[X]], [[IF_TRUE]] ] 2252; CHECK-NEXT: ret i32 [[S]] 2253; 2254entry: 2255 br i1 %cond, label %if.true, label %if.false 2256 2257if.true: 2258 switch i32 %x, label %exit [ 2259 i32 1, label %merge 2260 i32 2, label %merge 2261 ] 2262 2263exit: 2264 ret i32 0 2265 2266if.false: 2267 br label %merge 2268 2269merge: 2270 %phi = phi i32 [0, %if.true], [0, %if.true], [%y, %if.false] 2271 %s = select i1 %cond, i32 %x, i32 %phi 2272 ret i32 %s 2273} 2274 2275define i32 @transit_different_values_through_phi(i1 %cond, i1 %cond2) { 2276; CHECK-LABEL: @transit_different_values_through_phi( 2277; CHECK-NEXT: entry: 2278; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 2279; CHECK: if.true: 2280; CHECK-NEXT: br i1 [[COND2:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_TRUE_2:%.*]] 2281; CHECK: if.true.1: 2282; CHECK-NEXT: br label [[MERGE:%.*]] 2283; CHECK: if.true.2: 2284; CHECK-NEXT: br label [[MERGE]] 2285; CHECK: if.false: 2286; CHECK-NEXT: br label [[MERGE]] 2287; CHECK: merge: 2288; CHECK-NEXT: [[S:%.*]] = phi i32 [ 3, [[IF_FALSE]] ], [ 2, [[IF_TRUE_2]] ], [ 1, [[IF_TRUE_1]] ] 2289; CHECK-NEXT: ret i32 [[S]] 2290; CHECK: exit: 2291; CHECK-NEXT: ret i32 0 2292; 2293entry: 2294 br i1 %cond, label %if.true, label %if.false 2295 2296if.true: 2297 br i1 %cond2, label %if.true.1, label %if.true.2 2298 2299if.true.1: 2300 br label %merge 2301 2302if.true.2: 2303 br label %merge 2304 2305if.false: 2306 br label %merge 2307 2308merge: 2309 %p = phi i32 [ 1, %if.true.1 ], [ 2, %if.true.2 ], [ 4, %if.false ] 2310 %s = select i1 %cond, i32 %p, i32 3 2311 ret i32 %s 2312 2313exit: 2314 ret i32 0 2315} 2316 2317define i32 @select_phi_degenerate(i1 %cond, i1 %cond2) { 2318; CHECK-LABEL: @select_phi_degenerate( 2319; CHECK-NEXT: entry: 2320; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOP:%.*]], label [[EXIT:%.*]] 2321; CHECK: loop: 2322; CHECK-NEXT: [[SELECT:%.*]] = phi i32 [ [[IV_INC:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ] 2323; CHECK-NEXT: [[IV_INC]] = add i32 [[SELECT]], 1 2324; CHECK-NEXT: br i1 [[COND2:%.*]], label [[LOOP]], label [[EXIT2:%.*]] 2325; CHECK: exit: 2326; CHECK-NEXT: ret i32 0 2327; CHECK: exit2: 2328; CHECK-NEXT: ret i32 [[IV_INC]] 2329; 2330entry: 2331 br i1 %cond, label %loop, label %exit 2332 2333loop: 2334 %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ] 2335 %select = select i1 %cond, i32 %iv, i32 -1 2336 %iv.inc = add i32 %select, 1 2337 br i1 %cond2, label %loop, label %exit2 2338 2339exit: 2340 ret i32 0 2341 2342exit2: 2343 ret i32 %iv.inc 2344} 2345 2346define i32 @test_select_into_phi_not_idom(i1 %cond, i32 %A, i32 %B) { 2347; CHECK-LABEL: @test_select_into_phi_not_idom( 2348; CHECK-NEXT: entry: 2349; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 2350; CHECK: if.true: 2351; CHECK-NEXT: br label [[MERGE:%.*]] 2352; CHECK: if.false: 2353; CHECK-NEXT: br label [[MERGE]] 2354; CHECK: merge: 2355; CHECK-NEXT: br label [[EXIT:%.*]] 2356; CHECK: exit: 2357; CHECK-NEXT: ret i32 [[A:%.*]] 2358; 2359entry: 2360 br i1 %cond, label %if.true, label %if.false 2361 2362if.true: 2363 br label %merge 2364 2365if.false: 2366 br label %merge 2367 2368merge: 2369 %phi = phi i32 [%A, %if.true], [%B, %if.false] 2370 br label %exit 2371 2372exit: 2373 %sel = select i1 %cond, i32 %phi, i32 %A 2374 ret i32 %sel 2375} 2376 2377define i32 @test_select_into_phi_not_idom_2(i1 %cond, i32 %A, i32 %B) { 2378; CHECK-LABEL: @test_select_into_phi_not_idom_2( 2379; CHECK-NEXT: entry: 2380; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 2381; CHECK: if.true: 2382; CHECK-NEXT: br label [[MERGE:%.*]] 2383; CHECK: if.false: 2384; CHECK-NEXT: br label [[MERGE]] 2385; CHECK: merge: 2386; CHECK-NEXT: br label [[EXIT:%.*]] 2387; CHECK: exit: 2388; CHECK-NEXT: ret i32 [[B:%.*]] 2389; 2390entry: 2391 br i1 %cond, label %if.true, label %if.false 2392 2393if.true: 2394 br label %merge 2395 2396if.false: 2397 br label %merge 2398 2399merge: 2400 %phi = phi i32 [%A, %if.true], [%B, %if.false] 2401 br label %exit 2402 2403exit: 2404 %sel = select i1 %cond, i32 %B, i32 %phi 2405 ret i32 %sel 2406} 2407 2408define i32 @test_select_into_phi_not_idom_inverted(i1 %cond, i32 %A, i32 %B) { 2409; CHECK-LABEL: @test_select_into_phi_not_idom_inverted( 2410; CHECK-NEXT: entry: 2411; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]] 2412; CHECK: if.true: 2413; CHECK-NEXT: br label [[MERGE:%.*]] 2414; CHECK: if.false: 2415; CHECK-NEXT: br label [[MERGE]] 2416; CHECK: merge: 2417; CHECK-NEXT: [[SEL:%.*]] = phi i32 [ [[B:%.*]], [[IF_FALSE]] ], [ [[A:%.*]], [[IF_TRUE]] ] 2418; CHECK-NEXT: br label [[EXIT:%.*]] 2419; CHECK: exit: 2420; CHECK-NEXT: ret i32 [[SEL]] 2421; 2422entry: 2423 %inverted = xor i1 %cond, 1 2424 br i1 %inverted, label %if.true, label %if.false 2425 2426if.true: 2427 br label %merge 2428 2429if.false: 2430 br label %merge 2431 2432merge: 2433 %phi = phi i32 [%A, %if.true], [%B, %if.false] 2434 br label %exit 2435 2436exit: 2437 %sel = select i1 %cond, i32 %phi, i32 %A 2438 ret i32 %sel 2439} 2440 2441define i32 @test_select_into_phi_not_idom_inverted_2(i1 %cond, i32 %A, i32 %B) { 2442; CHECK-LABEL: @test_select_into_phi_not_idom_inverted_2( 2443; CHECK-NEXT: entry: 2444; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]] 2445; CHECK: if.true: 2446; CHECK-NEXT: br label [[MERGE:%.*]] 2447; CHECK: if.false: 2448; CHECK-NEXT: br label [[MERGE]] 2449; CHECK: merge: 2450; CHECK-NEXT: [[SEL:%.*]] = phi i32 [ [[B:%.*]], [[IF_FALSE]] ], [ [[A:%.*]], [[IF_TRUE]] ] 2451; CHECK-NEXT: br label [[EXIT:%.*]] 2452; CHECK: exit: 2453; CHECK-NEXT: ret i32 [[SEL]] 2454; 2455entry: 2456 %inverted = xor i1 %cond, 1 2457 br i1 %inverted, label %if.true, label %if.false 2458 2459if.true: 2460 br label %merge 2461 2462if.false: 2463 br label %merge 2464 2465merge: 2466 %phi = phi i32 [%A, %if.true], [%B, %if.false] 2467 br label %exit 2468 2469exit: 2470 %sel = select i1 %cond, i32 %B, i32 %phi 2471 ret i32 %sel 2472} 2473 2474define i32 @test_select_into_phi_not_idom_no_dom_input_1(i1 %cond, i32 %A, i32 %B, i32 *%p) { 2475; CHECK-LABEL: @test_select_into_phi_not_idom_no_dom_input_1( 2476; CHECK-NEXT: entry: 2477; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 2478; CHECK: if.true: 2479; CHECK-NEXT: [[C:%.*]] = load i32, i32* [[P:%.*]], align 4 2480; CHECK-NEXT: br label [[MERGE:%.*]] 2481; CHECK: if.false: 2482; CHECK-NEXT: br label [[MERGE]] 2483; CHECK: merge: 2484; CHECK-NEXT: [[SEL:%.*]] = phi i32 [ [[A:%.*]], [[IF_FALSE]] ], [ [[C]], [[IF_TRUE]] ] 2485; CHECK-NEXT: br label [[EXIT:%.*]] 2486; CHECK: exit: 2487; CHECK-NEXT: ret i32 [[SEL]] 2488; 2489entry: 2490 br i1 %cond, label %if.true, label %if.false 2491 2492if.true: 2493 %C = load i32, i32* %p 2494 br label %merge 2495 2496if.false: 2497 br label %merge 2498 2499merge: 2500 %phi = phi i32 [%C, %if.true], [%B, %if.false] 2501 br label %exit 2502 2503exit: 2504 %sel = select i1 %cond, i32 %phi, i32 %A 2505 ret i32 %sel 2506} 2507 2508define i32 @test_select_into_phi_not_idom_no_dom_input_2(i1 %cond, i32 %A, i32 %B, i32 *%p) { 2509; CHECK-LABEL: @test_select_into_phi_not_idom_no_dom_input_2( 2510; CHECK-NEXT: entry: 2511; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 2512; CHECK: if.true: 2513; CHECK-NEXT: br label [[MERGE:%.*]] 2514; CHECK: if.false: 2515; CHECK-NEXT: [[C:%.*]] = load i32, i32* [[P:%.*]], align 4 2516; CHECK-NEXT: br label [[MERGE]] 2517; CHECK: merge: 2518; CHECK-NEXT: [[SEL:%.*]] = phi i32 [ [[C]], [[IF_FALSE]] ], [ [[B:%.*]], [[IF_TRUE]] ] 2519; CHECK-NEXT: br label [[EXIT:%.*]] 2520; CHECK: exit: 2521; CHECK-NEXT: ret i32 [[SEL]] 2522; 2523entry: 2524 br i1 %cond, label %if.true, label %if.false 2525 2526if.true: 2527 br label %merge 2528 2529if.false: 2530 %C = load i32, i32* %p 2531 br label %merge 2532 2533merge: 2534 %phi = phi i32 [%A, %if.true], [%C, %if.false] 2535 br label %exit 2536 2537exit: 2538 %sel = select i1 %cond, i32 %B, i32 %phi 2539 ret i32 %sel 2540} 2541 2542; Negative tests to ensure we don't remove selects with undef true/false values. 2543; See https://bugs.llvm.org/show_bug.cgi?id=31633 2544; https://lists.llvm.org/pipermail/llvm-dev/2016-October/106182.html 2545; https://reviews.llvm.org/D83360 2546define i32 @false_undef(i1 %cond, i32 %x) { 2547; CHECK-LABEL: @false_undef( 2548; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], i32 [[X:%.*]], i32 undef 2549; CHECK-NEXT: ret i32 [[S]] 2550; 2551 %s = select i1 %cond, i32 %x, i32 undef 2552 ret i32 %s 2553} 2554 2555define i32 @true_undef(i1 %cond, i32 %x) { 2556; CHECK-LABEL: @true_undef( 2557; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], i32 undef, i32 [[X:%.*]] 2558; CHECK-NEXT: ret i32 [[S]] 2559; 2560 %s = select i1 %cond, i32 undef, i32 %x 2561 ret i32 %s 2562} 2563 2564define <2 x i32> @false_undef_vec(i1 %cond, <2 x i32> %x) { 2565; CHECK-LABEL: @false_undef_vec( 2566; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], <2 x i32> [[X:%.*]], <2 x i32> undef 2567; CHECK-NEXT: ret <2 x i32> [[S]] 2568; 2569 %s = select i1 %cond, <2 x i32> %x, <2 x i32> undef 2570 ret <2 x i32> %s 2571} 2572 2573define <2 x i32> @true_undef_vec(i1 %cond, <2 x i32> %x) { 2574; CHECK-LABEL: @true_undef_vec( 2575; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], <2 x i32> undef, <2 x i32> [[X:%.*]] 2576; CHECK-NEXT: ret <2 x i32> [[S]] 2577; 2578 %s = select i1 %cond, <2 x i32> undef, <2 x i32> %x 2579 ret <2 x i32> %s 2580} 2581 2582define i8 @cond_freeze(i8 %x, i8 %y) { 2583; CHECK-LABEL: @cond_freeze( 2584; CHECK-NEXT: ret i8 [[X:%.*]] 2585; 2586 %cond.fr = freeze i1 undef 2587 %s = select i1 %cond.fr, i8 %x, i8 %y 2588 ret i8 %s 2589} 2590 2591define i8 @cond_freeze2(i8 %x, i8 %y) { 2592; CHECK-LABEL: @cond_freeze2( 2593; CHECK-NEXT: ret i8 1 2594; 2595 %cond.fr = freeze i1 undef 2596 %s = select i1 %cond.fr, i8 %x, i8 1 2597 ret i8 %s 2598} 2599 2600define i8 @cond_freeze3(i8 %x) { 2601; CHECK-LABEL: @cond_freeze3( 2602; CHECK-NEXT: ret i8 1 2603; 2604 %cond.fr = freeze i1 undef 2605 %s = select i1 %cond.fr, i8 1, i8 %x 2606 ret i8 %s 2607} 2608 2609define <2 x i8> @cond_freeze_vec(<2 x i8> %x) { 2610; CHECK-LABEL: @cond_freeze_vec( 2611; CHECK-NEXT: ret <2 x i8> <i8 1, i8 2> 2612; 2613 %cond.fr = freeze <2 x i1> <i1 undef, i1 undef> 2614 %s = select <2 x i1> %cond.fr, <2 x i8> <i8 1, i8 2>, <2 x i8> %x 2615 ret <2 x i8> %s 2616} 2617 2618declare void @foo2(i8, i8) 2619 2620define void @cond_freeze_multipleuses(i8 %x, i8 %y) { 2621; CHECK-LABEL: @cond_freeze_multipleuses( 2622; CHECK-NEXT: call void @foo2(i8 [[X:%.*]], i8 [[Y:%.*]]) 2623; CHECK-NEXT: ret void 2624; 2625 %cond.fr = freeze i1 undef 2626 %s = select i1 %cond.fr, i8 %x, i8 %y 2627 %s2 = select i1 %cond.fr, i8 %y, i8 %x 2628 call void @foo2(i8 %s, i8 %s2) 2629 ret void 2630} 2631 2632define i32 @select_freeze_icmp_eq(i32 %x, i32 %y) { 2633; CHECK-LABEL: @select_freeze_icmp_eq( 2634; CHECK-NEXT: ret i32 [[Y:%.*]] 2635; 2636 %c = icmp eq i32 %x, %y 2637 %c.fr = freeze i1 %c 2638 %v = select i1 %c.fr, i32 %x, i32 %y 2639 ret i32 %v 2640} 2641 2642define i32 @select_freeze_icmp_ne(i32 %x, i32 %y) { 2643; CHECK-LABEL: @select_freeze_icmp_ne( 2644; CHECK-NEXT: ret i32 [[X:%.*]] 2645; 2646 %c = icmp ne i32 %x, %y 2647 %c.fr = freeze i1 %c 2648 %v = select i1 %c.fr, i32 %x, i32 %y 2649 ret i32 %v 2650} 2651 2652define i32 @select_freeze_icmp_else(i32 %x, i32 %y) { 2653; CHECK-LABEL: @select_freeze_icmp_else( 2654; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 2655; CHECK-NEXT: [[C_FR:%.*]] = freeze i1 [[C]] 2656; CHECK-NEXT: [[V:%.*]] = select i1 [[C_FR]], i32 [[X]], i32 [[Y]] 2657; CHECK-NEXT: ret i32 [[V]] 2658; 2659 %c = icmp ult i32 %x, %y 2660 %c.fr = freeze i1 %c 2661 %v = select i1 %c.fr, i32 %x, i32 %y 2662 ret i32 %v 2663} 2664 2665declare void @use_i1_i32(i1, i32) 2666 2667define void @select_freeze_icmp_multuses(i32 %x, i32 %y) { 2668; CHECK-LABEL: @select_freeze_icmp_multuses( 2669; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]] 2670; CHECK-NEXT: [[C_FR:%.*]] = freeze i1 [[C]] 2671; CHECK-NEXT: [[V:%.*]] = select i1 [[C_FR]], i32 [[X]], i32 [[Y]] 2672; CHECK-NEXT: call void @use_i1_i32(i1 [[C_FR]], i32 [[V]]) 2673; CHECK-NEXT: ret void 2674; 2675 %c = icmp ne i32 %x, %y 2676 %c.fr = freeze i1 %c 2677 %v = select i1 %c.fr, i32 %x, i32 %y 2678 call void @use_i1_i32(i1 %c.fr, i32 %v) 2679 ret void 2680} 2681 2682define i32 @pr47322_more_poisonous_replacement(i32 %arg) { 2683; CHECK-LABEL: @pr47322_more_poisonous_replacement( 2684; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[ARG:%.*]], 0 2685; CHECK-NEXT: [[TRAILING:%.*]] = call i32 @llvm.cttz.i32(i32 [[ARG]], i1 immarg true), !range [[RNG0:![0-9]+]] 2686; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[ARG]], [[TRAILING]] 2687; CHECK-NEXT: [[R1_SROA_0_1:%.*]] = select i1 [[CMP]], i32 0, i32 [[SHIFTED]] 2688; CHECK-NEXT: ret i32 [[R1_SROA_0_1]] 2689; 2690 %cmp = icmp eq i32 %arg, 0 2691 %trailing = call i32 @llvm.cttz.i32(i32 %arg, i1 immarg true) 2692 %shifted = lshr i32 %arg, %trailing 2693 %r1.sroa.0.1 = select i1 %cmp, i32 0, i32 %shifted 2694 ret i32 %r1.sroa.0.1 2695} 2696 2697define i8 @select_replacement_add_eq(i8 %x, i8 %y) { 2698; CHECK-LABEL: @select_replacement_add_eq( 2699; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 1 2700; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 2, i8 [[Y:%.*]] 2701; CHECK-NEXT: ret i8 [[SEL]] 2702; 2703 %cmp = icmp eq i8 %x, 1 2704 %add = add i8 %x, 1 2705 %sel = select i1 %cmp, i8 %add, i8 %y 2706 ret i8 %sel 2707} 2708 2709define i8 @select_replacement_add_ne(i8 %x, i8 %y) { 2710; CHECK-LABEL: @select_replacement_add_ne( 2711; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[X:%.*]], 1 2712; CHECK-NEXT: call void @use(i1 [[CMP]]) 2713; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[Y:%.*]], i8 2 2714; CHECK-NEXT: ret i8 [[SEL]] 2715; 2716 %cmp = icmp ne i8 %x, 1 2717 call void @use(i1 %cmp) 2718 %add = add i8 %x, 1 2719 %sel = select i1 %cmp, i8 %y, i8 %add 2720 ret i8 %sel 2721} 2722 2723define i8 @select_replacement_add_nuw(i8 %x, i8 %y) { 2724; CHECK-LABEL: @select_replacement_add_nuw( 2725; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 1 2726; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 2, i8 [[Y:%.*]] 2727; CHECK-NEXT: ret i8 [[SEL]] 2728; 2729 %cmp = icmp eq i8 %x, 1 2730 %add = add nuw i8 %x, 1 2731 %sel = select i1 %cmp, i8 %add, i8 %y 2732 ret i8 %sel 2733} 2734 2735define i8 @select_replacement_sub_noundef(i8 %x, i8 noundef %y, i8 %z) { 2736; CHECK-LABEL: @select_replacement_sub_noundef( 2737; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]] 2738; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 0, i8 [[Z:%.*]] 2739; CHECK-NEXT: ret i8 [[SEL]] 2740; 2741 %cmp = icmp eq i8 %x, %y 2742 %sub = sub i8 %x, %y 2743 %sel = select i1 %cmp, i8 %sub, i8 %z 2744 ret i8 %sel 2745} 2746 2747; TODO: The transform is also safe without noundef. 2748define i8 @select_replacement_sub(i8 %x, i8 %y, i8 %z) { 2749; CHECK-LABEL: @select_replacement_sub( 2750; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]] 2751; CHECK-NEXT: [[SUB:%.*]] = sub i8 [[X]], [[Y]] 2752; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[SUB]], i8 [[Z:%.*]] 2753; CHECK-NEXT: ret i8 [[SEL]] 2754; 2755 %cmp = icmp eq i8 %x, %y 2756 %sub = sub i8 %x, %y 2757 %sel = select i1 %cmp, i8 %sub, i8 %z 2758 ret i8 %sel 2759} 2760 2761define i8 @select_replacement_shift_noundef(i8 %x, i8 %y, i8 %z) { 2762; CHECK-LABEL: @select_replacement_shift_noundef( 2763; CHECK-NEXT: [[SHR:%.*]] = lshr exact i8 [[X:%.*]], 1 2764; CHECK-NEXT: call void @use_i8(i8 noundef [[SHR]]) 2765; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[SHR]], [[Y:%.*]] 2766; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[X]], i8 [[Z:%.*]] 2767; CHECK-NEXT: ret i8 [[SEL]] 2768; 2769 %shr = lshr exact i8 %x, 1 2770 call void @use_i8(i8 noundef %shr) 2771 %cmp = icmp eq i8 %shr, %y 2772 %shl = shl i8 %y, 1 2773 %sel = select i1 %cmp, i8 %shl, i8 %z 2774 ret i8 %sel 2775} 2776 2777; TODO: The transform is also safe without noundef. 2778define i8 @select_replacement_shift(i8 %x, i8 %y, i8 %z) { 2779; CHECK-LABEL: @select_replacement_shift( 2780; CHECK-NEXT: [[SHR:%.*]] = lshr exact i8 [[X:%.*]], 1 2781; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[SHR]], [[Y:%.*]] 2782; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[Y]], 1 2783; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[SHL]], i8 [[Z:%.*]] 2784; CHECK-NEXT: ret i8 [[SEL]] 2785; 2786 %shr = lshr exact i8 %x, 1 2787 %cmp = icmp eq i8 %shr, %y 2788 %shl = shl i8 %y, 1 2789 %sel = select i1 %cmp, i8 %shl, i8 %z 2790 ret i8 %sel 2791} 2792 2793define i8 @select_replacement_loop(i8 %x, i8 %y, i8 %z) { 2794; CHECK-LABEL: @select_replacement_loop( 2795; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]] 2796; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[X]], i8 [[Z:%.*]] 2797; CHECK-NEXT: ret i8 [[SEL]] 2798; 2799 %cmp = icmp eq i8 %x, %y 2800 %sel = select i1 %cmp, i8 %x, i8 %z 2801 ret i8 %sel 2802} 2803 2804define i32 @select_replacement_loop2(i32 %arg, i32 %arg2) { 2805; CHECK-LABEL: @select_replacement_loop2( 2806; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[ARG:%.*]], [[ARG2:%.*]] 2807; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[DIV]], [[ARG2]] 2808; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MUL]], [[ARG]] 2809; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[DIV]], i32 undef 2810; CHECK-NEXT: ret i32 [[SEL]] 2811; 2812 %div = udiv i32 %arg, %arg2 2813 %mul = mul nsw i32 %div, %arg2 2814 %cmp = icmp eq i32 %mul, %arg 2815 %sel = select i1 %cmp, i32 %div, i32 undef 2816 ret i32 %sel 2817} 2818 2819; TODO: Dropping the inbounds flag should not be necessary for this fold. 2820define i8* @select_replacement_gep_inbounds(i8* %base, i64 %offset) { 2821; CHECK-LABEL: @select_replacement_gep_inbounds( 2822; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, i8* [[BASE:%.*]], i64 [[OFFSET:%.*]] 2823; CHECK-NEXT: ret i8* [[GEP]] 2824; 2825 %cmp = icmp eq i64 %offset, 0 2826 %gep = getelementptr inbounds i8, i8* %base, i64 %offset 2827 %sel = select i1 %cmp, i8* %base, i8* %gep 2828 ret i8* %sel 2829} 2830 2831declare void @use(i1) 2832declare void @use_i8(i8) 2833declare i32 @llvm.cttz.i32(i32, i1 immarg) 2834