1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=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:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[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:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[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_poison_elt(<2 x i1> %C, <2 x i1> %X) { 45; CHECK-LABEL: @trueval_is_true_vec_poison_elt( 46; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> <i1 poison, i1 true>, <2 x i1> [[X:%.*]] 47; CHECK-NEXT: ret <2 x i1> [[R]] 48; 49 %R = select <2 x i1> %C, <2 x i1> <i1 poison, 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:%.*]] = select i1 [[C:%.*]], i1 [[X:%.*]], i1 false 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:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[X:%.*]], <2 x i1> zeroinitializer 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:%.*]] = select <vscale x 2 x i1> [[C:%.*]], <vscale x 2 x i1> [[X:%.*]], <vscale x 2 x i1> zeroinitializer 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:%.*]] = select i1 [[NOT_C]], i1 [[X:%.*]], i1 false 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:%.*]], splat (i1 true) 93; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[NOT_C]], <2 x i1> [[X:%.*]], <2 x i1> zeroinitializer 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:%.*]], splat (i1 true) 103; CHECK-NEXT: [[R:%.*]] = select <vscale x 2 x i1> [[NOT_C]], <vscale x 2 x i1> [[X:%.*]], <vscale x 2 x i1> zeroinitializer 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:%.*]] = select i1 [[NOT_C]], i1 true, i1 [[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:%.*]], splat (i1 true) 123; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[NOT_C]], <2 x i1> splat (i1 true), <2 x i1> [[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:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false 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:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> [[B:%.*]], <2 x i1> zeroinitializer 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:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[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:%.*]] = select <2 x i1> [[A:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[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_A:%.*]] = xor i1 [[A:%.*]], true 169; CHECK-NEXT: [[C:%.*]] = select i1 [[NOT_A]], i1 [[B:%.*]], i1 false 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_A:%.*]] = xor <2 x i1> [[A:%.*]], splat (i1 true) 180; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[NOT_A]], <2 x i1> [[B:%.*]], <2 x i1> zeroinitializer 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_A:%.*]] = xor i1 [[A:%.*]], true 191; CHECK-NEXT: [[C:%.*]] = select i1 [[NOT_A]], i1 true, i1 [[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_A:%.*]] = xor <2 x i1> [[A:%.*]], splat (i1 true) 202; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[NOT_A]], <2 x i1> splat (i1 true), <2 x i1> [[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 [[A:%.*]], [[B]] 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> [[A:%.*]], [[B]] 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:%.*]], splat (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:%.*]] = select i1 [[NOT_C]], i1 true, i1 [[R1]] 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:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[R1]] 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, ptr %P) { 342; CHECK-LABEL: @test16( 343; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P:%.*]], align 4 344; CHECK-NEXT: ret i32 [[V]] 345; 346 %P2 = select i1 %C, ptr %P, ptr null 347 %V = load i32, ptr %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, ptr addrspace(1) %P) { 353; CHECK-LABEL: @test16_neg( 354; CHECK-NEXT: [[P2:%.*]] = select i1 [[C:%.*]], ptr addrspace(1) [[P:%.*]], ptr addrspace(1) null 355; CHECK-NEXT: [[V:%.*]] = load i32, ptr addrspace(1) [[P2]], align 4 356; CHECK-NEXT: ret i32 [[V]] 357; 358 %P2 = select i1 %C, ptr addrspace(1) %P, ptr addrspace(1) null 359 %V = load i32, ptr addrspace(1) %P2 360 ret i32 %V 361} 362 363define i32 @test16_neg2(i1 %C, ptr addrspace(1) %P) { 364; CHECK-LABEL: @test16_neg2( 365; CHECK-NEXT: [[P2:%.*]] = select i1 [[C:%.*]], ptr addrspace(1) null, ptr addrspace(1) [[P:%.*]] 366; CHECK-NEXT: [[V:%.*]] = load i32, ptr addrspace(1) [[P2]], align 4 367; CHECK-NEXT: ret i32 [[V]] 368; 369 %P2 = select i1 %C, ptr addrspace(1) null, ptr addrspace(1) %P 370 %V = load i32, ptr 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, ptr %P) #0 { 376; CHECK-LABEL: @test16_no_null_opt( 377; CHECK-NEXT: [[P2:%.*]] = select i1 [[C:%.*]], ptr [[P:%.*]], ptr null 378; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P2]], align 4 379; CHECK-NEXT: ret i32 [[V]] 380; 381 %P2 = select i1 %C, ptr %P, ptr null 382 %V = load i32, ptr %P2 383 ret i32 %V 384} 385 386define i32 @test16_no_null_opt_2(i1 %C, ptr %P) #0 { 387; CHECK-LABEL: @test16_no_null_opt_2( 388; CHECK-NEXT: [[P2:%.*]] = select i1 [[C:%.*]], ptr null, ptr [[P:%.*]] 389; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P2]], align 4 390; CHECK-NEXT: ret i32 [[V]] 391; 392 %P2 = select i1 %C, ptr null, ptr %P 393 %V = load i32, ptr %P2 394 ret i32 %V 395} 396 397attributes #0 = { null_pointer_is_valid } 398 399define i1 @test17(ptr %X, i1 %C) { 400; CHECK-LABEL: @test17( 401; CHECK-NEXT: [[RV1:%.*]] = icmp eq ptr [[X:%.*]], null 402; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C:%.*]], true 403; CHECK-NEXT: [[RV:%.*]] = select i1 [[NOT_C]], i1 true, i1 [[RV1]] 404; CHECK-NEXT: ret i1 [[RV]] 405; 406 %R = select i1 %C, ptr %X, ptr null 407 %RV = icmp eq ptr %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 %t = icmp ugt i32 %x, 2147483647 427 %retval = select i1 %t, 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 %t = icmp slt i32 %x, 0 437 %retval = select i1 %t, 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: [[RETVAL:%.*]] = sext i32 [[X_LOBIT]] to i64 445; CHECK-NEXT: ret i64 [[RETVAL]] 446; 447 %t = icmp slt i32 %x, 0 448 %retval = select i1 %t, 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: [[RETVAL:%.*]] = trunc nsw i32 [[X_LOBIT]] to i16 456; CHECK-NEXT: ret i16 [[RETVAL]] 457; 458 %t = icmp slt i32 %x, 0 459 %retval = select i1 %t, 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 [ 20, [[ENTRY:%.*]] ], [ 10, [[JUMP]] ] 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 [ 20, [[ENTRY:%.*]] ], [ 10, [[JUMP]] ] 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: [[COND:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 [[Y:%.*]]) 596; CHECK-NEXT: ret i32 [[COND]] 597; 598 %cmp = icmp sgt i32 %x, %y 599 %cond = select i1 %cmp, i32 %x, i32 %y 600 %cmp5 = icmp sgt i32 %cond, %x 601 %retval = select i1 %cmp5, i32 %cond, i32 %x 602 ret i32 %retval 603} 604 605; UMAX(UMAX(x, y), x) -> UMAX(x, y) 606define i32 @test31(i32 %x, i32 %y) { 607; CHECK-LABEL: @test31( 608; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 [[Y:%.*]]) 609; CHECK-NEXT: ret i32 [[COND]] 610; 611 %cmp = icmp ugt i32 %x, %y 612 %cond = select i1 %cmp, i32 %x, i32 %y 613 %cmp5 = icmp ugt i32 %cond, %x 614 %retval = select i1 %cmp5, i32 %cond, i32 %x 615 ret i32 %retval 616} 617 618; SMIN(SMIN(x, y), x) -> SMIN(x, y) 619define i32 @test32(i32 %x, i32 %y) { 620; CHECK-LABEL: @test32( 621; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 [[Y:%.*]]) 622; CHECK-NEXT: ret i32 [[COND]] 623; 624 %cmp = icmp sgt i32 %x, %y 625 %cond = select i1 %cmp, i32 %y, i32 %x 626 %cmp5 = icmp sgt i32 %cond, %x 627 %retval = select i1 %cmp5, i32 %x, i32 %cond 628 ret i32 %retval 629} 630 631; MAX(MIN(x, y), x) -> x 632define i32 @test33(i32 %x, i32 %y) { 633; CHECK-LABEL: @test33( 634; CHECK-NEXT: ret i32 [[X:%.*]] 635; 636 %cmp = icmp sgt i32 %x, %y 637 %cond = select i1 %cmp, i32 %y, i32 %x 638 %cmp5 = icmp sgt i32 %cond, %x 639 %retval = select i1 %cmp5, i32 %cond, i32 %x 640 ret i32 %retval 641} 642 643; MIN(MAX(x, y), x) -> x 644define i32 @test34(i32 %x, i32 %y) { 645; CHECK-LABEL: @test34( 646; CHECK-NEXT: ret i32 [[X:%.*]] 647; 648 %cmp = icmp sgt i32 %x, %y 649 %cond = select i1 %cmp, i32 %x, i32 %y 650 %cmp5 = icmp sgt i32 %cond, %x 651 %retval = select i1 %cmp5, i32 %x, i32 %cond 652 ret i32 %retval 653} 654 655define i1 @test38(i1 %cond) { 656; CHECK-LABEL: @test38( 657; CHECK-NEXT: ret i1 false 658; 659 %zero = alloca i32 660 %one = alloca i32 661 %ptr = select i1 %cond, ptr %zero, ptr %one 662 %isnull = icmp eq ptr %ptr, null 663 ret i1 %isnull 664} 665 666define i1 @test39(i1 %cond, double %x) { 667; CHECK-LABEL: @test39( 668; CHECK-NEXT: ret i1 true 669; 670 %s = select i1 %cond, double %x, double 0x7FF0000000000000 ; RHS = +infty 671 %cmp = fcmp ule double %x, %s 672 ret i1 %cmp 673} 674 675define i1 @test40(i1 %cond) { 676; CHECK-LABEL: @test40( 677; CHECK-NEXT: ret i1 false 678; 679 %a = alloca i32 680 %b = alloca i32 681 %c = alloca i32 682 %s = select i1 %cond, ptr %a, ptr %b 683 %r = icmp eq ptr %s, %c 684 ret i1 %r 685} 686 687define i32 @test41(i1 %cond, i32 %x, i32 %y) { 688; CHECK-LABEL: @test41( 689; CHECK-NEXT: [[R:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 690; CHECK-NEXT: ret i32 [[R]] 691; 692 %z = and i32 %x, %y 693 %s = select i1 %cond, i32 %y, i32 %z 694 %r = and i32 %x, %s 695 ret i32 %r 696} 697 698define i32 @test42(i32 %x, i32 %y) { 699; CHECK-LABEL: @test42( 700; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[X:%.*]], 0 701; CHECK-NEXT: [[B:%.*]] = sext i1 [[COND]] to i32 702; CHECK-NEXT: [[C:%.*]] = add i32 [[Y:%.*]], [[B]] 703; CHECK-NEXT: ret i32 [[C]] 704; 705 %b = add i32 %y, -1 706 %cond = icmp eq i32 %x, 0 707 %c = select i1 %cond, i32 %b, i32 %y 708 ret i32 %c 709} 710 711define <2 x i32> @test42vec(<2 x i32> %x, <2 x i32> %y) { 712; CHECK-LABEL: @test42vec( 713; CHECK-NEXT: [[COND:%.*]] = icmp eq <2 x i32> [[X:%.*]], zeroinitializer 714; CHECK-NEXT: [[B:%.*]] = sext <2 x i1> [[COND]] to <2 x i32> 715; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[Y:%.*]], [[B]] 716; CHECK-NEXT: ret <2 x i32> [[C]] 717; 718 %b = add <2 x i32> %y, <i32 -1, i32 -1> 719 %cond = icmp eq <2 x i32> %x, zeroinitializer 720 %c = select <2 x i1> %cond, <2 x i32> %b, <2 x i32> %y 721 ret <2 x i32> %c 722} 723 724; PR8994 725 726; This select instruction can't be eliminated because trying to do so would 727; change the number of vector elements. This used to assert. 728define i48 @test51(<3 x i1> %icmp, <3 x i16> %t) { 729; CHECK-LABEL: @test51( 730; CHECK-NEXT: [[SELECT:%.*]] = select <3 x i1> [[ICMP:%.*]], <3 x i16> zeroinitializer, <3 x i16> [[T:%.*]] 731; CHECK-NEXT: [[T2:%.*]] = bitcast <3 x i16> [[SELECT]] to i48 732; CHECK-NEXT: ret i48 [[T2]] 733; 734 %select = select <3 x i1> %icmp, <3 x i16> zeroinitializer, <3 x i16> %t 735 %t2 = bitcast <3 x i16> %select to i48 736 ret i48 %t2 737} 738 739define <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) { 740; CHECK-LABEL: @bitcast_select_bitcast( 741; CHECK-NEXT: [[TMP1:%.*]] = bitcast <vscale x 4 x i32> [[A:%.*]] to <vscale x 4 x float> 742; CHECK-NEXT: [[BC2:%.*]] = select <vscale x 4 x i1> [[ICMP:%.*]], <vscale x 4 x float> [[B:%.*]], <vscale x 4 x float> [[TMP1]] 743; CHECK-NEXT: ret <vscale x 4 x float> [[BC2]] 744; 745 %bc1 = bitcast <vscale x 4 x float> %b to <vscale x 4 x i32> 746 %select = select <vscale x 4 x i1> %icmp, <vscale x 4 x i32> %bc1, <vscale x 4 x i32> %a 747 %bc2 = bitcast <vscale x 4 x i32> %select to <vscale x 4 x float> 748 ret <vscale x 4 x float> %bc2 749} 750 751define 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, ptr %ptr1) { 752; CHECK-LABEL: @select_oneuse_bitcast( 753; CHECK-NEXT: [[CMP:%.*]] = icmp ult <vscale x 4 x i32> [[C:%.*]], [[D:%.*]] 754; CHECK-NEXT: [[SEL1_V:%.*]] = select <vscale x 4 x i1> [[CMP]], <vscale x 4 x float> [[A:%.*]], <vscale x 4 x float> [[B:%.*]] 755; CHECK-NEXT: store <vscale x 4 x float> [[SEL1_V]], ptr [[PTR1:%.*]], align 16 756; CHECK-NEXT: ret void 757; 758 %cmp = icmp ult <vscale x 4 x i32> %c, %d 759 %bc1 = bitcast <vscale x 4 x float> %a to <vscale x 4 x i32> 760 %bc2 = bitcast <vscale x 4 x float> %b to <vscale x 4 x i32> 761 %sel1 = select <vscale x 4 x i1> %cmp, <vscale x 4 x i32> %bc1, <vscale x 4 x i32> %bc2 762 store <vscale x 4 x i32> %sel1, ptr %ptr1 763 ret void 764} 765 766; Allow select promotion even if there are multiple uses of bitcasted ops. 767; Hoisting the selects allows later pattern matching to see that these are min/max ops. 768 769define void @min_max_bitcast(<4 x float> %a, <4 x float> %b, ptr %ptr1, ptr %ptr2) { 770; CHECK-LABEL: @min_max_bitcast( 771; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <4 x float> [[A:%.*]], [[B:%.*]] 772; CHECK-NEXT: [[SEL1_V:%.*]] = select <4 x i1> [[CMP]], <4 x float> [[A]], <4 x float> [[B]] 773; CHECK-NEXT: [[SEL2_V:%.*]] = select <4 x i1> [[CMP]], <4 x float> [[B]], <4 x float> [[A]] 774; CHECK-NEXT: store <4 x float> [[SEL1_V]], ptr [[PTR1:%.*]], align 16 775; CHECK-NEXT: store <4 x float> [[SEL2_V]], ptr [[PTR2:%.*]], align 16 776; CHECK-NEXT: ret void 777; 778 %cmp = fcmp olt <4 x float> %a, %b 779 %bc1 = bitcast <4 x float> %a to <4 x i32> 780 %bc2 = bitcast <4 x float> %b to <4 x i32> 781 %sel1 = select <4 x i1> %cmp, <4 x i32> %bc1, <4 x i32> %bc2 782 %sel2 = select <4 x i1> %cmp, <4 x i32> %bc2, <4 x i32> %bc1 783 store <4 x i32> %sel1, ptr %ptr1 784 store <4 x i32> %sel2, ptr %ptr2 785 ret void 786} 787 788define void @min_max_bitcast1(<vscale x 4 x float> %a, <vscale x 4 x float> %b, ptr %ptr1, ptr %ptr2) { 789; CHECK-LABEL: @min_max_bitcast1( 790; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <vscale x 4 x float> [[A:%.*]], [[B:%.*]] 791; CHECK-NEXT: [[SEL1_V:%.*]] = select <vscale x 4 x i1> [[CMP]], <vscale x 4 x float> [[A]], <vscale x 4 x float> [[B]] 792; CHECK-NEXT: [[SEL2_V:%.*]] = select <vscale x 4 x i1> [[CMP]], <vscale x 4 x float> [[B]], <vscale x 4 x float> [[A]] 793; CHECK-NEXT: store <vscale x 4 x float> [[SEL1_V]], ptr [[PTR1:%.*]], align 16 794; CHECK-NEXT: store <vscale x 4 x float> [[SEL2_V]], ptr [[PTR2:%.*]], align 16 795; CHECK-NEXT: ret void 796; 797 %cmp = fcmp olt <vscale x 4 x float> %a, %b 798 %bc1 = bitcast <vscale x 4 x float> %a to <vscale x 4 x i32> 799 %bc2 = bitcast <vscale x 4 x float> %b to <vscale x 4 x i32> 800 %sel1 = select <vscale x 4 x i1> %cmp, <vscale x 4 x i32> %bc1, <vscale x 4 x i32> %bc2 801 %sel2 = select <vscale x 4 x i1> %cmp, <vscale x 4 x i32> %bc2, <vscale x 4 x i32> %bc1 802 store <vscale x 4 x i32> %sel1, ptr %ptr1 803 store <vscale x 4 x i32> %sel2, ptr %ptr2 804 ret void 805} 806 807; To avoid potential backend problems, we don't do the same transform for other casts. 808 809define void @truncs_before_selects(<4 x float> %f1, <4 x float> %f2, <4 x i64> %a, <4 x i64> %b, ptr %ptr1, ptr %ptr2) { 810; CHECK-LABEL: @truncs_before_selects( 811; CHECK-NEXT: [[CMP:%.*]] = fcmp olt <4 x float> [[F1:%.*]], [[F2:%.*]] 812; CHECK-NEXT: [[BC1:%.*]] = trunc <4 x i64> [[A:%.*]] to <4 x i32> 813; CHECK-NEXT: [[BC2:%.*]] = trunc <4 x i64> [[B:%.*]] to <4 x i32> 814; CHECK-NEXT: [[SEL1:%.*]] = select <4 x i1> [[CMP]], <4 x i32> [[BC1]], <4 x i32> [[BC2]] 815; CHECK-NEXT: [[SEL2:%.*]] = select <4 x i1> [[CMP]], <4 x i32> [[BC2]], <4 x i32> [[BC1]] 816; CHECK-NEXT: store <4 x i32> [[SEL1]], ptr [[PTR1:%.*]], align 16 817; CHECK-NEXT: store <4 x i32> [[SEL2]], ptr [[PTR2:%.*]], align 16 818; CHECK-NEXT: ret void 819; 820 %cmp = fcmp olt <4 x float> %f1, %f2 821 %bc1 = trunc <4 x i64> %a to <4 x i32> 822 %bc2 = trunc <4 x i64> %b to <4 x i32> 823 %sel1 = select <4 x i1> %cmp, <4 x i32> %bc1, <4 x i32> %bc2 824 %sel2 = select <4 x i1> %cmp, <4 x i32> %bc2, <4 x i32> %bc1 825 store <4 x i32> %sel1, ptr %ptr1, align 16 826 store <4 x i32> %sel2, ptr %ptr2, align 16 827 ret void 828} 829 830; PR8575 831 832define i32 @test52(i32 %n, i32 %m) { 833; CHECK-LABEL: @test52( 834; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], [[M:%.*]] 835; CHECK-NEXT: [[STOREMERGE:%.*]] = select i1 [[CMP]], i32 1, i32 6 836; CHECK-NEXT: ret i32 [[STOREMERGE]] 837; 838 %cmp = icmp sgt i32 %n, %m 839 %. = select i1 %cmp, i32 1, i32 3 840 %add = add nsw i32 %., 3 841 %storemerge = select i1 %cmp, i32 %., i32 %add 842 ret i32 %storemerge 843} 844 845; PR9454 846 847define i32 @test53(i32 %x) { 848; CHECK-LABEL: @test53( 849; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -3 850; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0 851; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 2, i32 1 852; CHECK-NEXT: ret i32 [[SEL]] 853; 854 %and = and i32 %x, 2 855 %cmp = icmp eq i32 %and, %x 856 %sel = select i1 %cmp, i32 2, i32 1 857 ret i32 %sel 858} 859 860define i32 @test54(i32 %X, i32 %Y) { 861; CHECK-LABEL: @test54( 862; CHECK-NEXT: [[B:%.*]] = icmp ne i32 [[X:%.*]], 0 863; CHECK-NEXT: [[C:%.*]] = zext i1 [[B]] to i32 864; CHECK-NEXT: ret i32 [[C]] 865; 866 %A = ashr exact i32 %X, %Y 867 %B = icmp eq i32 %A, 0 868 %C = select i1 %B, i32 %A, i32 1 869 ret i32 %C 870} 871 872define i1 @test55(i1 %X, i32 %Y, i32 %Z) { 873; CHECK-LABEL: @test55( 874; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[Y:%.*]], 0 875; CHECK-NEXT: ret i1 [[C]] 876; 877 %A = ashr exact i32 %Y, %Z 878 %B = select i1 %X, i32 %Y, i32 %A 879 %C = icmp eq i32 %B, 0 880 ret i1 %C 881} 882 883define i32 @test56(i16 %x) { 884; CHECK-LABEL: @test56( 885; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[X:%.*]] to i32 886; CHECK-NEXT: ret i32 [[CONV]] 887; 888 %tobool = icmp eq i16 %x, 0 889 %conv = zext i16 %x to i32 890 %cond = select i1 %tobool, i32 0, i32 %conv 891 ret i32 %cond 892} 893 894define i32 @test57(i32 %x, i32 %y) { 895; CHECK-LABEL: @test57( 896; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 897; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X]], 0 898; CHECK-NEXT: [[DOTAND:%.*]] = select i1 [[TOBOOL]], i32 0, i32 [[AND]] 899; CHECK-NEXT: ret i32 [[DOTAND]] 900; 901 %and = and i32 %x, %y 902 %tobool = icmp eq i32 %x, 0 903 %.and = select i1 %tobool, i32 0, i32 %and 904 ret i32 %.and 905} 906 907define i32 @test58(i16 %x) { 908; CHECK-LABEL: @test58( 909; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[X:%.*]] to i32 910; CHECK-NEXT: ret i32 [[CONV]] 911; 912 %tobool = icmp ne i16 %x, 1 913 %conv = zext i16 %x to i32 914 %cond = select i1 %tobool, i32 %conv, i32 1 915 ret i32 %cond 916} 917 918define i32 @test59(i32 %x, i32 %y) { 919; CHECK-LABEL: @test59( 920; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 921; CHECK-NEXT: ret i32 [[AND]] 922; 923 %and = and i32 %x, %y 924 %tobool = icmp ne i32 %x, %y 925 %.and = select i1 %tobool, i32 %and, i32 %y 926 ret i32 %.and 927} 928 929define i1 @test60(i32 %x, ptr %y) { 930; CHECK-LABEL: @test60( 931; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0 932; CHECK-NEXT: [[LOAD:%.*]] = load i1, ptr [[Y:%.*]], align 1 933; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[X]], 1 934; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i1 [[LOAD]], i1 [[CMP1]] 935; CHECK-NEXT: ret i1 [[SEL]] 936; 937 %cmp = icmp eq i32 %x, 0 938 %load = load i1, ptr %y, align 1 939 %cmp1 = icmp slt i32 %x, 1 940 %sel = select i1 %cmp, i1 %load, i1 %cmp1 941 ret i1 %sel 942} 943 944@glbl = constant i32 10 945define i32 @test61(ptr %ptr) { 946; CHECK-LABEL: @test61( 947; CHECK-NEXT: ret i32 10 948; 949 %A = load i32, ptr %ptr 950 %B = icmp eq ptr %ptr, @glbl 951 %C = select i1 %B, i32 %A, i32 10 952 ret i32 %C 953} 954 955; PR14131 956define void @test64(i32 %p, i16 %b, i1 %c1) noreturn { 957; CHECK-LABEL: @test64( 958; CHECK-NEXT: entry: 959; CHECK-NEXT: br i1 [[C1:%.*]], label [[LOR_RHS:%.*]], label [[LOR_END:%.*]] 960; CHECK: lor.rhs: 961; CHECK-NEXT: br label [[LOR_END]] 962; CHECK: lor.end: 963; CHECK-NEXT: br i1 poison, label [[COND_END17:%.*]], label [[COND_FALSE16:%.*]] 964; CHECK: cond.false16: 965; CHECK-NEXT: br label [[COND_END17]] 966; CHECK: cond.end17: 967; CHECK-NEXT: br label [[WHILE_BODY:%.*]] 968; CHECK: while.body: 969; CHECK-NEXT: br label [[WHILE_BODY]] 970; 971entry: 972 %p.addr.0.insert.mask = and i32 %p, -65536 973 %conv2 = and i32 %p, 65535 974 br i1 %c1, label %lor.rhs, label %lor.end 975 976lor.rhs: 977 %p.addr.0.extract.trunc = trunc i32 %p.addr.0.insert.mask to i16 978 %phitmp = zext i16 %p.addr.0.extract.trunc to i32 979 br label %lor.end 980 981lor.end: 982 %t.1 = phi i32 [ 0, %entry ], [ %phitmp, %lor.rhs ] 983 %conv6 = zext i16 %b to i32 984 %div = udiv i32 %conv6, %t.1 985 %tobool8 = icmp eq i32 %div, 0 986 %cmp = icmp eq i32 %t.1, 0 987 %cmp12 = icmp ult i32 %conv2, 2 988 %cmp.sink = select i1 %tobool8, i1 %cmp12, i1 %cmp 989 br i1 %cmp.sink, label %cond.end17, label %cond.false16 990 991cond.false16: 992 br label %cond.end17 993 994cond.end17: 995 br label %while.body 996 997while.body: 998 br label %while.body 999} 1000 1001@under_aligned = external global i32, align 1 1002 1003; The load here must not be speculated around the select. One side of the 1004; select is trivially dereferenceable but may have a lower alignment than the 1005; load does. 1006define i32 @test76(i1 %flag, ptr %x) { 1007; CHECK-LABEL: @test76( 1008; CHECK-NEXT: store i32 0, ptr [[X:%.*]], align 4 1009; CHECK-NEXT: [[P:%.*]] = select i1 [[FLAG:%.*]], ptr @under_aligned, ptr [[X]] 1010; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P]], align 4 1011; CHECK-NEXT: ret i32 [[V]] 1012; 1013 store i32 0, ptr %x 1014 %p = select i1 %flag, ptr @under_aligned, ptr %x 1015 %v = load i32, ptr %p 1016 ret i32 %v 1017} 1018 1019declare void @scribble_on_i32(ptr) 1020 1021; The load here must not be speculated around the select. One side of the 1022; select is trivially dereferenceable but may have a lower alignment than the 1023; load does. 1024 1025define i32 @test77(i1 %flag, ptr %x) { 1026; CHECK-LABEL: @test77( 1027; CHECK-NEXT: [[UNDER_ALIGNED:%.*]] = alloca i32, align 1 1028; CHECK-NEXT: call void @scribble_on_i32(ptr nonnull [[UNDER_ALIGNED]]) 1029; CHECK-NEXT: store i32 0, ptr [[X:%.*]], align 4 1030; CHECK-NEXT: [[P:%.*]] = select i1 [[FLAG:%.*]], ptr [[UNDER_ALIGNED]], ptr [[X]] 1031; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P]], align 4 1032; CHECK-NEXT: ret i32 [[V]] 1033; 1034 %under_aligned = alloca i32, align 1 1035 call void @scribble_on_i32(ptr %under_aligned) 1036 store i32 0, ptr %x 1037 %p = select i1 %flag, ptr %under_aligned, ptr %x 1038 %v = load i32, ptr %p 1039 ret i32 %v 1040} 1041 1042define i32 @test78(i1 %flag, ptr %x, ptr %y, ptr %z) { 1043; Test that we can speculate the loads around the select even when we can't 1044; fold the load completely away. 1045; CHECK-LABEL: @test78( 1046; CHECK-NEXT: entry: 1047; CHECK-NEXT: store i32 0, ptr [[X:%.*]], align 4 1048; CHECK-NEXT: store i32 0, ptr [[Y:%.*]], align 4 1049; CHECK-NEXT: store i32 42, ptr [[Z:%.*]], align 4 1050; CHECK-NEXT: [[X_VAL:%.*]] = load i32, ptr [[X]], align 4 1051; CHECK-NEXT: [[Y_VAL:%.*]] = load i32, ptr [[Y]], align 4 1052; CHECK-NEXT: [[V:%.*]] = select i1 [[FLAG:%.*]], i32 [[X_VAL]], i32 [[Y_VAL]] 1053; CHECK-NEXT: ret i32 [[V]] 1054; 1055entry: 1056 store i32 0, ptr %x 1057 store i32 0, ptr %y 1058 ; Block forwarding by storing to %z which could alias either %x or %y. 1059 store i32 42, ptr %z 1060 %p = select i1 %flag, ptr %x, ptr %y 1061 %v = load i32, ptr %p 1062 ret i32 %v 1063} 1064 1065; Test that we can speculate the loads around the select even when we can't 1066; fold the load completely away. 1067define i32 @test78_deref(i1 %flag, ptr dereferenceable(4) align 4 %x, ptr dereferenceable(4) align 4 %y, ptr %z) nofree nosync { 1068; CHECK-LABEL: @test78_deref( 1069; CHECK-NEXT: [[X_VAL:%.*]] = load i32, ptr [[X:%.*]], align 4 1070; CHECK-NEXT: [[Y_VAL:%.*]] = load i32, ptr [[Y:%.*]], align 4 1071; CHECK-NEXT: [[V:%.*]] = select i1 [[FLAG:%.*]], i32 [[X_VAL]], i32 [[Y_VAL]] 1072; CHECK-NEXT: ret i32 [[V]] 1073; 1074 %p = select i1 %flag, ptr %x, ptr %y 1075 %v = load i32, ptr %p 1076 ret i32 %v 1077} 1078 1079; The same as @test78 but we can't speculate the load because it can trap 1080; if under-aligned. 1081define i32 @test78_neg(i1 %flag, ptr %x, ptr %y, ptr %z) { 1082; CHECK-LABEL: @test78_neg( 1083; CHECK-NEXT: store i32 0, ptr [[X:%.*]], align 4 1084; CHECK-NEXT: store i32 0, ptr [[Y:%.*]], align 4 1085; CHECK-NEXT: store i32 42, ptr [[Z:%.*]], align 4 1086; CHECK-NEXT: [[P:%.*]] = select i1 [[FLAG:%.*]], ptr [[X]], ptr [[Y]] 1087; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P]], align 16 1088; CHECK-NEXT: ret i32 [[V]] 1089; 1090 store i32 0, ptr %x 1091 store i32 0, ptr %y 1092 ; Block forwarding by storing to %z which could alias either %x or %y. 1093 store i32 42, ptr %z 1094 %p = select i1 %flag, ptr %x, ptr %y 1095 %v = load i32, ptr %p, align 16 1096 ret i32 %v 1097} 1098 1099; The same as @test78_deref but we can't speculate the load because 1100; one of the arguments is not sufficiently dereferenceable. 1101define i32 @test78_deref_neg(i1 %flag, ptr dereferenceable(2) %x, ptr dereferenceable(4) %y, ptr %z) nofree nosync { 1102; CHECK-LABEL: @test78_deref_neg( 1103; CHECK-NEXT: [[P:%.*]] = select i1 [[FLAG:%.*]], ptr [[X:%.*]], ptr [[Y:%.*]] 1104; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P]], align 4 1105; CHECK-NEXT: ret i32 [[V]] 1106; 1107 %p = select i1 %flag, ptr %x, ptr %y 1108 %v = load i32, ptr %p 1109 ret i32 %v 1110} 1111 1112; Test that we can speculate the loads around the select even when we can't 1113; fold the load completely away. 1114define float @test79(i1 %flag, ptr %x, ptr %y, ptr %z) { 1115; CHECK-LABEL: @test79( 1116; CHECK-NEXT: store i32 0, ptr [[X:%.*]], align 4 1117; CHECK-NEXT: store i32 0, ptr [[Y:%.*]], align 4 1118; CHECK-NEXT: store i32 42, ptr [[Z:%.*]], align 4 1119; CHECK-NEXT: [[X_VAL:%.*]] = load float, ptr [[X]], align 4 1120; CHECK-NEXT: [[Y_VAL:%.*]] = load float, ptr [[Y]], align 4 1121; CHECK-NEXT: [[V:%.*]] = select i1 [[FLAG:%.*]], float [[X_VAL]], float [[Y_VAL]] 1122; CHECK-NEXT: ret float [[V]] 1123; 1124 store i32 0, ptr %x 1125 store i32 0, ptr %y 1126 ; Block forwarding by storing to %z which could alias either %x or %y. 1127 store i32 42, ptr %z 1128 %p = select i1 %flag, ptr %x, ptr %y 1129 %v = load float, ptr %p 1130 ret float %v 1131} 1132 1133; Test that when we speculate the loads around the select they fold throug 1134; load->load folding and load->store folding. 1135define i32 @test80(i1 %flag) { 1136; CHECK-LABEL: @test80( 1137; CHECK-NEXT: [[X:%.*]] = alloca i32, align 4 1138; CHECK-NEXT: [[Y:%.*]] = alloca i32, align 4 1139; CHECK-NEXT: call void @scribble_on_i32(ptr nonnull [[X]]) 1140; CHECK-NEXT: call void @scribble_on_i32(ptr nonnull [[Y]]) 1141; CHECK-NEXT: [[T:%.*]] = load i32, ptr [[X]], align 4 1142; CHECK-NEXT: store i32 [[T]], ptr [[Y]], align 4 1143; CHECK-NEXT: ret i32 [[T]] 1144; 1145 %x = alloca i32 1146 %y = alloca i32 1147 call void @scribble_on_i32(ptr %x) 1148 call void @scribble_on_i32(ptr %y) 1149 %t = load i32, ptr %x 1150 store i32 %t, ptr %y 1151 %p = select i1 %flag, ptr %x, ptr %y 1152 %v = load i32, ptr %p 1153 ret i32 %v 1154} 1155 1156; Test that we can speculate the load around the select even though they use 1157; differently typed pointers. 1158define float @test81(i1 %flag) { 1159; CHECK-LABEL: @test81( 1160; CHECK-NEXT: [[X:%.*]] = alloca float, align 4 1161; CHECK-NEXT: [[Y:%.*]] = alloca i32, align 4 1162; CHECK-NEXT: call void @scribble_on_i32(ptr nonnull [[X]]) 1163; CHECK-NEXT: call void @scribble_on_i32(ptr nonnull [[Y]]) 1164; CHECK-NEXT: [[T:%.*]] = load i32, ptr [[X]], align 4 1165; CHECK-NEXT: store i32 [[T]], ptr [[Y]], align 4 1166; CHECK-NEXT: [[V:%.*]] = bitcast i32 [[T]] to float 1167; CHECK-NEXT: ret float [[V]] 1168; 1169 %x = alloca float 1170 %y = alloca i32 1171 call void @scribble_on_i32(ptr %x) 1172 call void @scribble_on_i32(ptr %y) 1173 %t = load i32, ptr %x 1174 store i32 %t, ptr %y 1175 %p = select i1 %flag, ptr %x, ptr %y 1176 %v = load float, ptr %p 1177 ret float %v 1178} 1179 1180; Test that we can speculate the load around the select even though they use 1181; differently typed pointers. 1182define i32 @test82(i1 %flag) { 1183; CHECK-LABEL: @test82( 1184; CHECK-NEXT: [[X:%.*]] = alloca float, align 4 1185; CHECK-NEXT: [[Y:%.*]] = alloca i32, align 4 1186; CHECK-NEXT: call void @scribble_on_i32(ptr nonnull [[X]]) 1187; CHECK-NEXT: call void @scribble_on_i32(ptr nonnull [[Y]]) 1188; CHECK-NEXT: [[T:%.*]] = load float, ptr [[X]], align 4 1189; CHECK-NEXT: store float [[T]], ptr [[Y]], align 4 1190; CHECK-NEXT: [[V:%.*]] = bitcast float [[T]] to i32 1191; CHECK-NEXT: ret i32 [[V]] 1192; 1193 %x = alloca float 1194 %y = alloca i32 1195 call void @scribble_on_i32(ptr %x) 1196 call void @scribble_on_i32(ptr %y) 1197 %t = load float, ptr %x 1198 store float %t, ptr %y 1199 %p = select i1 %flag, ptr %x, ptr %y 1200 %v = load i32, ptr %p 1201 ret i32 %v 1202} 1203 1204declare void @scribble_on_i64(ptr) 1205declare void @scribble_on_i128(ptr) 1206 1207; Test that we can speculate the load around the select even though they use 1208; differently typed pointers and requires inttoptr casts. 1209define ptr @test83(i1 %flag) { 1210; CHECK-LABEL: @test83( 1211; CHECK-NEXT: [[X:%.*]] = alloca ptr, align 8 1212; CHECK-NEXT: [[Y:%.*]] = alloca i64, align 8 1213; CHECK-NEXT: call void @scribble_on_i64(ptr nonnull [[X]]) 1214; CHECK-NEXT: call void @scribble_on_i64(ptr nonnull [[Y]]) 1215; CHECK-NEXT: [[T:%.*]] = load i64, ptr [[X]], align 4 1216; CHECK-NEXT: store i64 [[T]], ptr [[Y]], align 4 1217; CHECK-NEXT: [[V:%.*]] = inttoptr i64 [[T]] to ptr 1218; CHECK-NEXT: ret ptr [[V]] 1219; 1220 %x = alloca ptr 1221 %y = alloca i64 1222 call void @scribble_on_i64(ptr %x) 1223 call void @scribble_on_i64(ptr %y) 1224 %t = load i64, ptr %x 1225 store i64 %t, ptr %y 1226 %p = select i1 %flag, ptr %x, ptr %y 1227 %v = load ptr, ptr %p 1228 ret ptr %v 1229} 1230 1231; Test that we can speculate the load around the select even though they use 1232; differently typed pointers and requires a ptrtoint cast. 1233define i64 @test84(i1 %flag) { 1234; CHECK-LABEL: @test84( 1235; CHECK-NEXT: [[X:%.*]] = alloca ptr, align 8 1236; CHECK-NEXT: [[Y:%.*]] = alloca i64, align 8 1237; CHECK-NEXT: call void @scribble_on_i64(ptr nonnull [[X]]) 1238; CHECK-NEXT: call void @scribble_on_i64(ptr nonnull [[Y]]) 1239; CHECK-NEXT: [[T:%.*]] = load ptr, ptr [[X]], align 8 1240; CHECK-NEXT: store ptr [[T]], ptr [[Y]], align 8 1241; CHECK-NEXT: [[V:%.*]] = ptrtoint ptr [[T]] to i64 1242; CHECK-NEXT: ret i64 [[V]] 1243; 1244 %x = alloca ptr 1245 %y = alloca i64 1246 call void @scribble_on_i64(ptr %x) 1247 call void @scribble_on_i64(ptr %y) 1248 %t = load ptr, ptr %x 1249 store ptr %t, ptr %y 1250 %p = select i1 %flag, ptr %x, ptr %y 1251 %v = load i64, ptr %p 1252 ret i64 %v 1253} 1254 1255; Test that we can't speculate the load around the select. The load of the 1256; pointer doesn't load all of the stored integer bits. We could fix this, but it 1257; would require endianness checks and other nastiness. 1258define ptr @test85(i1 %flag) { 1259; CHECK-LABEL: @test85( 1260; CHECK-NEXT: [[X:%.*]] = alloca [2 x ptr], align 8 1261; CHECK-NEXT: [[Y:%.*]] = alloca i128, align 8 1262; CHECK-NEXT: call void @scribble_on_i128(ptr nonnull [[X]]) 1263; CHECK-NEXT: call void @scribble_on_i128(ptr nonnull [[Y]]) 1264; CHECK-NEXT: [[T:%.*]] = load i128, ptr [[X]], align 4 1265; CHECK-NEXT: store i128 [[T]], ptr [[Y]], align 4 1266; CHECK-NEXT: [[X_VAL:%.*]] = load ptr, ptr [[X]], align 8 1267; CHECK-NEXT: [[Y_VAL:%.*]] = load ptr, ptr [[Y]], align 8 1268; CHECK-NEXT: [[V:%.*]] = select i1 [[FLAG:%.*]], ptr [[X_VAL]], ptr [[Y_VAL]] 1269; CHECK-NEXT: ret ptr [[V]] 1270; 1271 %x = alloca [2 x ptr] 1272 %y = alloca i128 1273 call void @scribble_on_i128(ptr %x) 1274 call void @scribble_on_i128(ptr %y) 1275 %t = load i128, ptr %x 1276 store i128 %t, ptr %y 1277 %p = select i1 %flag, ptr %x, ptr %y 1278 %v = load ptr, ptr %p 1279 ret ptr %v 1280} 1281 1282; Test that we can't speculate the load around the select when the integer size 1283; is larger than the pointer size. The store of the pointer doesn't store to all 1284; the bits of the integer. 1285define i128 @test86(i1 %flag) { 1286; CHECK-LABEL: @test86( 1287; CHECK-NEXT: [[X:%.*]] = alloca [2 x ptr], align 8 1288; CHECK-NEXT: [[Y:%.*]] = alloca i128, align 8 1289; CHECK-NEXT: call void @scribble_on_i128(ptr nonnull [[X]]) 1290; CHECK-NEXT: call void @scribble_on_i128(ptr nonnull [[Y]]) 1291; CHECK-NEXT: [[T:%.*]] = load ptr, ptr [[X]], align 8 1292; CHECK-NEXT: store ptr [[T]], ptr [[Y]], align 8 1293; CHECK-NEXT: [[X_VAL:%.*]] = load i128, ptr [[X]], align 4 1294; CHECK-NEXT: [[Y_VAL:%.*]] = load i128, ptr [[Y]], align 4 1295; CHECK-NEXT: [[V:%.*]] = select i1 [[FLAG:%.*]], i128 [[X_VAL]], i128 [[Y_VAL]] 1296; CHECK-NEXT: ret i128 [[V]] 1297; 1298 %x = alloca [2 x ptr] 1299 %y = alloca i128 1300 call void @scribble_on_i128(ptr %x) 1301 call void @scribble_on_i128(ptr %y) 1302 %t = load ptr, ptr %x 1303 store ptr %t, ptr %y 1304 %p = select i1 %flag, ptr %x, ptr %y 1305 %v = load i128, ptr %p 1306 ret i128 %v 1307} 1308 1309define i32 @test_select_select0(i32 %a, i32 %r0, i32 %r1, i32 %v1, i32 %v2) { 1310; CHECK-LABEL: @test_select_select0( 1311; CHECK-NEXT: [[C0_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[V1:%.*]] 1312; CHECK-NEXT: [[S0:%.*]] = select i1 [[C0_NOT]], i32 [[R1:%.*]], i32 [[R0:%.*]] 1313; CHECK-NEXT: [[C1:%.*]] = icmp slt i32 [[A]], [[V2:%.*]] 1314; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1]], i32 [[S0]], i32 [[R1]] 1315; CHECK-NEXT: ret i32 [[S1]] 1316; 1317 %c0 = icmp sge i32 %a, %v1 1318 %s0 = select i1 %c0, i32 %r0, i32 %r1 1319 %c1 = icmp slt i32 %a, %v2 1320 %s1 = select i1 %c1, i32 %s0, i32 %r1 1321 ret i32 %s1 1322} 1323 1324define i32 @test_select_select1(i32 %a, i32 %r0, i32 %r1, i32 %v1, i32 %v2) { 1325; CHECK-LABEL: @test_select_select1( 1326; CHECK-NEXT: [[C0_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[V1:%.*]] 1327; CHECK-NEXT: [[S0:%.*]] = select i1 [[C0_NOT]], i32 [[R1:%.*]], i32 [[R0:%.*]] 1328; CHECK-NEXT: [[C1:%.*]] = icmp slt i32 [[A]], [[V2:%.*]] 1329; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1]], i32 [[R0]], i32 [[S0]] 1330; CHECK-NEXT: ret i32 [[S1]] 1331; 1332 %c0 = icmp sge i32 %a, %v1 1333 %s0 = select i1 %c0, i32 %r0, i32 %r1 1334 %c1 = icmp slt i32 %a, %v2 1335 %s1 = select i1 %c1, i32 %r0, i32 %s0 1336 ret i32 %s1 1337} 1338 1339define i32 @PR23757(i32 %x) { 1340; CHECK-LABEL: @PR23757( 1341; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], 1 1342; CHECK-NEXT: ret i32 [[ADD]] 1343; 1344 %cmp = icmp eq i32 %x, 2147483647 1345 %add = add nsw i32 %x, 1 1346 %sel = select i1 %cmp, i32 -2147483648, i32 %add 1347 ret i32 %sel 1348} 1349 1350define i32 @PR23757_swapped(i32 %x) { 1351; CHECK-LABEL: @PR23757_swapped( 1352; CHECK-NEXT: ret i32 -2147483648 1353; 1354 %cmp = icmp eq i32 %x, 2147483647 1355 %add = add nsw i32 %x, 1 1356 %sel = select i1 %cmp, i32 %add, i32 -2147483648 1357 ret i32 %sel 1358} 1359 1360define i32 @PR23757_ne(i32 %x, ptr %p) { 1361; CHECK-LABEL: @PR23757_ne( 1362; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 2147483647 1363; CHECK-NEXT: store i1 [[CMP]], ptr [[P:%.*]], align 1 1364; CHECK-NEXT: ret i32 -2147483648 1365; 1366 %cmp = icmp ne i32 %x, 2147483647 1367 store i1 %cmp, ptr %p ; thwart predicate canonicalization 1368 %add = add nsw i32 %x, 1 1369 %sel = select i1 %cmp, i32 -2147483648, i32 %add 1370 ret i32 %sel 1371} 1372 1373define i32 @PR23757_ne_swapped(i32 %x, ptr %p) { 1374; CHECK-LABEL: @PR23757_ne_swapped( 1375; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 2147483647 1376; CHECK-NEXT: store i1 [[CMP]], ptr [[P:%.*]], align 1 1377; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X]], 1 1378; CHECK-NEXT: ret i32 [[ADD]] 1379; 1380 %cmp = icmp ne i32 %x, 2147483647 1381 store i1 %cmp, ptr %p ; thwart predicate canonicalization 1382 %add = add nsw i32 %x, 1 1383 %sel = select i1 %cmp, i32 %add, i32 -2147483648 1384 ret i32 %sel 1385} 1386 1387; max(max(~a, -1), -1) --> ~min(a, 0) 1388 1389define i32 @PR27137(i32 %a) { 1390; CHECK-LABEL: @PR27137( 1391; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[A:%.*]], i32 0) 1392; CHECK-NEXT: [[S1:%.*]] = xor i32 [[TMP1]], -1 1393; CHECK-NEXT: ret i32 [[S1]] 1394; 1395 %not_a = xor i32 %a, -1 1396 %c0 = icmp slt i32 %a, 0 1397 %s0 = select i1 %c0, i32 %not_a, i32 -1 1398 %c1 = icmp sgt i32 %s0, -1 1399 %s1 = select i1 %c1, i32 %s0, i32 -1 1400 ret i32 %s1 1401} 1402 1403; ub-safe negation pattern 1404define i32 @PR27817(i32 %x) { 1405; CHECK-LABEL: @PR27817( 1406; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[X:%.*]] 1407; CHECK-NEXT: ret i32 [[SUB]] 1408; 1409 %cmp = icmp eq i32 %x, -2147483648 1410 %sub = sub i32 0, %x 1411 %sel = select i1 %cmp, i32 -2147483648, i32 %sub 1412 ret i32 %sel 1413} 1414 1415define i32 @PR27817_nsw(i32 %x) { 1416; CHECK-LABEL: @PR27817_nsw( 1417; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[X:%.*]] 1418; CHECK-NEXT: ret i32 [[SUB]] 1419; 1420 %cmp = icmp eq i32 %x, -2147483648 1421 %sub = sub nsw i32 0, %x 1422 %sel = select i1 %cmp, i32 -2147483648, i32 %sub 1423 ret i32 %sel 1424} 1425 1426define <2 x i32> @PR27817_nsw_vec(<2 x i32> %x) { 1427; CHECK-LABEL: @PR27817_nsw_vec( 1428; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> zeroinitializer, [[X:%.*]] 1429; CHECK-NEXT: ret <2 x i32> [[SUB]] 1430; 1431 %cmp = icmp eq <2 x i32> %x, <i32 -2147483648, i32 -2147483648> 1432 %sub = sub nsw <2 x i32> zeroinitializer, %x 1433 %sel = select <2 x i1> %cmp, <2 x i32> <i32 -2147483648, i32 -2147483648>, <2 x i32> %sub 1434 ret <2 x i32> %sel 1435} 1436 1437define i32 @select_icmp_slt0_xor(i32 %x) { 1438; CHECK-LABEL: @select_icmp_slt0_xor( 1439; CHECK-NEXT: [[X_XOR:%.*]] = or i32 [[X:%.*]], -2147483648 1440; CHECK-NEXT: ret i32 [[X_XOR]] 1441; 1442 %cmp = icmp slt i32 %x, zeroinitializer 1443 %xor = xor i32 %x, 2147483648 1444 %x.xor = select i1 %cmp, i32 %x, i32 %xor 1445 ret i32 %x.xor 1446} 1447 1448define <2 x i32> @select_icmp_slt0_xor_vec(<2 x i32> %x) { 1449; CHECK-LABEL: @select_icmp_slt0_xor_vec( 1450; CHECK-NEXT: [[X_XOR:%.*]] = or <2 x i32> [[X:%.*]], splat (i32 -2147483648) 1451; CHECK-NEXT: ret <2 x i32> [[X_XOR]] 1452; 1453 %cmp = icmp slt <2 x i32> %x, zeroinitializer 1454 %xor = xor <2 x i32> %x, <i32 2147483648, i32 2147483648> 1455 %x.xor = select <2 x i1> %cmp, <2 x i32> %x, <2 x i32> %xor 1456 ret <2 x i32> %x.xor 1457} 1458 1459define <4 x i32> @canonicalize_to_shuffle(<4 x i32> %a, <4 x i32> %b) { 1460; CHECK-LABEL: @canonicalize_to_shuffle( 1461; CHECK-NEXT: [[SEL:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], <4 x i32> <i32 0, i32 5, i32 6, i32 3> 1462; CHECK-NEXT: ret <4 x i32> [[SEL]] 1463; 1464 %sel = select <4 x i1> <i1 true, i1 false, i1 false, i1 true>, <4 x i32> %a, <4 x i32> %b 1465 ret <4 x i32> %sel 1466} 1467 1468; Undef elements of the select condition may not be translated into undef elements of a shuffle mask 1469; because undef in a shuffle mask means we can return anything, not just one of the selected values. 1470; https://bugs.llvm.org/show_bug.cgi?id=32486 1471 1472define <4 x i32> @undef_elts_in_condition(<4 x i32> %a, <4 x i32> %b) { 1473; CHECK-LABEL: @undef_elts_in_condition( 1474; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> <i1 true, i1 undef, i1 false, i1 undef>, <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]] 1475; CHECK-NEXT: ret <4 x i32> [[SEL]] 1476; 1477 %sel = select <4 x i1> <i1 true, i1 undef, i1 false, i1 undef>, <4 x i32> %a, <4 x i32> %b 1478 ret <4 x i32> %sel 1479} 1480 1481; Don't die or try if the condition mask is a constant expression or contains a constant expression. 1482 1483@g = global i32 0 1484 1485define <4 x i32> @cannot_canonicalize_to_shuffle1(<4 x i32> %a, <4 x i32> %b) { 1486; CHECK-LABEL: @cannot_canonicalize_to_shuffle1( 1487; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> bitcast (i4 ptrtoint (ptr @g to i4) to <4 x i1>), <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]] 1488; CHECK-NEXT: ret <4 x i32> [[SEL]] 1489; 1490 %sel = select <4 x i1> bitcast (i4 ptrtoint (ptr @g to i4) to <4 x i1>), <4 x i32> %a, <4 x i32> %b 1491 ret <4 x i32> %sel 1492} 1493 1494define <4 x i32> @cannot_canonicalize_to_shuffle2(<4 x i32> %a, <4 x i32> %b) { 1495; CHECK-LABEL: @cannot_canonicalize_to_shuffle2( 1496; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> <i1 true, i1 undef, i1 false, i1 ptrtoint (ptr @g to i1)>, <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]] 1497; CHECK-NEXT: ret <4 x i32> [[SEL]] 1498; 1499 %sel = select <4 x i1> <i1 true, i1 undef, i1 false, i1 ptrtoint (ptr @g to i1)>, <4 x i32> %a, <4 x i32> %b 1500 ret <4 x i32> %sel 1501} 1502 1503declare void @llvm.assume(i1) 1504 1505define i8 @assume_cond_true(i1 %cond, i8 %x, i8 %y) { 1506; CHECK-LABEL: @assume_cond_true( 1507; CHECK-NEXT: call void @llvm.assume(i1 [[COND:%.*]]) 1508; CHECK-NEXT: ret i8 [[X:%.*]] 1509; 1510 call void @llvm.assume(i1 %cond) 1511 %sel = select i1 %cond, i8 %x, i8 %y 1512 ret i8 %sel 1513} 1514 1515; computeKnownBitsFromAssume() understands the 'not' of an assumed condition. 1516 1517define i8 @assume_cond_false(i1 %cond, i8 %x, i8 %y) { 1518; CHECK-LABEL: @assume_cond_false( 1519; CHECK-NEXT: [[NOTCOND:%.*]] = xor i1 [[COND:%.*]], true 1520; CHECK-NEXT: call void @llvm.assume(i1 [[NOTCOND]]) 1521; CHECK-NEXT: ret i8 [[Y:%.*]] 1522; 1523 %notcond = xor i1 %cond, true 1524 call void @llvm.assume(i1 %notcond) 1525 %sel = select i1 %cond, i8 %x, i8 %y 1526 ret i8 %sel 1527} 1528 1529; Test case to make sure we don't consider an all ones float values for converting the select into a sext. 1530define <4 x float> @PR33721(<4 x float> %w) { 1531; CHECK-LABEL: @PR33721( 1532; CHECK-NEXT: entry: 1533; CHECK-NEXT: [[TMP0:%.*]] = fcmp ole <4 x float> [[W:%.*]], zeroinitializer 1534; CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> [[TMP0]], <4 x float> splat (float 0xFFFFFFFFE0000000), <4 x float> zeroinitializer 1535; CHECK-NEXT: ret <4 x float> [[TMP1]] 1536; 1537entry: 1538 %0 = fcmp ole <4 x float> %w, zeroinitializer 1539 %1 = select <4 x i1> %0, <4 x float> <float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000>, <4 x float> zeroinitializer 1540 ret <4 x float> %1 1541} 1542 1543; select(C, binop(select(C, X, Y), W), Z) -> select(C, binop(X, W), Z) 1544define i8 @test87(i1 %cond, i8 %w, i8 %x, i8 %y, i8 %z) { 1545; CHECK-LABEL: @test87( 1546; CHECK-NEXT: [[B:%.*]] = add i8 [[X:%.*]], [[W:%.*]] 1547; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], i8 [[B]], i8 [[Z:%.*]] 1548; CHECK-NEXT: ret i8 [[C]] 1549; 1550 %a = select i1 %cond, i8 %x, i8 %y 1551 %b = add i8 %a, %w 1552 %c = select i1 %cond, i8 %b, i8 %z 1553 ret i8 %c 1554} 1555 1556; select(C, binop(select(C, X, Y), W), Z) -> select(C, Z, binop(Y, W)) 1557define i8 @test88(i1 %cond, i8 %w, i8 %x, i8 %y, i8 %z) { 1558; CHECK-LABEL: @test88( 1559; CHECK-NEXT: [[B:%.*]] = sub i8 [[Y:%.*]], [[W:%.*]] 1560; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], i8 [[Z:%.*]], i8 [[B]] 1561; CHECK-NEXT: ret i8 [[C]] 1562; 1563 %a = select i1 %cond, i8 %x, i8 %y 1564 %b = sub i8 %a, %w 1565 %c = select i1 %cond, i8 %z, i8 %b 1566 ret i8 %c 1567} 1568 1569; select(C, Z, binop(W, select(C, X, Y))) -> select(C, binop(X, W), Z) 1570define i8 @test89(i1 %cond, i8 %w, i8 %x, i8 %y, i8 %z) { 1571; CHECK-LABEL: @test89( 1572; CHECK-NEXT: [[B:%.*]] = and i8 [[W:%.*]], [[X:%.*]] 1573; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], i8 [[B]], i8 [[Z:%.*]] 1574; CHECK-NEXT: ret i8 [[C]] 1575; 1576 %a = select i1 %cond, i8 %x, i8 %y 1577 %b = and i8 %w, %a 1578 %c = select i1 %cond, i8 %b, i8 %z 1579 ret i8 %c 1580} 1581 1582; select(C, Z, binop(W, select(C, X, Y))) -> select(C, Z, binop(W, Y)) 1583define i8 @test90(i1 %cond, i8 %w, i8 %x, i8 %y, i8 %z) { 1584; CHECK-LABEL: @test90( 1585; CHECK-NEXT: [[B:%.*]] = or i8 [[W:%.*]], [[Y:%.*]] 1586; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], i8 [[Z:%.*]], i8 [[B]] 1587; CHECK-NEXT: ret i8 [[C]] 1588; 1589 %a = select i1 %cond, i8 %x, i8 %y 1590 %b = or i8 %w, %a 1591 %c = select i1 %cond, i8 %z, i8 %b 1592 ret i8 %c 1593} 1594 1595define i32 @test_shl_zext_bool(i1 %t) { 1596; CHECK-LABEL: @test_shl_zext_bool( 1597; CHECK-NEXT: [[R:%.*]] = select i1 [[T:%.*]], i32 4, i32 0 1598; CHECK-NEXT: ret i32 [[R]] 1599; 1600 %r = select i1 %t, i32 4, i32 0 1601 ret i32 %r 1602} 1603 1604define <2 x i32> @test_shl_zext_bool_splat(<2 x i1> %t) { 1605; CHECK-LABEL: @test_shl_zext_bool_splat( 1606; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T:%.*]], <2 x i32> splat (i32 8), <2 x i32> zeroinitializer 1607; CHECK-NEXT: ret <2 x i32> [[R]] 1608; 1609 %r = select <2 x i1> %t, <2 x i32> <i32 8, i32 8>, <2 x i32> zeroinitializer 1610 ret <2 x i32> %r 1611} 1612 1613define <2 x i32> @test_shl_zext_bool_vec(<2 x i1> %t) { 1614; CHECK-LABEL: @test_shl_zext_bool_vec( 1615; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T:%.*]], <2 x i32> <i32 4, i32 8>, <2 x i32> zeroinitializer 1616; CHECK-NEXT: ret <2 x i32> [[R]] 1617; 1618 %r = select <2 x i1> %t, <2 x i32> <i32 4, i32 8>, <2 x i32> zeroinitializer 1619 ret <2 x i32> %r 1620} 1621 1622define float @copysign1(float %x) { 1623; CHECK-LABEL: @copysign1( 1624; CHECK-NEXT: [[R:%.*]] = call float @llvm.copysign.f32(float 1.000000e+00, float [[X:%.*]]) 1625; CHECK-NEXT: ret float [[R]] 1626; 1627 %i = bitcast float %x to i32 1628 %ispos = icmp sgt i32 %i, -1 1629 %r = select i1 %ispos, float 1.0, float -1.0 1630 ret float %r 1631} 1632 1633define float @copysign1_fmf(float %x) { 1634; CHECK-LABEL: @copysign1_fmf( 1635; CHECK-NEXT: [[R:%.*]] = call float @llvm.copysign.f32(float 1.000000e+00, float [[X:%.*]]) 1636; CHECK-NEXT: ret float [[R]] 1637; 1638 %i = bitcast float %x to i32 1639 %ispos = icmp sgt i32 %i, -1 1640 %r = select nsz ninf i1 %ispos, float 1.0, float -1.0 1641 ret float %r 1642} 1643 1644define <2 x float> @copysign2(<2 x float> %x) { 1645; CHECK-LABEL: @copysign2( 1646; CHECK-NEXT: [[TMP1:%.*]] = fneg <2 x float> [[X:%.*]] 1647; CHECK-NEXT: [[R:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> splat (float 4.200000e+01), <2 x float> [[TMP1]]) 1648; CHECK-NEXT: ret <2 x float> [[R]] 1649; 1650 %i = bitcast <2 x float> %x to <2 x i32> 1651 %isneg = icmp slt <2 x i32> %i, zeroinitializer 1652 %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> 1653 ret <2 x float> %r 1654} 1655 1656define float @copysign3(float %x) { 1657; CHECK-LABEL: @copysign3( 1658; CHECK-NEXT: [[TMP1:%.*]] = fneg float [[X:%.*]] 1659; CHECK-NEXT: [[R:%.*]] = call float @llvm.copysign.f32(float 4.300000e+01, float [[TMP1]]) 1660; CHECK-NEXT: ret float [[R]] 1661; 1662 %i = bitcast float %x to i32 1663 %ispos = icmp ult i32 %i, 2147483648 1664 %r = select fast i1 %ispos, float -43.0, float 43.0 1665 ret float %r 1666} 1667 1668define <2 x float> @copysign_vec_poison(<2 x float> %x) { 1669; CHECK-LABEL: @copysign_vec_poison( 1670; CHECK-NEXT: [[TMP1:%.*]] = fneg <2 x float> [[X:%.*]] 1671; CHECK-NEXT: [[R:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> splat (float 4.200000e+01), <2 x float> [[TMP1]]) 1672; CHECK-NEXT: ret <2 x float> [[R]] 1673; 1674 %i = bitcast <2 x float> %x to <2 x i32> 1675 %isneg = icmp ugt <2 x i32> %i, <i32 2147483647, i32 2147483647> 1676 %r = select arcp nnan <2 x i1> %isneg, <2 x float> <float 42.0, float poison>, <2 x float> <float -42.0, float -42.0> 1677 ret <2 x float> %r 1678} 1679 1680define <2 x float> @copysign_vec_poison1(<2 x float> %x) { 1681; CHECK-LABEL: @copysign_vec_poison1( 1682; CHECK-NEXT: [[R:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> splat (float 4.200000e+01), <2 x float> [[X:%.*]]) 1683; CHECK-NEXT: ret <2 x float> [[R]] 1684; 1685 %i = bitcast <2 x float> %x to <2 x i32> 1686 %isneg = icmp ult <2 x i32> %i, <i32 2147483648, i32 2147483648> 1687 %r = select arcp nnan <2 x i1> %isneg, <2 x float> <float 42.0, float 42.0>, <2 x float> <float poison, float -42.0> 1688 ret <2 x float> %r 1689} 1690 1691define <2 x float> @copysign_vec_poison3(<2 x float> %x) { 1692; CHECK-LABEL: @copysign_vec_poison3( 1693; CHECK-NEXT: [[R:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> splat (float 4.200000e+01), <2 x float> [[X:%.*]]) 1694; CHECK-NEXT: ret <2 x float> [[R]] 1695; 1696 %i = bitcast <2 x float> %x to <2 x i32> 1697 %isneg = icmp ugt <2 x i32> %i, <i32 2147483647, i32 2147483647> 1698 %r = select arcp nnan <2 x i1> %isneg, <2 x float> <float -42.0, float poison>, <2 x float> <float +42.0, float poison> 1699 ret <2 x float> %r 1700} 1701 1702declare void @use1(i1) 1703 1704; Negative test 1705 1706define float @copysign_extra_use(float %x) { 1707; CHECK-LABEL: @copysign_extra_use( 1708; CHECK-NEXT: [[I:%.*]] = bitcast float [[X:%.*]] to i32 1709; CHECK-NEXT: [[ISNEG:%.*]] = icmp slt i32 [[I]], 0 1710; CHECK-NEXT: call void @use1(i1 [[ISNEG]]) 1711; CHECK-NEXT: [[R:%.*]] = select i1 [[ISNEG]], float -4.400000e+01, float 4.400000e+01 1712; CHECK-NEXT: ret float [[R]] 1713; 1714 %i = bitcast float %x to i32 1715 %isneg = icmp ugt i32 %i, 2147483647 1716 call void @use1(i1 %isneg) 1717 %r = select i1 %isneg, float -44.0, float 44.0 1718 ret float %r 1719} 1720 1721; Negative test 1722 1723define float @copysign_type_mismatch(double %x) { 1724; CHECK-LABEL: @copysign_type_mismatch( 1725; CHECK-NEXT: [[I:%.*]] = bitcast double [[X:%.*]] to i64 1726; CHECK-NEXT: [[ISPOS:%.*]] = icmp sgt i64 [[I]], -1 1727; CHECK-NEXT: [[R:%.*]] = select i1 [[ISPOS]], float 1.000000e+00, float -1.000000e+00 1728; CHECK-NEXT: ret float [[R]] 1729; 1730 %i = bitcast double %x to i64 1731 %ispos = icmp sgt i64 %i, -1 1732 %r = select i1 %ispos, float 1.0, float -1.0 1733 ret float %r 1734} 1735 1736; Negative test 1737 1738define <2 x float> @copysign_type_mismatch2(<2 x float> %x) { 1739; CHECK-LABEL: @copysign_type_mismatch2( 1740; CHECK-NEXT: [[I:%.*]] = bitcast <2 x float> [[X:%.*]] to i64 1741; CHECK-NEXT: [[ISPOS:%.*]] = icmp sgt i64 [[I]], -1 1742; CHECK-NEXT: [[R:%.*]] = select i1 [[ISPOS]], <2 x float> splat (float 1.000000e+00), <2 x float> splat (float -1.000000e+00) 1743; CHECK-NEXT: ret <2 x float> [[R]] 1744; 1745 %i = bitcast <2 x float> %x to i64 1746 %ispos = icmp sgt i64 %i, -1 1747 %r = select i1 %ispos, <2 x float> <float 1.0, float 1.0>, <2 x float> <float -1.0, float -1.0> 1748 ret <2 x float> %r 1749} 1750 1751; Negative test 1752 1753define float @copysign_wrong_cmp(float %x) { 1754; CHECK-LABEL: @copysign_wrong_cmp( 1755; CHECK-NEXT: [[I:%.*]] = bitcast float [[X:%.*]] to i32 1756; CHECK-NEXT: [[ISPOS:%.*]] = icmp sgt i32 [[I]], 0 1757; CHECK-NEXT: [[R:%.*]] = select i1 [[ISPOS]], float 1.000000e+00, float -1.000000e+00 1758; CHECK-NEXT: ret float [[R]] 1759; 1760 %i = bitcast float %x to i32 1761 %ispos = icmp sgt i32 %i, 0 1762 %r = select i1 %ispos, float 1.0, float -1.0 1763 ret float %r 1764} 1765 1766; Negative test 1767 1768define float @copysign_wrong_const(float %x) { 1769; CHECK-LABEL: @copysign_wrong_const( 1770; CHECK-NEXT: [[I:%.*]] = bitcast float [[X:%.*]] to i32 1771; CHECK-NEXT: [[ISPOS:%.*]] = icmp sgt i32 [[I]], -1 1772; CHECK-NEXT: [[R:%.*]] = select i1 [[ISPOS]], float 2.000000e+00, float -1.000000e+00 1773; CHECK-NEXT: ret float [[R]] 1774; 1775 %i = bitcast float %x to i32 1776 %ispos = icmp sgt i32 %i, -1 1777 %r = select i1 %ispos, float 2.0, float -1.0 1778 ret float %r 1779} 1780 1781; TODO: we can replace select with a Phi. 1782define i32 @select_dominating_cond(i1 %cond, i32 %x, i32 %y) { 1783; CHECK-LABEL: @select_dominating_cond( 1784; CHECK-NEXT: entry: 1785; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 1786; CHECK: if.true: 1787; CHECK-NEXT: br label [[MERGE:%.*]] 1788; CHECK: if.false: 1789; CHECK-NEXT: br label [[MERGE]] 1790; CHECK: merge: 1791; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[Y:%.*]], [[IF_FALSE]] ], [ [[X:%.*]], [[IF_TRUE]] ] 1792; CHECK-NEXT: ret i32 [[S]] 1793; 1794entry: 1795 br i1 %cond, label %if.true, label %if.false 1796 1797if.true: 1798 br label %merge 1799 1800if.false: 1801 br label %merge 1802 1803merge: 1804 %s = select i1 %cond, i32 %x, i32 %y 1805 ret i32 %s 1806} 1807 1808define i32 @select_dominating_inverted(i1 %cond, i32 %x, i32 %y) { 1809; CHECK-LABEL: @select_dominating_inverted( 1810; CHECK-NEXT: entry: 1811; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]] 1812; CHECK: if.true: 1813; CHECK-NEXT: br label [[MERGE:%.*]] 1814; CHECK: if.false: 1815; CHECK-NEXT: br label [[MERGE]] 1816; CHECK: merge: 1817; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[X:%.*]], [[IF_FALSE]] ], [ [[Y:%.*]], [[IF_TRUE]] ] 1818; CHECK-NEXT: ret i32 [[S]] 1819; 1820entry: 1821 %inverted = xor i1 %cond, 1 1822 br i1 %inverted, label %if.true, label %if.false 1823 1824if.true: 1825 br label %merge 1826 1827if.false: 1828 br label %merge 1829 1830merge: 1831 %s = select i1 %cond, i32 %x, i32 %y 1832 ret i32 %s 1833} 1834 1835; More complex CFG: the block with select has multiple predecessors. 1836define i32 @select_dominating_cond_multiple_preds(i1 %cond, i1 %cond2, i1 %cond3, i32 %x, i32 %y) { 1837; CHECK-LABEL: @select_dominating_cond_multiple_preds( 1838; CHECK-NEXT: entry: 1839; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 1840; CHECK: if.true: 1841; CHECK-NEXT: br i1 [[COND2:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_TRUE_2:%.*]] 1842; CHECK: if.true.1: 1843; CHECK-NEXT: br label [[MERGE:%.*]] 1844; CHECK: if.true.2: 1845; CHECK-NEXT: br label [[MERGE]] 1846; CHECK: if.false: 1847; CHECK-NEXT: br i1 [[COND3:%.*]], label [[IF_FALSE_1:%.*]], label [[EXIT:%.*]] 1848; CHECK: if.false.1: 1849; CHECK-NEXT: br label [[MERGE]] 1850; CHECK: merge: 1851; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[Y:%.*]], [[IF_FALSE_1]] ], [ [[X:%.*]], [[IF_TRUE_2]] ], [ [[X]], [[IF_TRUE_1]] ] 1852; CHECK-NEXT: ret i32 [[S]] 1853; CHECK: exit: 1854; CHECK-NEXT: ret i32 0 1855; 1856entry: 1857 br i1 %cond, label %if.true, label %if.false 1858 1859if.true: 1860 br i1 %cond2, label %if.true.1, label %if.true.2 1861 1862if.true.1: 1863 br label %merge 1864 1865if.true.2: 1866 br label %merge 1867 1868if.false: 1869 br i1 %cond3, label %if.false.1, label %exit 1870 1871if.false.1: 1872 br label %merge 1873 1874merge: 1875 %s = select i1 %cond, i32 %x, i32 %y 1876 ret i32 %s 1877 1878exit: 1879 ret i32 0 1880} 1881 1882; More complex CFG for inverted case: the block with select has multiple predecessors. 1883define i32 @select_dominating_cond_inverted_multiple_preds(i1 %cond, i1 %cond2, i1 %cond3, i32 %x, i32 %y) { 1884; CHECK-LABEL: @select_dominating_cond_inverted_multiple_preds( 1885; CHECK-NEXT: entry: 1886; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]] 1887; CHECK: if.true: 1888; CHECK-NEXT: br i1 [[COND2:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_TRUE_2:%.*]] 1889; CHECK: if.true.1: 1890; CHECK-NEXT: br label [[MERGE:%.*]] 1891; CHECK: if.true.2: 1892; CHECK-NEXT: br label [[MERGE]] 1893; CHECK: if.false: 1894; CHECK-NEXT: br i1 [[COND3:%.*]], label [[IF_FALSE_1:%.*]], label [[EXIT:%.*]] 1895; CHECK: if.false.1: 1896; CHECK-NEXT: br label [[MERGE]] 1897; CHECK: merge: 1898; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[X:%.*]], [[IF_FALSE_1]] ], [ [[Y:%.*]], [[IF_TRUE_2]] ], [ [[Y]], [[IF_TRUE_1]] ] 1899; CHECK-NEXT: ret i32 [[S]] 1900; CHECK: exit: 1901; CHECK-NEXT: ret i32 0 1902; 1903entry: 1904 %inverted = xor i1 %cond, 1 1905 br i1 %inverted, label %if.true, label %if.false 1906 1907if.true: 1908 br i1 %cond2, label %if.true.1, label %if.true.2 1909 1910if.true.1: 1911 br label %merge 1912 1913if.true.2: 1914 br label %merge 1915 1916if.false: 1917 br i1 %cond3, label %if.false.1, label %exit 1918 1919if.false.1: 1920 br label %merge 1921 1922merge: 1923 %s = select i1 %cond, i32 %x, i32 %y 1924 ret i32 %s 1925 1926exit: 1927 ret i32 0 1928} 1929 1930; More complex CFG for inverted case: the block with select has multiple predecessors that can duplicate. 1931define i32 @select_dominating_cond_inverted_multiple_duplicating_preds(i1 %cond, i32 %cond2, i1 %cond3, i32 %x, i32 %y) { 1932; CHECK-LABEL: @select_dominating_cond_inverted_multiple_duplicating_preds( 1933; CHECK-NEXT: entry: 1934; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]] 1935; CHECK: if.true: 1936; CHECK-NEXT: switch i32 [[COND2:%.*]], label [[SWITCH_CASE_1:%.*]] [ 1937; CHECK-NEXT: i32 1, label [[MERGE:%.*]] 1938; CHECK-NEXT: i32 2, label [[MERGE]] 1939; CHECK-NEXT: i32 3, label [[MERGE]] 1940; CHECK-NEXT: ] 1941; CHECK: switch.case.1: 1942; CHECK-NEXT: br label [[MERGE]] 1943; CHECK: if.false: 1944; CHECK-NEXT: br i1 [[COND3:%.*]], label [[IF_FALSE_1:%.*]], label [[EXIT:%.*]] 1945; CHECK: if.false.1: 1946; CHECK-NEXT: br label [[MERGE]] 1947; CHECK: merge: 1948; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[X:%.*]], [[IF_FALSE_1]] ], [ [[Y:%.*]], [[SWITCH_CASE_1]] ], [ [[Y]], [[IF_TRUE]] ], [ [[Y]], [[IF_TRUE]] ], [ [[Y]], [[IF_TRUE]] ] 1949; CHECK-NEXT: ret i32 [[S]] 1950; CHECK: exit: 1951; CHECK-NEXT: ret i32 0 1952; 1953entry: 1954 %inverted = xor i1 %cond, 1 1955 br i1 %inverted, label %if.true, label %if.false 1956 1957if.true: 1958 switch i32 %cond2, label %switch.case.1 [ 1959 i32 1, label %merge 1960 i32 2, label %merge 1961 i32 3, label %merge 1962 ] 1963 1964switch.case.1: 1965 br label %merge 1966 1967if.false: 1968 br i1 %cond3, label %if.false.1, label %exit 1969 1970if.false.1: 1971 br label %merge 1972 1973merge: 1974 %s = select i1 %cond, i32 %x, i32 %y 1975 ret i32 %s 1976 1977exit: 1978 ret i32 0 1979} 1980 1981; Negative test: currently we take condition from IDom, but might be willing to expand it in the future. 1982define i32 @select_not_imm_dominating_cond_neg(i1 %cond, i32 %x, i32 %y) { 1983; CHECK-LABEL: @select_not_imm_dominating_cond_neg( 1984; CHECK-NEXT: entry: 1985; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 1986; CHECK: if.true: 1987; CHECK-NEXT: br label [[MERGE:%.*]] 1988; CHECK: if.false: 1989; CHECK-NEXT: br label [[MERGE]] 1990; CHECK: merge: 1991; CHECK-NEXT: br label [[EXIT:%.*]] 1992; CHECK: exit: 1993; CHECK-NEXT: [[S:%.*]] = select i1 [[COND]], i32 [[X:%.*]], i32 [[Y:%.*]] 1994; CHECK-NEXT: ret i32 [[S]] 1995; 1996entry: 1997 br i1 %cond, label %if.true, label %if.false 1998 1999if.true: 2000 br label %merge 2001 2002if.false: 2003 br label %merge 2004 2005merge: 2006 br label %exit 2007 2008exit: 2009 %s = select i1 %cond, i32 %x, i32 %y 2010 ret i32 %s 2011} 2012 2013; Shows how we can leverage dominance to eliminate duplicating selects. 2014define i32 @select_dominance_chain(i1 %cond, i32 %x, i32 %y) { 2015; CHECK-LABEL: @select_dominance_chain( 2016; CHECK-NEXT: entry: 2017; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_FALSE_1:%.*]] 2018; CHECK: if.true.1: 2019; CHECK-NEXT: br label [[MERGE_1:%.*]] 2020; CHECK: if.false.1: 2021; CHECK-NEXT: br label [[MERGE_1]] 2022; CHECK: merge.1: 2023; CHECK-NEXT: br i1 [[COND]], label [[IF_TRUE_2:%.*]], label [[IF_FALSE_2:%.*]] 2024; CHECK: if.true.2: 2025; CHECK-NEXT: br label [[MERGE_2:%.*]] 2026; CHECK: if.false.2: 2027; CHECK-NEXT: br label [[MERGE_2]] 2028; CHECK: merge.2: 2029; CHECK-NEXT: br i1 [[COND]], label [[IF_TRUE_3:%.*]], label [[IF_FALSE_3:%.*]] 2030; CHECK: if.true.3: 2031; CHECK-NEXT: br label [[MERGE_3:%.*]] 2032; CHECK: if.false.3: 2033; CHECK-NEXT: br label [[MERGE_3]] 2034; CHECK: merge.3: 2035; CHECK-NEXT: [[S_1:%.*]] = phi i32 [ [[Y:%.*]], [[IF_FALSE_3]] ], [ [[X:%.*]], [[IF_TRUE_3]] ] 2036; CHECK-NEXT: [[SUM_2:%.*]] = mul i32 [[S_1]], 3 2037; CHECK-NEXT: ret i32 [[SUM_2]] 2038; 2039entry: 2040 br i1 %cond, label %if.true.1, label %if.false.1 2041 2042if.true.1: 2043 br label %merge.1 2044 2045if.false.1: 2046 br label %merge.1 2047 2048merge.1: 2049 %s.1 = select i1 %cond, i32 %x, i32 %y 2050 br i1 %cond, label %if.true.2, label %if.false.2 2051 2052if.true.2: 2053 br label %merge.2 2054 2055if.false.2: 2056 br label %merge.2 2057 2058merge.2: 2059 %s.2 = select i1 %cond, i32 %x, i32 %y 2060 br i1 %cond, label %if.true.3, label %if.false.3 2061 2062if.true.3: 2063 br label %merge.3 2064 2065if.false.3: 2066 br label %merge.3 2067 2068merge.3: 2069 %s.3 = select i1 %cond, i32 %x, i32 %y 2070 %sum.1 = add i32 %s.1, %s.2 2071 %sum.2 = add i32 %sum.1, %s.3 2072 ret i32 %sum.2 2073} 2074 2075; TODO: We can replace select with a Phi and then sink a and b to respective 2076; branches. 2077define i32 @select_dominating_cond_and_sink(i1 %cond, i32 %x, i32 %y) { 2078; CHECK-LABEL: @select_dominating_cond_and_sink( 2079; CHECK-NEXT: entry: 2080; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 2081; CHECK: if.true: 2082; CHECK-NEXT: br label [[MERGE:%.*]] 2083; CHECK: if.false: 2084; CHECK-NEXT: br label [[MERGE]] 2085; CHECK: merge: 2086; CHECK-NEXT: [[B:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]] 2087; CHECK-NEXT: [[A:%.*]] = add i32 [[X]], [[Y]] 2088; CHECK-NEXT: [[S:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]] 2089; CHECK-NEXT: ret i32 [[S]] 2090; 2091entry: 2092 %a = add i32 %x, %y 2093 %b = mul i32 %x, %y 2094 br i1 %cond, label %if.true, label %if.false 2095 2096if.true: 2097 br label %merge 2098 2099if.false: 2100 br label %merge 2101 2102merge: 2103 %s = select i1 %cond, i32 %a, i32 %b 2104 ret i32 %s 2105} 2106 2107define i32 @select_dominating_cond_same_labels(i1 %cond) { 2108; CHECK-LABEL: @select_dominating_cond_same_labels( 2109; CHECK-NEXT: entry: 2110; CHECK-NEXT: br i1 false, label [[EXIT:%.*]], label [[EXIT]] 2111; CHECK: exit: 2112; CHECK-NEXT: [[RESULT:%.*]] = select i1 [[COND:%.*]], i32 123, i32 456 2113; CHECK-NEXT: ret i32 [[RESULT]] 2114; 2115entry: 2116 %result = select i1 %cond, i32 123, i32 456 2117 br i1 %cond, label %exit, label %exit 2118exit: 2119 ret i32 %result 2120} 2121 2122define i32 @select_phi_same_condition(i1 %cond, i32 %x, i32 %y, i32 %z) { 2123; CHECK-LABEL: @select_phi_same_condition( 2124; CHECK-NEXT: entry: 2125; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 2126; CHECK: if.true: 2127; CHECK-NEXT: br label [[MERGE:%.*]] 2128; CHECK: if.false: 2129; CHECK-NEXT: br label [[MERGE]] 2130; CHECK: merge: 2131; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[X:%.*]], [[IF_TRUE]] ], [ [[Z:%.*]], [[IF_FALSE]] ] 2132; CHECK-NEXT: ret i32 [[S]] 2133; 2134entry: 2135 br i1 %cond, label %if.true, label %if.false 2136 2137if.true: 2138 br label %merge 2139 2140if.false: 2141 br label %merge 2142 2143merge: 2144 %phi = phi i32 [0, %if.true], [%z, %if.false] 2145 %s = select i1 %cond, i32 %x, i32 %phi 2146 ret i32 %s 2147} 2148 2149 2150; TODO: Replace with phi[a, c] and sink them to respective branches. 2151define i32 @select_phi_same_condition_sink(i1 %cond, i32 %x, i32 %y, i32 %z) { 2152; CHECK-LABEL: @select_phi_same_condition_sink( 2153; CHECK-NEXT: entry: 2154; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 2155; CHECK: if.true: 2156; CHECK-NEXT: br label [[MERGE:%.*]] 2157; CHECK: if.false: 2158; CHECK-NEXT: [[B:%.*]] = mul i32 [[X:%.*]], [[Z:%.*]] 2159; CHECK-NEXT: br label [[MERGE]] 2160; CHECK: merge: 2161; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[IF_TRUE]] ], [ [[B]], [[IF_FALSE]] ] 2162; CHECK-NEXT: [[A:%.*]] = add i32 [[X]], [[Y:%.*]] 2163; CHECK-NEXT: [[S:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[PHI]] 2164; CHECK-NEXT: ret i32 [[S]] 2165; 2166entry: 2167 %a = add i32 %x, %y 2168 %b = mul i32 %x, %z 2169 br i1 %cond, label %if.true, label %if.false 2170 2171if.true: 2172 br label %merge 2173 2174if.false: 2175 br label %merge 2176 2177merge: 2178 %phi = phi i32 [0, %if.true], [%b, %if.false] 2179 %s = select i1 %cond, i32 %a, i32 %phi 2180 ret i32 %s 2181} 2182 2183declare i32 @__gxx_personality_v0(...) 2184declare i1 @foo() 2185 2186define i32 @test_invoke_neg(i32 %x, i32 %y) nounwind uwtable ssp personality ptr @__gxx_personality_v0 { 2187; CHECK-LABEL: @test_invoke_neg( 2188; CHECK-NEXT: entry: 2189; CHECK-NEXT: [[COND:%.*]] = invoke i1 @foo() 2190; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 2191; CHECK: invoke.cont: 2192; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i32 [[X:%.*]], i32 [[Y:%.*]] 2193; CHECK-NEXT: ret i32 [[SEL]] 2194; CHECK: lpad: 2195; CHECK-NEXT: [[LP:%.*]] = landingpad { i1, i32 } 2196; CHECK-NEXT: filter [0 x i1] zeroinitializer 2197; CHECK-NEXT: unreachable 2198; 2199entry: 2200 %cond = invoke i1 @foo() 2201 to label %invoke.cont unwind label %lpad 2202 2203invoke.cont: 2204 %sel = select i1 %cond, i32 %x, i32 %y 2205 ret i32 %sel 2206 2207lpad: 2208 %lp = landingpad { i1, i32 } 2209 filter [0 x i1] zeroinitializer 2210 unreachable 2211} 2212 2213declare i32 @bar() 2214 2215define i32 @test_invoke_2_neg(i1 %cond, i32 %x, i32 %y) nounwind uwtable ssp personality ptr @__gxx_personality_v0 { 2216; CHECK-LABEL: @test_invoke_2_neg( 2217; CHECK-NEXT: entry: 2218; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 2219; CHECK: if.true: 2220; CHECK-NEXT: br label [[MERGE:%.*]] 2221; CHECK: if.false: 2222; CHECK-NEXT: [[RESULT:%.*]] = invoke i32 @bar() 2223; CHECK-NEXT: to label [[MERGE]] unwind label [[LPAD:%.*]] 2224; CHECK: merge: 2225; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[IF_TRUE]] ], [ [[RESULT]], [[IF_FALSE]] ] 2226; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i32 1, i32 [[PHI]] 2227; CHECK-NEXT: ret i32 [[SEL]] 2228; CHECK: lpad: 2229; CHECK-NEXT: [[LP:%.*]] = landingpad { i1, i32 } 2230; CHECK-NEXT: filter [0 x i1] zeroinitializer 2231; CHECK-NEXT: unreachable 2232; 2233entry: 2234 br i1 %cond, label %if.true, label %if.false 2235 2236if.true: 2237 br label %merge 2238 2239if.false: 2240 %result = invoke i32 @bar() 2241 to label %merge unwind label %lpad 2242 2243merge: 2244 %phi = phi i32 [ 0, %if.true ], [ %result, %if.false ] 2245 %sel = select i1 %cond, i32 1, i32 %phi 2246 ret i32 %sel 2247 2248lpad: 2249 %lp = landingpad { i1, i32 } 2250 filter [0 x i1] zeroinitializer 2251 unreachable 2252} 2253 2254define i32 @select_phi_same_condition_switch(i1 %cond, i32 %x, i32 %y) { 2255; CHECK-LABEL: @select_phi_same_condition_switch( 2256; CHECK-NEXT: entry: 2257; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 2258; CHECK: if.true: 2259; CHECK-NEXT: switch i32 [[X:%.*]], label [[EXIT:%.*]] [ 2260; CHECK-NEXT: i32 1, label [[MERGE:%.*]] 2261; CHECK-NEXT: i32 2, label [[MERGE]] 2262; CHECK-NEXT: ] 2263; CHECK: exit: 2264; CHECK-NEXT: ret i32 0 2265; CHECK: if.false: 2266; CHECK-NEXT: br label [[MERGE]] 2267; CHECK: merge: 2268; CHECK-NEXT: [[S:%.*]] = phi i32 [ [[X]], [[IF_TRUE]] ], [ [[X]], [[IF_TRUE]] ], [ [[Y:%.*]], [[IF_FALSE]] ] 2269; CHECK-NEXT: ret i32 [[S]] 2270; 2271entry: 2272 br i1 %cond, label %if.true, label %if.false 2273 2274if.true: 2275 switch i32 %x, label %exit [ 2276 i32 1, label %merge 2277 i32 2, label %merge 2278 ] 2279 2280exit: 2281 ret i32 0 2282 2283if.false: 2284 br label %merge 2285 2286merge: 2287 %phi = phi i32 [0, %if.true], [0, %if.true], [%y, %if.false] 2288 %s = select i1 %cond, i32 %x, i32 %phi 2289 ret i32 %s 2290} 2291 2292define i32 @transit_different_values_through_phi(i1 %cond, i1 %cond2) { 2293; CHECK-LABEL: @transit_different_values_through_phi( 2294; CHECK-NEXT: entry: 2295; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 2296; CHECK: if.true: 2297; CHECK-NEXT: br i1 [[COND2:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_TRUE_2:%.*]] 2298; CHECK: if.true.1: 2299; CHECK-NEXT: br label [[MERGE:%.*]] 2300; CHECK: if.true.2: 2301; CHECK-NEXT: br label [[MERGE]] 2302; CHECK: if.false: 2303; CHECK-NEXT: br label [[MERGE]] 2304; CHECK: merge: 2305; CHECK-NEXT: [[S:%.*]] = phi i32 [ 1, [[IF_TRUE_1]] ], [ 2, [[IF_TRUE_2]] ], [ 3, [[IF_FALSE]] ] 2306; CHECK-NEXT: ret i32 [[S]] 2307; CHECK: exit: 2308; CHECK-NEXT: ret i32 0 2309; 2310entry: 2311 br i1 %cond, label %if.true, label %if.false 2312 2313if.true: 2314 br i1 %cond2, label %if.true.1, label %if.true.2 2315 2316if.true.1: 2317 br label %merge 2318 2319if.true.2: 2320 br label %merge 2321 2322if.false: 2323 br label %merge 2324 2325merge: 2326 %p = phi i32 [ 1, %if.true.1 ], [ 2, %if.true.2 ], [ 4, %if.false ] 2327 %s = select i1 %cond, i32 %p, i32 3 2328 ret i32 %s 2329 2330exit: 2331 ret i32 0 2332} 2333 2334define i32 @select_phi_degenerate(i1 %cond, i1 %cond2) { 2335; CHECK-LABEL: @select_phi_degenerate( 2336; CHECK-NEXT: entry: 2337; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOP:%.*]], label [[EXIT:%.*]] 2338; CHECK: loop: 2339; CHECK-NEXT: [[SELECT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_INC:%.*]], [[LOOP]] ] 2340; CHECK-NEXT: [[IV_INC]] = add i32 [[SELECT]], 1 2341; CHECK-NEXT: br i1 [[COND2:%.*]], label [[LOOP]], label [[EXIT2:%.*]] 2342; CHECK: exit: 2343; CHECK-NEXT: ret i32 0 2344; CHECK: exit2: 2345; CHECK-NEXT: ret i32 [[IV_INC]] 2346; 2347entry: 2348 br i1 %cond, label %loop, label %exit 2349 2350loop: 2351 %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ] 2352 %select = select i1 %cond, i32 %iv, i32 -1 2353 %iv.inc = add i32 %select, 1 2354 br i1 %cond2, label %loop, label %exit2 2355 2356exit: 2357 ret i32 0 2358 2359exit2: 2360 ret i32 %iv.inc 2361} 2362 2363define i32 @test_select_into_phi_not_idom(i1 %cond, i32 %A, i32 %B) { 2364; CHECK-LABEL: @test_select_into_phi_not_idom( 2365; CHECK-NEXT: entry: 2366; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 2367; CHECK: if.true: 2368; CHECK-NEXT: br label [[MERGE:%.*]] 2369; CHECK: if.false: 2370; CHECK-NEXT: br label [[MERGE]] 2371; CHECK: merge: 2372; CHECK-NEXT: br label [[EXIT:%.*]] 2373; CHECK: exit: 2374; CHECK-NEXT: ret i32 [[A:%.*]] 2375; 2376entry: 2377 br i1 %cond, label %if.true, label %if.false 2378 2379if.true: 2380 br label %merge 2381 2382if.false: 2383 br label %merge 2384 2385merge: 2386 %phi = phi i32 [%A, %if.true], [%B, %if.false] 2387 br label %exit 2388 2389exit: 2390 %sel = select i1 %cond, i32 %phi, i32 %A 2391 ret i32 %sel 2392} 2393 2394define i32 @test_select_into_phi_not_idom_2(i1 %cond, i32 %A, i32 %B) { 2395; CHECK-LABEL: @test_select_into_phi_not_idom_2( 2396; CHECK-NEXT: entry: 2397; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 2398; CHECK: if.true: 2399; CHECK-NEXT: br label [[MERGE:%.*]] 2400; CHECK: if.false: 2401; CHECK-NEXT: br label [[MERGE]] 2402; CHECK: merge: 2403; CHECK-NEXT: br label [[EXIT:%.*]] 2404; CHECK: exit: 2405; CHECK-NEXT: ret i32 [[B:%.*]] 2406; 2407entry: 2408 br i1 %cond, label %if.true, label %if.false 2409 2410if.true: 2411 br label %merge 2412 2413if.false: 2414 br label %merge 2415 2416merge: 2417 %phi = phi i32 [%A, %if.true], [%B, %if.false] 2418 br label %exit 2419 2420exit: 2421 %sel = select i1 %cond, i32 %B, i32 %phi 2422 ret i32 %sel 2423} 2424 2425define i32 @test_select_into_phi_not_idom_inverted(i1 %cond, i32 %A, i32 %B) { 2426; CHECK-LABEL: @test_select_into_phi_not_idom_inverted( 2427; CHECK-NEXT: entry: 2428; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]] 2429; CHECK: if.true: 2430; CHECK-NEXT: br label [[MERGE:%.*]] 2431; CHECK: if.false: 2432; CHECK-NEXT: br label [[MERGE]] 2433; CHECK: merge: 2434; CHECK-NEXT: [[SEL:%.*]] = phi i32 [ [[A:%.*]], [[IF_TRUE]] ], [ [[B:%.*]], [[IF_FALSE]] ] 2435; CHECK-NEXT: br label [[EXIT:%.*]] 2436; CHECK: exit: 2437; CHECK-NEXT: ret i32 [[SEL]] 2438; 2439entry: 2440 %inverted = xor i1 %cond, 1 2441 br i1 %inverted, label %if.true, label %if.false 2442 2443if.true: 2444 br label %merge 2445 2446if.false: 2447 br label %merge 2448 2449merge: 2450 %phi = phi i32 [%A, %if.true], [%B, %if.false] 2451 br label %exit 2452 2453exit: 2454 %sel = select i1 %cond, i32 %phi, i32 %A 2455 ret i32 %sel 2456} 2457 2458define i32 @test_select_into_phi_not_idom_inverted_2(i1 %cond, i32 %A, i32 %B) { 2459; CHECK-LABEL: @test_select_into_phi_not_idom_inverted_2( 2460; CHECK-NEXT: entry: 2461; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]] 2462; CHECK: if.true: 2463; CHECK-NEXT: br label [[MERGE:%.*]] 2464; CHECK: if.false: 2465; CHECK-NEXT: br label [[MERGE]] 2466; CHECK: merge: 2467; CHECK-NEXT: [[SEL:%.*]] = phi i32 [ [[A:%.*]], [[IF_TRUE]] ], [ [[B:%.*]], [[IF_FALSE]] ] 2468; CHECK-NEXT: br label [[EXIT:%.*]] 2469; CHECK: exit: 2470; CHECK-NEXT: ret i32 [[SEL]] 2471; 2472entry: 2473 %inverted = xor i1 %cond, 1 2474 br i1 %inverted, label %if.true, label %if.false 2475 2476if.true: 2477 br label %merge 2478 2479if.false: 2480 br label %merge 2481 2482merge: 2483 %phi = phi i32 [%A, %if.true], [%B, %if.false] 2484 br label %exit 2485 2486exit: 2487 %sel = select i1 %cond, i32 %B, i32 %phi 2488 ret i32 %sel 2489} 2490 2491define i32 @test_select_into_phi_not_idom_no_dom_input_1(i1 %cond, i32 %A, i32 %B, ptr %p) { 2492; CHECK-LABEL: @test_select_into_phi_not_idom_no_dom_input_1( 2493; CHECK-NEXT: entry: 2494; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 2495; CHECK: if.true: 2496; CHECK-NEXT: [[C:%.*]] = load i32, ptr [[P:%.*]], align 4 2497; CHECK-NEXT: br label [[MERGE:%.*]] 2498; CHECK: if.false: 2499; CHECK-NEXT: br label [[MERGE]] 2500; CHECK: merge: 2501; CHECK-NEXT: [[SEL:%.*]] = phi i32 [ [[C]], [[IF_TRUE]] ], [ [[A:%.*]], [[IF_FALSE]] ] 2502; CHECK-NEXT: br label [[EXIT:%.*]] 2503; CHECK: exit: 2504; CHECK-NEXT: ret i32 [[SEL]] 2505; 2506entry: 2507 br i1 %cond, label %if.true, label %if.false 2508 2509if.true: 2510 %C = load i32, ptr %p 2511 br label %merge 2512 2513if.false: 2514 br label %merge 2515 2516merge: 2517 %phi = phi i32 [%C, %if.true], [%B, %if.false] 2518 br label %exit 2519 2520exit: 2521 %sel = select i1 %cond, i32 %phi, i32 %A 2522 ret i32 %sel 2523} 2524 2525define i32 @test_select_into_phi_not_idom_no_dom_input_2(i1 %cond, i32 %A, i32 %B, ptr %p) { 2526; CHECK-LABEL: @test_select_into_phi_not_idom_no_dom_input_2( 2527; CHECK-NEXT: entry: 2528; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 2529; CHECK: if.true: 2530; CHECK-NEXT: br label [[MERGE:%.*]] 2531; CHECK: if.false: 2532; CHECK-NEXT: [[C:%.*]] = load i32, ptr [[P:%.*]], align 4 2533; CHECK-NEXT: br label [[MERGE]] 2534; CHECK: merge: 2535; CHECK-NEXT: [[SEL:%.*]] = phi i32 [ [[B:%.*]], [[IF_TRUE]] ], [ [[C]], [[IF_FALSE]] ] 2536; CHECK-NEXT: br label [[EXIT:%.*]] 2537; CHECK: exit: 2538; CHECK-NEXT: ret i32 [[SEL]] 2539; 2540entry: 2541 br i1 %cond, label %if.true, label %if.false 2542 2543if.true: 2544 br label %merge 2545 2546if.false: 2547 %C = load i32, ptr %p 2548 br label %merge 2549 2550merge: 2551 %phi = phi i32 [%A, %if.true], [%C, %if.false] 2552 br label %exit 2553 2554exit: 2555 %sel = select i1 %cond, i32 %B, i32 %phi 2556 ret i32 %sel 2557} 2558 2559; Negative tests to ensure we don't remove selects with undef true/false values. 2560; See https://bugs.llvm.org/show_bug.cgi?id=31633 2561; https://lists.llvm.org/pipermail/llvm-dev/2016-October/106182.html 2562; https://reviews.llvm.org/D83360 2563define i32 @false_undef(i1 %cond, i32 %x) { 2564; CHECK-LABEL: @false_undef( 2565; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], i32 [[X:%.*]], i32 undef 2566; CHECK-NEXT: ret i32 [[S]] 2567; 2568 %s = select i1 %cond, i32 %x, i32 undef 2569 ret i32 %s 2570} 2571 2572define i32 @true_undef(i1 %cond, i32 %x) { 2573; CHECK-LABEL: @true_undef( 2574; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], i32 undef, i32 [[X:%.*]] 2575; CHECK-NEXT: ret i32 [[S]] 2576; 2577 %s = select i1 %cond, i32 undef, i32 %x 2578 ret i32 %s 2579} 2580 2581define <2 x i32> @false_undef_vec(i1 %cond, <2 x i32> %x) { 2582; CHECK-LABEL: @false_undef_vec( 2583; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], <2 x i32> [[X:%.*]], <2 x i32> undef 2584; CHECK-NEXT: ret <2 x i32> [[S]] 2585; 2586 %s = select i1 %cond, <2 x i32> %x, <2 x i32> undef 2587 ret <2 x i32> %s 2588} 2589 2590define <2 x i32> @true_undef_vec(i1 %cond, <2 x i32> %x) { 2591; CHECK-LABEL: @true_undef_vec( 2592; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], <2 x i32> undef, <2 x i32> [[X:%.*]] 2593; CHECK-NEXT: ret <2 x i32> [[S]] 2594; 2595 %s = select i1 %cond, <2 x i32> undef, <2 x i32> %x 2596 ret <2 x i32> %s 2597} 2598 2599define i8 @cond_freeze(i8 %x, i8 %y) { 2600; CHECK-LABEL: @cond_freeze( 2601; CHECK-NEXT: ret i8 [[Y:%.*]] 2602; 2603 %cond.fr = freeze i1 undef 2604 %s = select i1 %cond.fr, i8 %x, i8 %y 2605 ret i8 %s 2606} 2607 2608define i8 @cond_freeze_constant_false_val(i8 %x) { 2609; CHECK-LABEL: @cond_freeze_constant_false_val( 2610; CHECK-NEXT: ret i8 1 2611; 2612 %cond.fr = freeze i1 undef 2613 %s = select i1 %cond.fr, i8 %x, i8 1 2614 ret i8 %s 2615} 2616 2617define i8 @cond_freeze_constant_true_val(i8 %x) { 2618; CHECK-LABEL: @cond_freeze_constant_true_val( 2619; CHECK-NEXT: ret i8 1 2620; 2621 %cond.fr = freeze i1 undef 2622 %s = select i1 %cond.fr, i8 1, i8 %x 2623 ret i8 %s 2624} 2625 2626define i8 @cond_freeze_both_arms_constant() { 2627; CHECK-LABEL: @cond_freeze_both_arms_constant( 2628; CHECK-NEXT: ret i8 42 2629; 2630 %cond.fr = freeze i1 undef 2631 %s = select i1 %cond.fr, i8 42, i8 3 2632 ret i8 %s 2633} 2634 2635define <2 x i8> @cond_freeze_constant_true_val_vec(<2 x i8> %x) { 2636; CHECK-LABEL: @cond_freeze_constant_true_val_vec( 2637; CHECK-NEXT: ret <2 x i8> <i8 1, i8 2> 2638; 2639 %cond.fr = freeze <2 x i1> <i1 undef, i1 undef> 2640 %s = select <2 x i1> %cond.fr, <2 x i8> <i8 1, i8 2>, <2 x i8> %x 2641 ret <2 x i8> %s 2642} 2643 2644define <2 x i8> @partial_cond_freeze_constant_true_val_vec(<2 x i8> %x) { 2645; CHECK-LABEL: @partial_cond_freeze_constant_true_val_vec( 2646; CHECK-NEXT: ret <2 x i8> <i8 1, i8 2> 2647; 2648 %cond.fr = freeze <2 x i1> <i1 true, i1 undef> 2649 %s = select <2 x i1> %cond.fr, <2 x i8> <i8 1, i8 2>, <2 x i8> %x 2650 ret <2 x i8> %s 2651} 2652 2653define <2 x i8> @partial_cond_freeze_constant_false_val_vec(<2 x i8> %x) { 2654; CHECK-LABEL: @partial_cond_freeze_constant_false_val_vec( 2655; CHECK-NEXT: [[S1:%.*]] = insertelement <2 x i8> [[X:%.*]], i8 2, i64 1 2656; CHECK-NEXT: ret <2 x i8> [[S1]] 2657; 2658 %cond.fr = freeze <2 x i1> <i1 true, i1 undef> 2659 %s = select <2 x i1> %cond.fr, <2 x i8> %x, <2 x i8> <i8 1, i8 2> 2660 ret <2 x i8> %s 2661} 2662 2663define <2 x i8> @partial_cond_freeze_both_arms_constant_vec() { 2664; CHECK-LABEL: @partial_cond_freeze_both_arms_constant_vec( 2665; CHECK-NEXT: ret <2 x i8> <i8 42, i8 2> 2666; 2667 %cond.fr = freeze <2 x i1> <i1 false, i1 undef> 2668 %s = select <2 x i1> %cond.fr, <2 x i8> <i8 1, i8 2>, <2 x i8> <i8 42, i8 43> 2669 ret <2 x i8> %s 2670} 2671 2672declare void @foo2(i8, i8) 2673 2674define void @cond_freeze_multipleuses(i8 %x, i8 %y) { 2675; CHECK-LABEL: @cond_freeze_multipleuses( 2676; CHECK-NEXT: call void @foo2(i8 [[Y:%.*]], i8 [[X:%.*]]) 2677; CHECK-NEXT: ret void 2678; 2679 %cond.fr = freeze i1 undef 2680 %s = select i1 %cond.fr, i8 %x, i8 %y 2681 %s2 = select i1 %cond.fr, i8 %y, i8 %x 2682 call void @foo2(i8 %s, i8 %s2) 2683 ret void 2684} 2685 2686define i32 @select_freeze_icmp_eq(i32 %x, i32 %y) { 2687; CHECK-LABEL: @select_freeze_icmp_eq( 2688; CHECK-NEXT: ret i32 [[Y:%.*]] 2689; 2690 %c = icmp eq i32 %x, %y 2691 %c.fr = freeze i1 %c 2692 %v = select i1 %c.fr, i32 %x, i32 %y 2693 ret i32 %v 2694} 2695 2696define i32 @select_freeze_icmp_ne(i32 %x, i32 %y) { 2697; CHECK-LABEL: @select_freeze_icmp_ne( 2698; CHECK-NEXT: ret i32 [[X:%.*]] 2699; 2700 %c = icmp ne i32 %x, %y 2701 %c.fr = freeze i1 %c 2702 %v = select i1 %c.fr, i32 %x, i32 %y 2703 ret i32 %v 2704} 2705 2706define i32 @select_freeze_icmp_else(i32 %x, i32 %y) { 2707; CHECK-LABEL: @select_freeze_icmp_else( 2708; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 2709; CHECK-NEXT: [[C_FR:%.*]] = freeze i1 [[C]] 2710; CHECK-NEXT: [[V:%.*]] = select i1 [[C_FR]], i32 [[X]], i32 [[Y]] 2711; CHECK-NEXT: ret i32 [[V]] 2712; 2713 %c = icmp ult i32 %x, %y 2714 %c.fr = freeze i1 %c 2715 %v = select i1 %c.fr, i32 %x, i32 %y 2716 ret i32 %v 2717} 2718 2719declare void @use_i1_i32(i1, i32) 2720 2721define void @select_freeze_icmp_multuses(i32 %x, i32 %y) { 2722; CHECK-LABEL: @select_freeze_icmp_multuses( 2723; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]] 2724; CHECK-NEXT: [[C_FR:%.*]] = freeze i1 [[C]] 2725; CHECK-NEXT: [[V:%.*]] = select i1 [[C_FR]], i32 [[X]], i32 [[Y]] 2726; CHECK-NEXT: call void @use_i1_i32(i1 [[C_FR]], i32 [[V]]) 2727; CHECK-NEXT: ret void 2728; 2729 %c = icmp ne i32 %x, %y 2730 %c.fr = freeze i1 %c 2731 %v = select i1 %c.fr, i32 %x, i32 %y 2732 call void @use_i1_i32(i1 %c.fr, i32 %v) 2733 ret void 2734} 2735 2736define i32 @pr47322_more_poisonous_replacement(i32 %arg) { 2737; CHECK-LABEL: @pr47322_more_poisonous_replacement( 2738; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[ARG:%.*]], 0 2739; CHECK-NEXT: [[TRAILING:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[ARG]], i1 true) 2740; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[ARG]], [[TRAILING]] 2741; CHECK-NEXT: [[R1_SROA_0_1:%.*]] = select i1 [[CMP]], i32 0, i32 [[SHIFTED]] 2742; CHECK-NEXT: ret i32 [[R1_SROA_0_1]] 2743; 2744 %cmp = icmp eq i32 %arg, 0 2745 %trailing = call i32 @llvm.cttz.i32(i32 %arg, i1 true) 2746 %shifted = lshr i32 %arg, %trailing 2747 %r1.sroa.0.1 = select i1 %cmp, i32 0, i32 %shifted 2748 ret i32 %r1.sroa.0.1 2749} 2750 2751define i8 @select_replacement_add_eq(i8 %x, i8 %y) { 2752; CHECK-LABEL: @select_replacement_add_eq( 2753; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 1 2754; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 2, i8 [[Y:%.*]] 2755; CHECK-NEXT: ret i8 [[SEL]] 2756; 2757 %cmp = icmp eq i8 %x, 1 2758 %add = add i8 %x, 1 2759 %sel = select i1 %cmp, i8 %add, i8 %y 2760 ret i8 %sel 2761} 2762 2763define <2 x i8> @select_replacement_add_eq_vec(<2 x i8> %x, <2 x i8> %y) { 2764; CHECK-LABEL: @select_replacement_add_eq_vec( 2765; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 1) 2766; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> splat (i8 2), <2 x i8> [[Y:%.*]] 2767; CHECK-NEXT: ret <2 x i8> [[SEL]] 2768; 2769 %cmp = icmp eq <2 x i8> %x, <i8 1, i8 1> 2770 %add = add <2 x i8> %x, <i8 1, i8 1> 2771 %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y 2772 ret <2 x i8> %sel 2773} 2774 2775define <2 x i8> @select_replacement_add_eq_vec_nonuniform(<2 x i8> %x, <2 x i8> %y) { 2776; CHECK-LABEL: @select_replacement_add_eq_vec_nonuniform( 2777; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 1, i8 2> 2778; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> <i8 4, i8 6>, <2 x i8> [[Y:%.*]] 2779; CHECK-NEXT: ret <2 x i8> [[SEL]] 2780; 2781 %cmp = icmp eq <2 x i8> %x, <i8 1, i8 2> 2782 %add = add <2 x i8> %x, <i8 3, i8 4> 2783 %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y 2784 ret <2 x i8> %sel 2785} 2786 2787define <2 x i8> @select_replacement_add_eq_vec_poison(<2 x i8> %x, <2 x i8> %y) { 2788; CHECK-LABEL: @select_replacement_add_eq_vec_poison( 2789; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 1, i8 poison> 2790; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> <i8 2, i8 poison>, <2 x i8> [[Y:%.*]] 2791; CHECK-NEXT: ret <2 x i8> [[SEL]] 2792; 2793 %cmp = icmp eq <2 x i8> %x, <i8 1, i8 poison> 2794 %add = add <2 x i8> %x, <i8 1, i8 1> 2795 %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y 2796 ret <2 x i8> %sel 2797} 2798 2799define <2 x i8> @select_replacement_add_eq_vec_undef(<2 x i8> %x, <2 x i8> %y) { 2800; CHECK-LABEL: @select_replacement_add_eq_vec_undef( 2801; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 1, i8 undef> 2802; CHECK-NEXT: [[ADD:%.*]] = add <2 x i8> [[X]], splat (i8 1) 2803; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[ADD]], <2 x i8> [[Y:%.*]] 2804; CHECK-NEXT: ret <2 x i8> [[SEL]] 2805; 2806 %cmp = icmp eq <2 x i8> %x, <i8 1, i8 undef> 2807 %add = add <2 x i8> %x, <i8 1, i8 1> 2808 %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y 2809 ret <2 x i8> %sel 2810} 2811 2812define <2 x i8> @select_replacement_add_eq_vec_undef_okay(<2 x i8> %x, <2 x i8> %y) { 2813; CHECK-LABEL: @select_replacement_add_eq_vec_undef_okay( 2814; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 1) 2815; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> <i8 2, i8 undef>, <2 x i8> [[Y:%.*]] 2816; CHECK-NEXT: ret <2 x i8> [[SEL]] 2817; 2818 %cmp = icmp eq <2 x i8> %x, <i8 1, i8 1> 2819 %add = add <2 x i8> %x, <i8 1, i8 undef> 2820 %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y 2821 ret <2 x i8> %sel 2822} 2823 2824 2825define <2 x i8> @select_replacement_add_eq_vec_undef_okay_todo(<2 x i8> %x, <2 x i8> %y) { 2826; CHECK-LABEL: @select_replacement_add_eq_vec_undef_okay_todo( 2827; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 1, i8 undef> 2828; CHECK-NEXT: [[ADD:%.*]] = add <2 x i8> [[X]], <i8 1, i8 undef> 2829; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[ADD]], <2 x i8> [[Y:%.*]] 2830; CHECK-NEXT: ret <2 x i8> [[SEL]] 2831; 2832 %cmp = icmp eq <2 x i8> %x, <i8 1, i8 undef> 2833 %add = add <2 x i8> %x, <i8 1, i8 undef> 2834 %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %y 2835 ret <2 x i8> %sel 2836} 2837 2838define <2 x i8> @select_replacement_xor_eq_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 2839; CHECK-LABEL: @select_replacement_xor_eq_vec( 2840; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], [[Y:%.*]] 2841; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> zeroinitializer, <2 x i8> [[Z:%.*]] 2842; CHECK-NEXT: ret <2 x i8> [[SEL]] 2843; 2844 %cmp = icmp eq <2 x i8> %x, %y 2845 %add = xor <2 x i8> %x, %y 2846 %sel = select <2 x i1> %cmp, <2 x i8> %add, <2 x i8> %z 2847 ret <2 x i8> %sel 2848} 2849 2850 2851define i8 @select_replacement_add_ne(i8 %x, i8 %y) { 2852; CHECK-LABEL: @select_replacement_add_ne( 2853; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[X:%.*]], 1 2854; CHECK-NEXT: call void @use(i1 [[CMP]]) 2855; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[Y:%.*]], i8 2 2856; CHECK-NEXT: ret i8 [[SEL]] 2857; 2858 %cmp = icmp ne i8 %x, 1 2859 call void @use(i1 %cmp) 2860 %add = add i8 %x, 1 2861 %sel = select i1 %cmp, i8 %y, i8 %add 2862 ret i8 %sel 2863} 2864 2865define i8 @select_replacement_add_nuw(i8 %x, i8 %y) { 2866; CHECK-LABEL: @select_replacement_add_nuw( 2867; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 1 2868; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 2, i8 [[Y:%.*]] 2869; CHECK-NEXT: ret i8 [[SEL]] 2870; 2871 %cmp = icmp eq i8 %x, 1 2872 %add = add nuw i8 %x, 1 2873 %sel = select i1 %cmp, i8 %add, i8 %y 2874 ret i8 %sel 2875} 2876 2877define i8 @select_replacement_sub_noundef(i8 %x, i8 noundef %y, i8 %z) { 2878; CHECK-LABEL: @select_replacement_sub_noundef( 2879; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]] 2880; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 0, i8 [[Z:%.*]] 2881; CHECK-NEXT: ret i8 [[SEL]] 2882; 2883 %cmp = icmp eq i8 %x, %y 2884 %sub = sub i8 %x, %y 2885 %sel = select i1 %cmp, i8 %sub, i8 %z 2886 ret i8 %sel 2887} 2888 2889define i8 @select_replacement_sub_noundef_but_may_be_poison(i8 %x, i8 noundef %yy, i8 %z) { 2890; CHECK-LABEL: @select_replacement_sub_noundef_but_may_be_poison( 2891; CHECK-NEXT: [[Y:%.*]] = shl nuw i8 [[YY:%.*]], 1 2892; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], [[Y]] 2893; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 0, i8 [[Z:%.*]] 2894; CHECK-NEXT: ret i8 [[SEL]] 2895; 2896 %y = shl nuw i8 %yy, 1 2897 %cmp = icmp eq i8 %x, %y 2898 %sub = sub i8 %x, %y 2899 %sel = select i1 %cmp, i8 %sub, i8 %z 2900 ret i8 %sel 2901} 2902 2903; TODO: The transform is also safe without noundef. 2904define i8 @select_replacement_sub(i8 %x, i8 %y, i8 %z) { 2905; CHECK-LABEL: @select_replacement_sub( 2906; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]] 2907; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 0, i8 [[Z:%.*]] 2908; CHECK-NEXT: ret i8 [[SEL]] 2909; 2910 %cmp = icmp eq i8 %x, %y 2911 %sub = sub i8 %x, %y 2912 %sel = select i1 %cmp, i8 %sub, i8 %z 2913 ret i8 %sel 2914} 2915 2916; FIXME: This is safe to fold. 2917define i8 @select_replacement_shift_noundef(i8 %x, i8 %y, i8 %z) { 2918; CHECK-LABEL: @select_replacement_shift_noundef( 2919; CHECK-NEXT: [[SHR:%.*]] = lshr exact i8 [[X:%.*]], 1 2920; CHECK-NEXT: call void @use_i8(i8 noundef [[SHR]]) 2921; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[SHR]], [[Y:%.*]] 2922; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[Y]], 1 2923; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[SHL]], i8 [[Z:%.*]] 2924; CHECK-NEXT: ret i8 [[SEL]] 2925; 2926 %shr = lshr exact i8 %x, 1 2927 call void @use_i8(i8 noundef %shr) 2928 %cmp = icmp eq i8 %shr, %y 2929 %shl = shl i8 %y, 1 2930 %sel = select i1 %cmp, i8 %shl, i8 %z 2931 ret i8 %sel 2932} 2933 2934; TODO: The transform is also safe without noundef. 2935define i8 @select_replacement_shift(i8 %x, i8 %y, i8 %z) { 2936; CHECK-LABEL: @select_replacement_shift( 2937; CHECK-NEXT: [[SHR:%.*]] = lshr exact i8 [[X:%.*]], 1 2938; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[SHR]], [[Y:%.*]] 2939; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[Y]], 1 2940; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[SHL]], i8 [[Z:%.*]] 2941; CHECK-NEXT: ret i8 [[SEL]] 2942; 2943 %shr = lshr exact i8 %x, 1 2944 %cmp = icmp eq i8 %shr, %y 2945 %shl = shl i8 %y, 1 2946 %sel = select i1 %cmp, i8 %shl, i8 %z 2947 ret i8 %sel 2948} 2949 2950define i8 @select_replacement_loop(i8 %x, i8 %y, i8 %z) { 2951; CHECK-LABEL: @select_replacement_loop( 2952; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]] 2953; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[X]], i8 [[Z:%.*]] 2954; CHECK-NEXT: ret i8 [[SEL]] 2955; 2956 %cmp = icmp eq i8 %x, %y 2957 %sel = select i1 %cmp, i8 %x, i8 %z 2958 ret i8 %sel 2959} 2960 2961define i32 @select_replacement_loop2(i32 %arg, i32 %arg2) { 2962; CHECK-LABEL: @select_replacement_loop2( 2963; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[ARG:%.*]], [[ARG2:%.*]] 2964; CHECK-NEXT: ret i32 [[DIV]] 2965; 2966 %div = udiv i32 %arg, %arg2 2967 %mul = mul nsw i32 %div, %arg2 2968 %cmp = icmp eq i32 %mul, %arg 2969 %sel = select i1 %cmp, i32 %div, i32 undef 2970 ret i32 %sel 2971} 2972 2973define i8 @select_replacement_loop3(i32 noundef %x) { 2974; CHECK-LABEL: @select_replacement_loop3( 2975; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[X:%.*]] to i8 2976; CHECK-NEXT: [[REV:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[TRUNC]]) 2977; CHECK-NEXT: [[EXT:%.*]] = zext i8 [[REV]] to i32 2978; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[EXT]] 2979; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[TRUNC]], i8 0 2980; CHECK-NEXT: ret i8 [[SEL]] 2981; 2982 %trunc = trunc i32 %x to i8 2983 %rev = call i8 @llvm.bitreverse.i8(i8 %trunc) 2984 %ext = zext i8 %rev to i32 2985 %cmp = icmp eq i32 %ext, %x 2986 %sel = select i1 %cmp, i8 %trunc, i8 0 2987 ret i8 %sel 2988} 2989 2990define i16 @select_replacement_loop4(i16 noundef %p_12) { 2991; CHECK-LABEL: @select_replacement_loop4( 2992; CHECK-NEXT: [[P_12:%.*]] = call i16 @llvm.umin.i16(i16 [[P_13:%.*]], i16 2) 2993; CHECK-NEXT: [[AND1:%.*]] = and i16 [[P_12]], 1 2994; CHECK-NEXT: ret i16 [[AND1]] 2995; 2996 %cmp1 = icmp ult i16 %p_12, 2 2997 %and1 = and i16 %p_12, 1 2998 %and2 = select i1 %cmp1, i16 %and1, i16 0 2999 %cmp2 = icmp eq i16 %and2, %p_12 3000 %and3 = select i1 %cmp2, i16 %and1, i16 0 3001 ret i16 %and3 3002} 3003 3004define ptr @select_replacement_gep_inbounds(ptr %base, i64 %offset) { 3005; CHECK-LABEL: @select_replacement_gep_inbounds( 3006; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[BASE:%.*]], i64 [[OFFSET:%.*]] 3007; CHECK-NEXT: ret ptr [[GEP]] 3008; 3009 %cmp = icmp eq i64 %offset, 0 3010 %gep = getelementptr inbounds i8, ptr %base, i64 %offset 3011 %sel = select i1 %cmp, ptr %base, ptr %gep 3012 ret ptr %sel 3013} 3014 3015define i8 @replace_false_op_eq_shl_or_disjoint(i8 %x) { 3016; CHECK-LABEL: @replace_false_op_eq_shl_or_disjoint( 3017; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[X:%.*]], 3 3018; CHECK-NEXT: [[OR:%.*]] = or i8 [[X]], [[SHL]] 3019; CHECK-NEXT: ret i8 [[OR]] 3020; 3021 %eq0 = icmp eq i8 %x, -1 3022 %shl = shl i8 %x, 3 3023 %or = or disjoint i8 %x, %shl 3024 %sel = select i1 %eq0, i8 -1, i8 %or 3025 ret i8 %sel 3026} 3027 3028define i8 @select_or_disjoint_eq(i8 %x, i8 %y) { 3029; CHECK-LABEL: @select_or_disjoint_eq( 3030; CHECK-NEXT: [[OR:%.*]] = or i8 [[X:%.*]], [[Y:%.*]] 3031; CHECK-NEXT: ret i8 [[OR]] 3032; 3033 %cmp = icmp eq i8 %x, %y 3034 %or = or disjoint i8 %x, %y 3035 %sel = select i1 %cmp, i8 %x, i8 %or 3036 ret i8 %sel 3037} 3038 3039define <2 x i1> @partial_true_undef_condval(<2 x i1> %x) { 3040; CHECK-LABEL: @partial_true_undef_condval( 3041; CHECK-NEXT: ret <2 x i1> <i1 true, i1 poison> 3042; 3043 %r = select <2 x i1> <i1 true, i1 poison>, <2 x i1> <i1 true, i1 poison>, <2 x i1> %x 3044 ret <2 x i1> %r 3045} 3046 3047define <2 x i1> @partial_false_undef_condval(<2 x i1> %x) { 3048; CHECK-LABEL: @partial_false_undef_condval( 3049; CHECK-NEXT: ret <2 x i1> <i1 false, i1 poison> 3050; 3051 %r = select <2 x i1> <i1 false, i1 poison>, <2 x i1> %x, <2 x i1> <i1 false, i1 poison> 3052 ret <2 x i1> %r 3053} 3054 3055; select (x == 0), 0, x * y --> freeze(y) * x 3056define i32 @mul_select_eq_zero(i32 %x, i32 %y) { 3057; CHECK-LABEL: @mul_select_eq_zero( 3058; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y:%.*]] 3059; CHECK-NEXT: [[M:%.*]] = mul i32 [[X:%.*]], [[Y_FR]] 3060; CHECK-NEXT: ret i32 [[M]] 3061; 3062 %c = icmp eq i32 %x, 0 3063 %m = mul i32 %x, %y 3064 %r = select i1 %c, i32 0, i32 %m 3065 ret i32 %r 3066} 3067 3068; select (y == 0), 0, x * y --> freeze(x) * y 3069define i32 @mul_select_eq_zero_commute(i32 %x, i32 %y) { 3070; CHECK-LABEL: @mul_select_eq_zero_commute( 3071; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X:%.*]] 3072; CHECK-NEXT: [[M:%.*]] = mul i32 [[X_FR]], [[Y:%.*]] 3073; CHECK-NEXT: ret i32 [[M]] 3074; 3075 %c = icmp eq i32 %y, 0 3076 %m = mul i32 %x, %y 3077 %r = select i1 %c, i32 0, i32 %m 3078 ret i32 %r 3079} 3080 3081; Check that mul's flags preserved during the transformation. 3082define i32 @mul_select_eq_zero_copy_flags(i32 %x, i32 %y) { 3083; CHECK-LABEL: @mul_select_eq_zero_copy_flags( 3084; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y:%.*]] 3085; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[X:%.*]], [[Y_FR]] 3086; CHECK-NEXT: ret i32 [[M]] 3087; 3088 %c = icmp eq i32 %x, 0 3089 %m = mul nuw nsw i32 %x, %y 3090 %r = select i1 %c, i32 0, i32 %m 3091 ret i32 %r 3092} 3093 3094; Check that the transformation could be applied after condition's inversion. 3095; select (x != 0), x * y, 0 --> freeze(y) * x 3096define i32 @mul_select_ne_zero(i32 %x, i32 %y) { 3097; CHECK-LABEL: @mul_select_ne_zero( 3098; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[X:%.*]], 0 3099; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y:%.*]] 3100; CHECK-NEXT: [[M:%.*]] = mul i32 [[X]], [[Y_FR]] 3101; CHECK-NEXT: call void @use(i1 [[C]]) 3102; CHECK-NEXT: ret i32 [[M]] 3103; 3104 %c = icmp ne i32 %x, 0 3105 %m = mul i32 %x, %y 3106 %r = select i1 %c, i32 %m, i32 0 3107 call void @use(i1 %c) 3108 ret i32 %r 3109} 3110 3111; Check that if one of a select's branches returns undef then 3112; an expression could be folded into mul as if there was a 0 instead of undef. 3113; select (x == 0), undef, x * y --> freeze(y) * x 3114define i32 @mul_select_eq_zero_sel_undef(i32 %x, i32 %y) { 3115; CHECK-LABEL: @mul_select_eq_zero_sel_undef( 3116; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y:%.*]] 3117; CHECK-NEXT: [[M:%.*]] = mul i32 [[X:%.*]], [[Y_FR]] 3118; CHECK-NEXT: ret i32 [[M]] 3119; 3120 %c = icmp eq i32 %x, 0 3121 %m = mul i32 %x, %y 3122 %r = select i1 %c, i32 undef, i32 %m 3123 ret i32 %r 3124} 3125 3126; Check that the transformation is applied disregard to a number 3127; of expression's users. 3128define i32 @mul_select_eq_zero_multiple_users(i32 %x, i32 %y) { 3129; CHECK-LABEL: @mul_select_eq_zero_multiple_users( 3130; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y:%.*]] 3131; CHECK-NEXT: [[M:%.*]] = mul i32 [[X:%.*]], [[Y_FR]] 3132; CHECK-NEXT: call void @use_i32(i32 [[M]]) 3133; CHECK-NEXT: call void @use_i32(i32 [[M]]) 3134; CHECK-NEXT: call void @use_i32(i32 [[M]]) 3135; CHECK-NEXT: ret i32 [[M]] 3136; 3137 %m = mul i32 %x, %y 3138 call void @use_i32(i32 %m) 3139 %c = icmp eq i32 %x, 0 3140 %r = select i1 %c, i32 0, i32 %m 3141 call void @use_i32(i32 %m) 3142 call void @use_i32(i32 %r) 3143 ret i32 %r 3144} 3145 3146; Negative test: select's condition is unrelated to multiplied values, 3147; so the transformation should not be applied. 3148define i32 @mul_select_eq_zero_unrelated_condition(i32 %x, i32 %y, i32 %z) { 3149; CHECK-LABEL: @mul_select_eq_zero_unrelated_condition( 3150; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[Z:%.*]], 0 3151; CHECK-NEXT: [[M:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]] 3152; CHECK-NEXT: [[R:%.*]] = select i1 [[C]], i32 0, i32 [[M]] 3153; CHECK-NEXT: ret i32 [[R]] 3154; 3155 %c = icmp eq i32 %z, 0 3156 %m = mul i32 %x, %y 3157 %r = select i1 %c, i32 0, i32 %m 3158 ret i32 %r 3159} 3160 3161; select (<k x elt> x == 0), <k x elt> 0, <k x elt> x * y --> freeze(y) * x 3162define <4 x i32> @mul_select_eq_zero_vector(<4 x i32> %x, <4 x i32> %y) { 3163; CHECK-LABEL: @mul_select_eq_zero_vector( 3164; CHECK-NEXT: [[Y_FR:%.*]] = freeze <4 x i32> [[Y:%.*]] 3165; CHECK-NEXT: [[M:%.*]] = mul <4 x i32> [[X:%.*]], [[Y_FR]] 3166; CHECK-NEXT: ret <4 x i32> [[M]] 3167; 3168 %c = icmp eq <4 x i32> %x, zeroinitializer 3169 %m = mul <4 x i32> %x, %y 3170 %r = select <4 x i1> %c, <4 x i32> zeroinitializer, <4 x i32> %m 3171 ret <4 x i32> %r 3172} 3173 3174; Check that a select is folded into multiplication if condition's operand 3175; is a vector consisting of zeros and poisons. 3176; select (<k x elt> x == {0, poison, ...}), <k x elt> 0, <k x elt> x * y --> freeze(y) * x 3177define <2 x i32> @mul_select_eq_poison_vector(<2 x i32> %x, <2 x i32> %y) { 3178; CHECK-LABEL: @mul_select_eq_poison_vector( 3179; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 0, i32 poison> 3180; CHECK-NEXT: [[M:%.*]] = mul <2 x i32> [[X]], [[Y:%.*]] 3181; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[C]], <2 x i32> <i32 0, i32 42>, <2 x i32> [[M]] 3182; CHECK-NEXT: ret <2 x i32> [[R]] 3183; 3184 %c = icmp eq <2 x i32> %x, <i32 0, i32 poison> 3185 %m = mul <2 x i32> %x, %y 3186 %r = select <2 x i1> %c, <2 x i32> <i32 0, i32 42>, <2 x i32> %m 3187 ret <2 x i32> %r 3188} 3189 3190; Check that a select is folded into multiplication if other select's operand 3191; is a vector consisting of zeros and poisons. 3192; select (<k x elt> x == 0), <k x elt> {0, poison, ...}, <k x elt> x * y --> freeze(y) * x 3193define <2 x i32> @mul_select_eq_zero_sel_poison_vector(<2 x i32> %x, <2 x i32> %y) { 3194; CHECK-LABEL: @mul_select_eq_zero_sel_poison_vector( 3195; CHECK-NEXT: [[Y_FR:%.*]] = freeze <2 x i32> [[Y:%.*]] 3196; CHECK-NEXT: [[M:%.*]] = mul <2 x i32> [[X:%.*]], [[Y_FR]] 3197; CHECK-NEXT: ret <2 x i32> [[M]] 3198; 3199 %c = icmp eq <2 x i32> %x, zeroinitializer 3200 %m = mul <2 x i32> %x, %y 3201 %r = select <2 x i1> %c, <2 x i32> <i32 0, i32 poison>, <2 x i32> %m 3202 ret <2 x i32> %r 3203} 3204 3205; Negative test: select should not be folded into mul because 3206; condition's operand and select's operand do not merge into zero vector. 3207define <2 x i32> @mul_select_eq_poison_vector_not_merging_to_zero(<2 x i32> %x, <2 x i32> %y) { 3208; CHECK-LABEL: @mul_select_eq_poison_vector_not_merging_to_zero( 3209; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 0, i32 poison> 3210; CHECK-NEXT: [[M:%.*]] = mul <2 x i32> [[X]], [[Y:%.*]] 3211; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[C]], <2 x i32> <i32 1, i32 0>, <2 x i32> [[M]] 3212; CHECK-NEXT: ret <2 x i32> [[R]] 3213; 3214 %c = icmp eq <2 x i32> %x, <i32 0, i32 poison> 3215 %m = mul <2 x i32> %x, %y 3216 %r = select <2 x i1> %c, <2 x i32> <i32 1, i32 0>, <2 x i32> %m 3217 ret <2 x i32> %r 3218} 3219 3220define i8 @ne0_is_all_ones(i8 %x) { 3221; CHECK-LABEL: @ne0_is_all_ones( 3222; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[X:%.*]], 0 3223; CHECK-NEXT: [[R:%.*]] = sext i1 [[TMP1]] to i8 3224; CHECK-NEXT: ret i8 [[R]] 3225; 3226 %negx = sub i8 0, %x 3227 %ugt1 = icmp ugt i8 %x, 1 3228 %r = select i1 %ugt1, i8 -1, i8 %negx 3229 ret i8 %r 3230} 3231 3232define i8 @ne0_is_all_ones_use1(i8 %x) { 3233; CHECK-LABEL: @ne0_is_all_ones_use1( 3234; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X:%.*]] 3235; CHECK-NEXT: call void @use_i8(i8 [[NEGX]]) 3236; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[X]], 0 3237; CHECK-NEXT: [[R:%.*]] = sext i1 [[TMP1]] to i8 3238; CHECK-NEXT: ret i8 [[R]] 3239; 3240 %negx = sub i8 0, %x 3241 call void @use_i8(i8 %negx) 3242 %ugt1 = icmp ugt i8 %x, 1 3243 %r = select i1 %ugt1, i8 -1, i8 %negx 3244 ret i8 %r 3245} 3246 3247; negative test 3248 3249define i8 @ne0_is_all_ones_use2(i8 %x) { 3250; CHECK-LABEL: @ne0_is_all_ones_use2( 3251; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X:%.*]] 3252; CHECK-NEXT: [[UGT1:%.*]] = icmp ugt i8 [[X]], 1 3253; CHECK-NEXT: call void @use(i1 [[UGT1]]) 3254; CHECK-NEXT: [[R:%.*]] = select i1 [[UGT1]], i8 -1, i8 [[NEGX]] 3255; CHECK-NEXT: ret i8 [[R]] 3256; 3257 %negx = sub i8 0, %x 3258 %ugt1 = icmp ugt i8 %x, 1 3259 call void @use(i1 %ugt1) 3260 %r = select i1 %ugt1, i8 -1, i8 %negx 3261 ret i8 %r 3262} 3263 3264; negative test 3265 3266define i8 @ne0_is_all_ones_wrong_pred(i8 %x) { 3267; CHECK-LABEL: @ne0_is_all_ones_wrong_pred( 3268; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X:%.*]] 3269; CHECK-NEXT: [[UGT1:%.*]] = icmp sgt i8 [[X]], 2 3270; CHECK-NEXT: [[R:%.*]] = select i1 [[UGT1]], i8 -1, i8 [[NEGX]] 3271; CHECK-NEXT: ret i8 [[R]] 3272; 3273 %negx = sub i8 0, %x 3274 %ugt1 = icmp sgt i8 %x, 2 3275 %r = select i1 %ugt1, i8 -1, i8 %negx 3276 ret i8 %r 3277} 3278 3279; negative test 3280 3281define i8 @ne0_is_all_ones_wrong_cmp(i8 %x) { 3282; CHECK-LABEL: @ne0_is_all_ones_wrong_cmp( 3283; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X:%.*]] 3284; CHECK-NEXT: [[UGT1:%.*]] = icmp ugt i8 [[X]], 2 3285; CHECK-NEXT: [[R:%.*]] = select i1 [[UGT1]], i8 -1, i8 [[NEGX]] 3286; CHECK-NEXT: ret i8 [[R]] 3287; 3288 %negx = sub i8 0, %x 3289 %ugt1 = icmp ugt i8 %x, 2 3290 %r = select i1 %ugt1, i8 -1, i8 %negx 3291 ret i8 %r 3292} 3293 3294; negative test 3295 3296define i8 @ne0_is_all_ones_wrong_sel(i8 %x) { 3297; CHECK-LABEL: @ne0_is_all_ones_wrong_sel( 3298; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X:%.*]] 3299; CHECK-NEXT: [[UGT1:%.*]] = icmp ugt i8 [[X]], 2 3300; CHECK-NEXT: [[R:%.*]] = select i1 [[UGT1]], i8 1, i8 [[NEGX]] 3301; CHECK-NEXT: ret i8 [[R]] 3302; 3303 %negx = sub i8 0, %x 3304 %ugt1 = icmp ugt i8 %x, 2 3305 %r = select i1 %ugt1, i8 1, i8 %negx 3306 ret i8 %r 3307} 3308 3309define <2 x i8> @ne0_is_all_ones_swap_vec(<2 x i8> %x) { 3310; CHECK-LABEL: @ne0_is_all_ones_swap_vec( 3311; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i8> [[X:%.*]], zeroinitializer 3312; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8> 3313; CHECK-NEXT: ret <2 x i8> [[R]] 3314; 3315 %negx = sub <2 x i8> zeroinitializer, %x 3316 %ult2 = icmp ult <2 x i8> %x, <i8 2, i8 2> 3317 %r = select <2 x i1> %ult2, <2 x i8> %negx, <2 x i8> <i8 -1, i8 -1> 3318 ret <2 x i8> %r 3319} 3320 3321define <2 x i8> @ne0_is_all_ones_swap_vec_poison(<2 x i8> %x) { 3322; CHECK-LABEL: @ne0_is_all_ones_swap_vec_poison( 3323; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i8> [[X:%.*]], zeroinitializer 3324; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8> 3325; CHECK-NEXT: ret <2 x i8> [[R]] 3326; 3327 %negx = sub <2 x i8> <i8 0, i8 poison>, %x 3328 %ult2 = icmp ult <2 x i8> %x, <i8 2, i8 poison> 3329 %r = select <2 x i1> %ult2, <2 x i8> %negx, <2 x i8> <i8 -1, i8 poison> 3330 ret <2 x i8> %r 3331} 3332 3333define i64 @udiv_of_select_constexpr(i1 %c, i64 %x) { 3334; CHECK-LABEL: @udiv_of_select_constexpr( 3335; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i64 [[X:%.*]], i64 ptrtoint (ptr @glbl to i64) 3336; CHECK-NEXT: [[OP:%.*]] = udiv i64 [[SEL]], 3 3337; CHECK-NEXT: ret i64 [[OP]] 3338; 3339 %sel = select i1 %c, i64 %x, i64 ptrtoint (ptr @glbl to i64) 3340 %op = udiv i64 %sel, 3 3341 ret i64 %op 3342} 3343 3344define i64 @udiv_of_select_constexpr_commuted(i1 %c, i64 %x) { 3345; CHECK-LABEL: @udiv_of_select_constexpr_commuted( 3346; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i64 ptrtoint (ptr @glbl to i64), i64 [[X:%.*]] 3347; CHECK-NEXT: [[OP:%.*]] = udiv i64 [[SEL]], 3 3348; CHECK-NEXT: ret i64 [[OP]] 3349; 3350 %sel = select i1 %c, i64 ptrtoint (ptr @glbl to i64), i64 %x 3351 %op = udiv i64 %sel, 3 3352 ret i64 %op 3353} 3354 3355declare void @use(i1) 3356declare void @use_i8(i8) 3357declare void @use_i32(i32) 3358declare i32 @llvm.cttz.i32(i32, i1 immarg) 3359 3360define i32 @select_cond_zext_cond(i1 %cond, i32 %b) { 3361; CHECK-LABEL: @select_cond_zext_cond( 3362; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 1, i32 [[B:%.*]] 3363; CHECK-NEXT: ret i32 [[SEL]] 3364; 3365 %zext = zext i1 %cond to i32 3366 %sel = select i1 %cond, i32 %zext, i32 %b 3367 ret i32 %sel 3368} 3369 3370define <2 x i32> @select_cond_zext_cond_vec(<2 x i1> %cond, <2 x i32> %b) { 3371; CHECK-LABEL: @select_cond_zext_cond_vec( 3372; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[COND:%.*]], <2 x i32> splat (i32 1), <2 x i32> [[B:%.*]] 3373; CHECK-NEXT: ret <2 x i32> [[SEL]] 3374; 3375 %zext = zext <2 x i1> %cond to <2 x i32> 3376 %sel = select <2 x i1> %cond, <2 x i32> %zext, <2 x i32> %b 3377 ret <2 x i32> %sel 3378} 3379 3380define i32 @select_cond_sext_cond(i1 %cond, i32 %b) { 3381; CHECK-LABEL: @select_cond_sext_cond( 3382; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 -1, i32 [[B:%.*]] 3383; CHECK-NEXT: ret i32 [[SEL]] 3384; 3385 %sext = sext i1 %cond to i32 3386 %sel = select i1 %cond, i32 %sext, i32 %b 3387 ret i32 %sel 3388} 3389 3390define <2 x i32> @select_cond_sext_cond_vec(<2 x i1> %cond, <2 x i32> %b) { 3391; CHECK-LABEL: @select_cond_sext_cond_vec( 3392; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[COND:%.*]], <2 x i32> splat (i32 -1), <2 x i32> [[B:%.*]] 3393; CHECK-NEXT: ret <2 x i32> [[SEL]] 3394; 3395 %sext = sext <2 x i1> %cond to <2 x i32> 3396 %sel = select <2 x i1> %cond, <2 x i32> %sext, <2 x i32> %b 3397 ret <2 x i32> %sel 3398} 3399 3400define i32 @select_cond_val_zext_cond(i1 %cond, i32 %b) { 3401; CHECK-LABEL: @select_cond_val_zext_cond( 3402; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[B:%.*]], i32 0 3403; CHECK-NEXT: ret i32 [[SEL]] 3404; 3405 %zext = zext i1 %cond to i32 3406 %sel = select i1 %cond, i32 %b, i32 %zext 3407 ret i32 %sel 3408} 3409 3410define <2 x i32> @select_cond_val_zext_cond_vec(<2 x i1> %cond, <2 x i32> %b) { 3411; CHECK-LABEL: @select_cond_val_zext_cond_vec( 3412; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[COND:%.*]], <2 x i32> [[B:%.*]], <2 x i32> zeroinitializer 3413; CHECK-NEXT: ret <2 x i32> [[SEL]] 3414; 3415 %zext = zext <2 x i1> %cond to <2 x i32> 3416 %sel = select <2 x i1> %cond, <2 x i32> %b, <2 x i32> %zext 3417 ret <2 x i32> %sel 3418} 3419 3420define i32 @select_cond_val_sext_cond(i1 %cond, i32 %b) { 3421; CHECK-LABEL: @select_cond_val_sext_cond( 3422; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[B:%.*]], i32 0 3423; CHECK-NEXT: ret i32 [[SEL]] 3424; 3425 %sext = sext i1 %cond to i32 3426 %sel = select i1 %cond, i32 %b, i32 %sext 3427 ret i32 %sel 3428} 3429 3430define i32 @select_cond_zext_not_cond_val(i1 %cond, i32 %b) { 3431; CHECK-LABEL: @select_cond_zext_not_cond_val( 3432; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 0, i32 [[B:%.*]] 3433; CHECK-NEXT: ret i32 [[SEL]] 3434; 3435 %not_cond = xor i1 %cond, true 3436 %zext = zext i1 %not_cond to i32 3437 %sel = select i1 %cond, i32 %zext, i32 %b 3438 ret i32 %sel 3439} 3440 3441define i32 @select_cond_sext_not_cond_val(i1 %cond, i32 %b) { 3442; CHECK-LABEL: @select_cond_sext_not_cond_val( 3443; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 0, i32 [[B:%.*]] 3444; CHECK-NEXT: ret i32 [[SEL]] 3445; 3446 %not_cond = xor i1 %cond, true 3447 %sext = sext i1 %not_cond to i32 3448 %sel = select i1 %cond, i32 %sext, i32 %b 3449 ret i32 %sel 3450} 3451 3452 3453define i32 @select_cond_val_zext_not_cond(i1 %cond, i32 %b) { 3454; CHECK-LABEL: @select_cond_val_zext_not_cond( 3455; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[B:%.*]], i32 1 3456; CHECK-NEXT: ret i32 [[SEL]] 3457; 3458 %not_cond = xor i1 %cond, true 3459 %zext = zext i1 %not_cond to i32 3460 %sel = select i1 %cond, i32 %b, i32 %zext 3461 ret i32 %sel 3462} 3463 3464define i32 @select_cond_val_sext_not_cond(i1 %cond, i32 %b) { 3465; CHECK-LABEL: @select_cond_val_sext_not_cond( 3466; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[B:%.*]], i32 -1 3467; CHECK-NEXT: ret i32 [[SEL]] 3468; 3469 %not_cond = xor i1 %cond, true 3470 %sext = sext i1 %not_cond to i32 3471 %sel = select i1 %cond, i32 %b, i32 %sext 3472 ret i32 %sel 3473} 3474 3475define i32 @select_cond_not_cond_cond1(i1 %cond) { 3476; CHECK-LABEL: @select_cond_not_cond_cond1( 3477; CHECK-NEXT: ret i32 0 3478; 3479 %z = zext i1 %cond to i32 3480 %not_cond = xor i1 %cond, true 3481 %s = sext i1 %not_cond to i32 3482 %v = select i1 %cond, i32 %s, i32 %z 3483 ret i32 %v 3484} 3485 3486define i32 @select_cond_not_cond_cond2(i1 %cond) { 3487; CHECK-LABEL: @select_cond_not_cond_cond2( 3488; CHECK-NEXT: ret i32 0 3489; 3490 %z = sext i1 %cond to i32 3491 %not_cond = xor i1 %cond, true 3492 %s = zext i1 %not_cond to i32 3493 %v = select i1 %cond, i32 %s, i32 %z 3494 ret i32 %v 3495} 3496 3497; This previously crashed due to Constant::getUniqueInteger not handling 3498; scalable vector splat ConstantExprs. 3499define <vscale x 2 x i32> @and_constant_select_svec(<vscale x 2 x i32> %x, <vscale x 2 x i1> %cond) { 3500; CHECK-LABEL: @and_constant_select_svec( 3501; CHECK-NEXT: [[A:%.*]] = and <vscale x 2 x i32> [[X:%.*]], splat (i32 1) 3502; CHECK-NEXT: [[B:%.*]] = select <vscale x 2 x i1> [[COND:%.*]], <vscale x 2 x i32> [[A]], <vscale x 2 x i32> [[X]] 3503; CHECK-NEXT: ret <vscale x 2 x i32> [[B]] 3504; 3505 %a = and <vscale x 2 x i32> %x, splat (i32 1) 3506 %b = select <vscale x 2 x i1> %cond, <vscale x 2 x i32> %a, <vscale x 2 x i32> %x 3507 ret <vscale x 2 x i32> %b 3508} 3509 3510define <vscale x 2 x i32> @scalable_sign_bits(<vscale x 2 x i8> %x) { 3511; CHECK-LABEL: @scalable_sign_bits( 3512; CHECK-NEXT: [[A:%.*]] = sext <vscale x 2 x i8> [[X:%.*]] to <vscale x 2 x i32> 3513; CHECK-NEXT: [[B:%.*]] = shl nsw <vscale x 2 x i32> [[A]], splat (i32 16) 3514; CHECK-NEXT: ret <vscale x 2 x i32> [[B]] 3515; 3516 %a = sext <vscale x 2 x i8> %x to <vscale x 2 x i32> 3517 %b = shl <vscale x 2 x i32> %a, splat (i32 16) 3518 ret <vscale x 2 x i32> %b 3519} 3520 3521define <vscale x 2 x i1> @scalable_non_zero(<vscale x 2 x i32> %x) { 3522; CHECK-LABEL: @scalable_non_zero( 3523; CHECK-NEXT: [[A:%.*]] = or <vscale x 2 x i32> [[X:%.*]], splat (i32 1) 3524; CHECK-NEXT: [[CMP:%.*]] = icmp ult <vscale x 2 x i32> [[A]], splat (i32 57) 3525; CHECK-NEXT: ret <vscale x 2 x i1> [[CMP]] 3526; 3527 %a = or <vscale x 2 x i32> %x, splat (i32 1) 3528 %b = add <vscale x 2 x i32> %a, splat (i32 -1) 3529 %cmp = icmp ult <vscale x 2 x i32> %b, splat (i32 56) 3530 ret <vscale x 2 x i1> %cmp 3531} 3532 3533define i32 @clamp_umin(i32 %x) { 3534; CHECK-LABEL: @clamp_umin( 3535; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 1) 3536; CHECK-NEXT: ret i32 [[SEL]] 3537; 3538 %cmp = icmp eq i32 %x, 0 3539 %sel = select i1 %cmp, i32 1, i32 %x 3540 ret i32 %sel 3541} 3542 3543define i32 @clamp_umin_use(i32 %x) { 3544; CHECK-LABEL: @clamp_umin_use( 3545; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0 3546; CHECK-NEXT: call void @use1(i1 [[CMP]]) 3547; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 1) 3548; CHECK-NEXT: ret i32 [[SEL]] 3549; 3550 %cmp = icmp eq i32 %x, 0 3551 call void @use1(i1 %cmp) 3552 %sel = select i1 %cmp, i32 1, i32 %x 3553 ret i32 %sel 3554} 3555 3556; negative test - wrong cmp constant 3557 3558define i32 @not_clamp_umin1(i32 %x) { 3559; CHECK-LABEL: @not_clamp_umin1( 3560; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 2 3561; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 1, i32 [[X]] 3562; CHECK-NEXT: ret i32 [[SEL]] 3563; 3564 %cmp = icmp eq i32 %x, 2 3565 %sel = select i1 %cmp, i32 1, i32 %x 3566 ret i32 %sel 3567} 3568 3569; negative test - wrong select constant 3570 3571define i32 @not_clamp_umin2(i32 %x) { 3572; CHECK-LABEL: @not_clamp_umin2( 3573; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0 3574; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 -1, i32 [[X]] 3575; CHECK-NEXT: ret i32 [[SEL]] 3576; 3577 %cmp = icmp eq i32 %x, 0 3578 %sel = select i1 %cmp, i32 -1, i32 %x 3579 ret i32 %sel 3580} 3581 3582define <2 x i8> @clamp_umaxval(<2 x i8> %x) { 3583; CHECK-LABEL: @clamp_umaxval( 3584; CHECK-NEXT: [[SEL:%.*]] = call <2 x i8> @llvm.umin.v2i8(<2 x i8> [[X:%.*]], <2 x i8> splat (i8 -2)) 3585; CHECK-NEXT: ret <2 x i8> [[SEL]] 3586; 3587 %cmp = icmp eq <2 x i8> %x, <i8 255, i8 255> 3588 %sel = select <2 x i1> %cmp, <2 x i8> <i8 254, i8 254>, <2 x i8> %x 3589 ret <2 x i8> %sel 3590} 3591 3592; negative test - wrong cmp constant 3593 3594define i8 @not_clamp_umax1(i8 %x) { 3595; CHECK-LABEL: @not_clamp_umax1( 3596; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -3 3597; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 -2, i8 [[X]] 3598; CHECK-NEXT: ret i8 [[SEL]] 3599; 3600 %cmp = icmp eq i8 %x, 253 3601 %sel = select i1 %cmp, i8 254, i8 %x 3602 ret i8 %sel 3603} 3604 3605; negative test - wrong select constant 3606 3607define i8 @not_clamp_umax2(i8 %x) { 3608; CHECK-LABEL: @not_clamp_umax2( 3609; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -1 3610; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 1, i8 [[X]] 3611; CHECK-NEXT: ret i8 [[SEL]] 3612; 3613 %cmp = icmp eq i8 %x, 255 3614 %sel = select i1 %cmp, i8 1, i8 %x 3615 ret i8 %sel 3616} 3617 3618define i8 @clamp_smin(i8 %x) { 3619; CHECK-LABEL: @clamp_smin( 3620; CHECK-NEXT: [[SEL:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 -127) 3621; CHECK-NEXT: ret i8 [[SEL]] 3622; 3623 %cmp = icmp eq i8 %x, -128 3624 %sel = select i1 %cmp, i8 -127, i8 %x 3625 ret i8 %sel 3626} 3627 3628define i8 @clamp_smin_use(i8 %x) { 3629; CHECK-LABEL: @clamp_smin_use( 3630; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -128 3631; CHECK-NEXT: call void @use1(i1 [[CMP]]) 3632; CHECK-NEXT: [[SEL:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 -127) 3633; CHECK-NEXT: ret i8 [[SEL]] 3634; 3635 %cmp = icmp eq i8 %x, -128 3636 call void @use1(i1 %cmp) 3637 %sel = select i1 %cmp, i8 -127, i8 %x 3638 ret i8 %sel 3639} 3640 3641; negative test - wrong cmp constant 3642 3643define i8 @not_clamp_smin1(i8 %x) { 3644; CHECK-LABEL: @not_clamp_smin1( 3645; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 127 3646; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 -127, i8 [[X]] 3647; CHECK-NEXT: ret i8 [[SEL]] 3648; 3649 %cmp = icmp eq i8 %x, 127 3650 %sel = select i1 %cmp, i8 -127, i8 %x 3651 ret i8 %sel 3652} 3653 3654; negative test - wrong select constant 3655 3656define i8 @not_clamp_smin2(i8 %x) { 3657; CHECK-LABEL: @not_clamp_smin2( 3658; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -128 3659; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 -1, i8 [[X]] 3660; CHECK-NEXT: ret i8 [[SEL]] 3661; 3662 %cmp = icmp eq i8 %x, -128 3663 %sel = select i1 %cmp, i8 -1, i8 %x 3664 ret i8 %sel 3665} 3666 3667define <2 x i8> @clamp_smaxval(<2 x i8> %x) { 3668; CHECK-LABEL: @clamp_smaxval( 3669; CHECK-NEXT: [[SEL:%.*]] = call <2 x i8> @llvm.smin.v2i8(<2 x i8> [[X:%.*]], <2 x i8> splat (i8 126)) 3670; CHECK-NEXT: ret <2 x i8> [[SEL]] 3671; 3672 %cmp = icmp eq <2 x i8> %x, <i8 127, i8 127> 3673 %sel = select <2 x i1> %cmp, <2 x i8> <i8 126, i8 126>, <2 x i8> %x 3674 ret <2 x i8> %sel 3675} 3676 3677; negative test - wrong cmp constant 3678 3679define i8 @not_clamp_smax1(i8 %x) { 3680; CHECK-LABEL: @not_clamp_smax1( 3681; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -128 3682; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 126, i8 [[X]] 3683; CHECK-NEXT: ret i8 [[SEL]] 3684; 3685 %cmp = icmp eq i8 %x, -128 3686 %sel = select i1 %cmp, i8 126, i8 %x 3687 ret i8 %sel 3688} 3689 3690; negative test - wrong select constant 3691 3692define i8 @not_clamp_smax2(i8 %x) { 3693; CHECK-LABEL: @not_clamp_smax2( 3694; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 127 3695; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 125, i8 [[X]] 3696; CHECK-NEXT: ret i8 [[SEL]] 3697; 3698 %cmp = icmp eq i8 %x, 127 3699 %sel = select i1 %cmp, i8 125, i8 %x 3700 ret i8 %sel 3701} 3702 3703; Used to infinite loop. 3704define i32 @pr61361(i32 %arg) { 3705; CHECK-LABEL: @pr61361( 3706; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[ARG:%.*]], 0 3707; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i32 16777215, i32 0 3708; CHECK-NEXT: ret i32 [[SEL2]] 3709; 3710 %cmp1 = icmp eq i32 %arg, 1 3711 %sel1 = select i1 %cmp1, i32 0, i32 33554431 3712 %cmp2 = icmp eq i32 %arg, 0 3713 %sel2 = select i1 %cmp2, i32 %sel1, i32 0 3714 %ashr = ashr i32 %sel2, 1 3715 ret i32 %ashr 3716} 3717 3718define i32 @pr62088() { 3719; CHECK-LABEL: @pr62088( 3720; CHECK-NEXT: entry: 3721; CHECK-NEXT: br label [[LOOP:%.*]] 3722; CHECK: loop: 3723; CHECK-NEXT: [[NOT2:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ -2, [[LOOP]] ] 3724; CHECK-NEXT: [[H_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ 1, [[LOOP]] ] 3725; CHECK-NEXT: [[XOR:%.*]] = or disjoint i32 [[H_0]], [[NOT2]] 3726; CHECK-NEXT: [[SUB5:%.*]] = sub i32 -1824888657, [[XOR]] 3727; CHECK-NEXT: [[XOR6:%.*]] = xor i32 [[SUB5]], -1260914025 3728; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[XOR6]], 824855120 3729; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]] 3730; CHECK: exit: 3731; CHECK-NEXT: ret i32 [[H_0]] 3732; 3733entry: 3734 br label %loop 3735 3736loop: 3737 %not2 = phi i32 [ 0, %entry ], [ -2, %loop ] 3738 %i.0 = phi i32 [ 0, %entry ], [ %shr, %loop ] 3739 %h.0 = phi i32 [ 0, %entry ], [ 1, %loop ] 3740 %i.0.fr = freeze i32 %i.0 3741 %sext = shl i32 %i.0.fr, 16 3742 %conv = ashr exact i32 %sext, 16 3743 %not = xor i32 %conv, -1 3744 %and = and i32 %h.0, 1 3745 %rem.urem = sub nsw i32 %and, %conv 3746 %rem.cmp = icmp ult i32 %and, %conv 3747 %rem = select i1 %rem.cmp, i32 %not, i32 %rem.urem 3748 %xor = xor i32 %rem, %not2 3749 %sub = sub nsw i32 0, %xor 3750 %sub5 = sub i32 -1824888657, %xor 3751 %xor6 = xor i32 %sub5, -1260914025 3752 %cmp = icmp slt i32 %xor6, 824855120 3753 %shr = ashr i32 %xor6, 40 3754 br i1 %cmp, label %loop, label %exit 3755 3756exit: 3757 ret i32 %rem 3758} 3759 3760; Select icmp and/or/xor 3761; https://alive2.llvm.org/ce/z/QXQDwF 3762; X&Y==C?X|Y:X^Y, X&Y==C?X^Y:X|Y 3763; TODO: X&Y==0 could imply no_common_bit to TrueValue 3764define i32 @src_and_eq_0_or_xor(i32 %x, i32 %y) { 3765; CHECK-LABEL: @src_and_eq_0_or_xor( 3766; CHECK-NEXT: entry: 3767; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 3768; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 3769; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y]], [[X]] 3770; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]] 3771; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[XOR]] 3772; CHECK-NEXT: ret i32 [[COND]] 3773; 3774entry: 3775 %and = and i32 %y, %x 3776 %cmp = icmp eq i32 %and, 0 3777 %or = or i32 %y, %x 3778 %xor = xor i32 %y, %x 3779 %cond = select i1 %cmp, i32 %or, i32 %xor 3780 ret i32 %cond 3781} 3782 3783; TODO: X&Y==0 could imply no_common_bit to TrueValue 3784define i32 @src_and_eq_0_xor_or(i32 %x, i32 %y) { 3785; CHECK-LABEL: @src_and_eq_0_xor_or( 3786; CHECK-NEXT: entry: 3787; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 3788; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 3789; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]] 3790; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y]], [[X]] 3791; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[OR]] 3792; CHECK-NEXT: ret i32 [[COND]] 3793; 3794entry: 3795 %and = and i32 %y, %x 3796 %cmp = icmp eq i32 %and, 0 3797 %xor = xor i32 %y, %x 3798 %or = or i32 %y, %x 3799 %cond = select i1 %cmp, i32 %xor, i32 %or 3800 ret i32 %cond 3801} 3802 3803; TODO: X&Y==-1 could imply all_common_bit to TrueValue 3804define i32 @src_and_eq_neg1_or_xor(i32 %x, i32 %y) { 3805; CHECK-LABEL: @src_and_eq_neg1_or_xor( 3806; CHECK-NEXT: entry: 3807; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 3808; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], -1 3809; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]] 3810; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 -1, i32 [[XOR]] 3811; CHECK-NEXT: ret i32 [[COND]] 3812; 3813entry: 3814 %and = and i32 %y, %x 3815 %cmp = icmp eq i32 %and, -1 3816 %or = or i32 %y, %x 3817 %xor = xor i32 %y, %x 3818 %cond = select i1 %cmp, i32 %or, i32 %xor 3819 ret i32 %cond 3820} 3821 3822; TODO: X&Y==-1 could imply all_common_bit to TrueValue 3823define i32 @src_and_eq_neg1_xor_or(i32 %x, i32 %y) { 3824; CHECK-LABEL: @src_and_eq_neg1_xor_or( 3825; CHECK-NEXT: entry: 3826; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 3827; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], -1 3828; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y]], [[X]] 3829; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 0, i32 [[OR]] 3830; CHECK-NEXT: ret i32 [[COND]] 3831; 3832entry: 3833 %and = and i32 %y, %x 3834 %cmp = icmp eq i32 %and, -1 3835 %xor = xor i32 %y, %x 3836 %or = or i32 %y, %x 3837 %cond = select i1 %cmp, i32 %xor, i32 %or 3838 ret i32 %cond 3839} 3840 3841define i32 @src_and_eq_C_or_xororC(i32 %x, i32 %y, i32 %c) { 3842; CHECK-LABEL: @src_and_eq_C_or_xororC( 3843; CHECK-NEXT: entry: 3844; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 3845; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], [[C:%.*]] 3846; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y]], [[X]] 3847; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]] 3848; CHECK-NEXT: [[OR1:%.*]] = or i32 [[XOR]], [[C]] 3849; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[OR1]] 3850; CHECK-NEXT: ret i32 [[COND]] 3851; 3852entry: 3853 %and = and i32 %y, %x 3854 %cmp = icmp eq i32 %and, %c 3855 %or = or i32 %y, %x 3856 %xor = xor i32 %y, %x 3857 %or1 = or i32 %xor, %c 3858 %cond = select i1 %cmp, i32 %or, i32 %or1 3859 ret i32 %cond 3860} 3861 3862define i32 @src_and_eq_C_or_xorxorC(i32 %x, i32 %y, i32 %c) { 3863; CHECK-LABEL: @src_and_eq_C_or_xorxorC( 3864; CHECK-NEXT: entry: 3865; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 3866; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], [[C:%.*]] 3867; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y]], [[X]] 3868; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]] 3869; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[XOR]], [[C]] 3870; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[XOR1]] 3871; CHECK-NEXT: ret i32 [[COND]] 3872; 3873entry: 3874 %and = and i32 %y, %x 3875 %cmp = icmp eq i32 %and, %c 3876 %or = or i32 %y, %x 3877 %xor = xor i32 %y, %x 3878 %xor1 = xor i32 %xor, %c 3879 %cond = select i1 %cmp, i32 %or, i32 %xor1 3880 ret i32 %cond 3881} 3882 3883define i32 @src_and_eq_C_xor_OrAndNotC(i32 %x, i32 %y, i32 %c) { 3884; CHECK-LABEL: @src_and_eq_C_xor_OrAndNotC( 3885; CHECK-NEXT: entry: 3886; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 3887; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], [[C:%.*]] 3888; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]] 3889; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y]], [[X]] 3890; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[C]], -1 3891; CHECK-NEXT: [[AND1:%.*]] = and i32 [[OR]], [[NOT]] 3892; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[AND1]] 3893; CHECK-NEXT: ret i32 [[COND]] 3894; 3895entry: 3896 %and = and i32 %y, %x 3897 %cmp = icmp eq i32 %and, %c 3898 %xor = xor i32 %y, %x 3899 %or = or i32 %y, %x 3900 %not = xor i32 %c, -1 3901 %and1 = and i32 %or, %not 3902 %cond = select i1 %cmp, i32 %xor, i32 %and1 3903 ret i32 %cond 3904} 3905 3906define <2 x i32> @src_and_eq_C_xor_OrAndNotC_vec_poison(<2 x i32> %0, <2 x i32> %1, <2 x i32> %2) { 3907; CHECK-LABEL: @src_and_eq_C_xor_OrAndNotC_vec_poison( 3908; CHECK-NEXT: entry: 3909; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[TMP1:%.*]], [[TMP0:%.*]] 3910; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], [[TMP2:%.*]] 3911; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[TMP1]], [[TMP0]] 3912; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[TMP1]], [[TMP0]] 3913; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i32> [[TMP2]], <i32 -1, i32 poison> 3914; CHECK-NEXT: [[AND1:%.*]] = and <2 x i32> [[OR]], [[NOT]] 3915; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[XOR]], <2 x i32> [[AND1]] 3916; CHECK-NEXT: ret <2 x i32> [[COND]] 3917; 3918entry: 3919 %and = and <2 x i32> %1, %0 3920 %cmp = icmp eq <2 x i32> %and, %2 3921 %xor = xor <2 x i32> %1, %0 3922 %or = or <2 x i32> %1, %0 3923 %not = xor <2 x i32> %2, <i32 -1, i32 poison> 3924 %and1 = and <2 x i32> %or, %not 3925 %cond = select <2 x i1> %cmp, <2 x i32> %xor, <2 x i32> %and1 3926 ret <2 x i32> %cond 3927} 3928 3929define i32 @src_and_eq_C_xor_orxorC(i32 %x, i32 %y, i32 %c) { 3930; CHECK-LABEL: @src_and_eq_C_xor_orxorC( 3931; CHECK-NEXT: entry: 3932; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 3933; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], [[C:%.*]] 3934; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]] 3935; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y]], [[X]] 3936; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[OR]], [[C]] 3937; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[XOR1]] 3938; CHECK-NEXT: ret i32 [[COND]] 3939; 3940entry: 3941 %and = and i32 %y, %x 3942 %cmp = icmp eq i32 %and, %c 3943 %xor = xor i32 %y, %x 3944 %or = or i32 %y, %x 3945 %xor1 = xor i32 %or, %c 3946 %cond = select i1 %cmp, i32 %xor, i32 %xor1 3947 ret i32 %cond 3948} 3949 3950; https://alive2.llvm.org/ce/z/9RPwfN 3951; X|Y==C?X&Y:X^Y, X|Y==C?X^Y:X&Y 3952; TODO: X|Y==0 could imply no_common_bit to TrueValue 3953define i32 @src_or_eq_0_and_xor(i32 %x, i32 %y) { 3954; CHECK-LABEL: @src_or_eq_0_and_xor( 3955; CHECK-NEXT: entry: 3956; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]] 3957; CHECK-NEXT: ret i32 [[XOR]] 3958; 3959entry: 3960 %or = or i32 %y, %x 3961 %cmp = icmp eq i32 %or, 0 3962 %and = and i32 %y, %x 3963 %xor = xor i32 %y, %x 3964 %cond = select i1 %cmp, i32 %and, i32 %xor 3965 ret i32 %cond 3966} 3967 3968; TODO: X|Y==0 could imply no_common_bit to TrueValue 3969define i32 @src_or_eq_0_xor_and(i32 %x, i32 %y) { 3970; CHECK-LABEL: @src_or_eq_0_xor_and( 3971; CHECK-NEXT: entry: 3972; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 3973; CHECK-NEXT: ret i32 [[AND]] 3974; 3975entry: 3976 %or = or i32 %y, %x 3977 %cmp = icmp eq i32 %or, 0 3978 %xor = xor i32 %y, %x 3979 %and = and i32 %y, %x 3980 %cond = select i1 %cmp, i32 %xor, i32 %and 3981 ret i32 %cond 3982} 3983 3984define i32 @src_or_eq_neg1_and_xor(i32 %x, i32 %y) { 3985; CHECK-LABEL: @src_or_eq_neg1_and_xor( 3986; CHECK-NEXT: entry: 3987; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] 3988; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[OR]], -1 3989; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], [[X]] 3990; CHECK-NEXT: [[TMP0:%.*]] = xor i32 [[X]], [[Y]] 3991; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[TMP0]], -1 3992; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[NOT]] 3993; CHECK-NEXT: ret i32 [[COND]] 3994; 3995entry: 3996 %or = or i32 %y, %x 3997 %cmp = icmp eq i32 %or, -1 3998 %and = and i32 %y, %x 3999 %0 = xor i32 %x, %y 4000 %not = xor i32 %0, -1 4001 %cond = select i1 %cmp, i32 %and, i32 %not 4002 ret i32 %cond 4003} 4004 4005define i32 @src_or_eq_neg1_xor_and(i32 %x, i32 %y) { 4006; CHECK-LABEL: @src_or_eq_neg1_xor_and( 4007; CHECK-NEXT: entry: 4008; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] 4009; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[OR]], -1 4010; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]] 4011; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], [[X]] 4012; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[AND]], -1 4013; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[NOT]] 4014; CHECK-NEXT: ret i32 [[COND]] 4015; 4016entry: 4017 %or = or i32 %y, %x 4018 %cmp = icmp eq i32 %or, -1 4019 %xor = xor i32 %y, %x 4020 %and = and i32 %y, %x 4021 %not = xor i32 %and, -1 4022 %cond = select i1 %cmp, i32 %xor, i32 %not 4023 ret i32 %cond 4024} 4025 4026define i32 @src_or_eq_C_and_xorC(i32 %x, i32 %y, i32 %c) { 4027; CHECK-LABEL: @src_or_eq_C_and_xorC( 4028; CHECK-NEXT: entry: 4029; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] 4030; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[OR]], [[C:%.*]] 4031; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], [[X]] 4032; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]] 4033; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[XOR]], [[C]] 4034; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[XOR1]] 4035; CHECK-NEXT: ret i32 [[COND]] 4036; 4037entry: 4038 %or = or i32 %y, %x 4039 %cmp = icmp eq i32 %or, %c 4040 %and = and i32 %y, %x 4041 %xor = xor i32 %y, %x 4042 %xor1 = xor i32 %xor, %c 4043 %cond = select i1 %cmp, i32 %and, i32 %xor1 4044 ret i32 %cond 4045} 4046 4047define i32 @src_or_eq_C_and_andnotxorC(i32 %x, i32 %y, i32 %c) { 4048; CHECK-LABEL: @src_or_eq_C_and_andnotxorC( 4049; CHECK-NEXT: entry: 4050; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] 4051; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[OR]], [[C:%.*]] 4052; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], [[X]] 4053; CHECK-NEXT: [[TMP0:%.*]] = xor i32 [[X]], [[Y]] 4054; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[TMP0]], -1 4055; CHECK-NEXT: [[AND1:%.*]] = and i32 [[C]], [[NOT]] 4056; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[AND1]] 4057; CHECK-NEXT: ret i32 [[COND]] 4058; 4059entry: 4060 %or = or i32 %y, %x 4061 %cmp = icmp eq i32 %or, %c 4062 %and = and i32 %y, %x 4063 %0 = xor i32 %x, %y 4064 %not = xor i32 %0, -1 4065 %and1 = and i32 %not, %c 4066 %cond = select i1 %cmp, i32 %and, i32 %and1 4067 ret i32 %cond 4068} 4069 4070define i32 @src_or_eq_C_xor_xorandC(i32 %x, i32 %y, i32 %c) { 4071; CHECK-LABEL: @src_or_eq_C_xor_xorandC( 4072; CHECK-NEXT: entry: 4073; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] 4074; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[OR]], [[C:%.*]] 4075; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]] 4076; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], [[X]] 4077; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[AND]], [[C]] 4078; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[XOR1]] 4079; CHECK-NEXT: ret i32 [[COND]] 4080; 4081entry: 4082 %or = or i32 %y, %x 4083 %cmp = icmp eq i32 %or, %c 4084 %xor = xor i32 %y, %x 4085 %and = and i32 %y, %x 4086 %xor1 = xor i32 %and, %c 4087 %cond = select i1 %cmp, i32 %xor, i32 %xor1 4088 ret i32 %cond 4089} 4090 4091define i32 @src_or_eq_C_xor_andnotandC(i32 %x, i32 %y, i32 %c) { 4092; CHECK-LABEL: @src_or_eq_C_xor_andnotandC( 4093; CHECK-NEXT: entry: 4094; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] 4095; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[OR]], [[C:%.*]] 4096; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y]], [[X]] 4097; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], [[X]] 4098; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[AND]], -1 4099; CHECK-NEXT: [[AND1:%.*]] = and i32 [[C]], [[NOT]] 4100; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[AND1]] 4101; CHECK-NEXT: ret i32 [[COND]] 4102; 4103entry: 4104 %or = or i32 %y, %x 4105 %cmp = icmp eq i32 %or, %c 4106 %xor = xor i32 %y, %x 4107 %and = and i32 %y, %x 4108 %not = xor i32 %and, -1 4109 %and1 = and i32 %not, %c 4110 %cond = select i1 %cmp, i32 %xor, i32 %and1 4111 ret i32 %cond 4112} 4113 4114; https://alive2.llvm.org/ce/z/c6oXi4 4115; X^Y==C?X&Y:X|Y, X^Y==C?X|Y:X&Y 4116define i32 @src_xor_eq_neg1_and(i32 %x, i32 %y) { 4117; CHECK-LABEL: @src_xor_eq_neg1_and( 4118; CHECK-NEXT: entry: 4119; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]] 4120; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[XOR]], -1 4121; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], [[X]] 4122; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y]], [[X]] 4123; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[OR]], -1 4124; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[NOT]] 4125; CHECK-NEXT: ret i32 [[COND]] 4126; 4127entry: 4128 %xor = xor i32 %y, %x 4129 %cmp = icmp eq i32 %xor, -1 4130 %and = and i32 %y, %x 4131 %or = or i32 %y, %x 4132 %not = xor i32 %or, -1 4133 %cond = select i1 %cmp, i32 %and, i32 %not 4134 ret i32 %cond 4135} 4136 4137; TODO: X^Y==-1 could imply no_common_bit to TrueValue 4138define i32 @src_xor_eq_neg1_or(i32 %x, i32 %y) { 4139; CHECK-LABEL: @src_xor_eq_neg1_or( 4140; CHECK-NEXT: entry: 4141; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]] 4142; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[XOR]], -1 4143; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y]], [[X]] 4144; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 -1 4145; CHECK-NEXT: ret i32 [[COND]] 4146; 4147entry: 4148 %xor = xor i32 %y, %x 4149 %cmp = icmp eq i32 %xor, -1 4150 %or = or i32 %y, %x 4151 %cond = select i1 %cmp, i32 %or, i32 -1 4152 ret i32 %cond 4153} 4154 4155define i32 @src_xor_eq_C_and_xororC(i32 %x, i32 %y, i32 %c) { 4156; CHECK-LABEL: @src_xor_eq_C_and_xororC( 4157; CHECK-NEXT: entry: 4158; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]] 4159; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[XOR]], [[C:%.*]] 4160; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], [[X]] 4161; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y]], [[X]] 4162; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[OR]], [[C]] 4163; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[XOR1]] 4164; CHECK-NEXT: ret i32 [[COND]] 4165; 4166entry: 4167 %xor = xor i32 %y, %x 4168 %cmp = icmp eq i32 %xor, %c 4169 %and = and i32 %y, %x 4170 %or = or i32 %y, %x 4171 %xor1 = xor i32 %or, %c 4172 %cond = select i1 %cmp, i32 %and, i32 %xor1 4173 ret i32 %cond 4174} 4175 4176define i32 @src_xor_eq_C_and_andornotC(i32 %x, i32 %y, i32 %c) { 4177; CHECK-LABEL: @src_xor_eq_C_and_andornotC( 4178; CHECK-NEXT: entry: 4179; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]] 4180; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[XOR]], [[C:%.*]] 4181; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], [[X]] 4182; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y]], [[X]] 4183; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[C]], -1 4184; CHECK-NEXT: [[AND1:%.*]] = and i32 [[OR]], [[NOT]] 4185; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[AND1]] 4186; CHECK-NEXT: ret i32 [[COND]] 4187; 4188entry: 4189 %xor = xor i32 %y, %x 4190 %cmp = icmp eq i32 %xor, %c 4191 %and = and i32 %y, %x 4192 %or = or i32 %y, %x 4193 %not = xor i32 %c, -1 4194 %and1 = and i32 %or, %not 4195 %cond = select i1 %cmp, i32 %and, i32 %and1 4196 ret i32 %cond 4197} 4198 4199define i32 @src_xor_eq_C_or_xorandC(i32 %x, i32 %y, i32 %c) { 4200; CHECK-LABEL: @src_xor_eq_C_or_xorandC( 4201; CHECK-NEXT: entry: 4202; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]] 4203; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[XOR]], [[C:%.*]] 4204; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y]], [[X]] 4205; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], [[X]] 4206; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[AND]], [[C]] 4207; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[XOR1]] 4208; CHECK-NEXT: ret i32 [[COND]] 4209; 4210entry: 4211 %xor = xor i32 %y, %x 4212 %cmp = icmp eq i32 %xor, %c 4213 %or = or i32 %y, %x 4214 %and = and i32 %y, %x 4215 %xor1 = xor i32 %and, %c 4216 %cond = select i1 %cmp, i32 %or, i32 %xor1 4217 ret i32 %cond 4218} 4219 4220define i32 @src_xor_eq_C_or_orandC(i32 %x, i32 %y, i32 %c) { 4221; CHECK-LABEL: @src_xor_eq_C_or_orandC( 4222; CHECK-NEXT: entry: 4223; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]] 4224; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[XOR]], [[C:%.*]] 4225; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y]], [[X]] 4226; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], [[X]] 4227; CHECK-NEXT: [[OR1:%.*]] = or i32 [[AND]], [[C]] 4228; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[OR1]] 4229; CHECK-NEXT: ret i32 [[COND]] 4230; 4231entry: 4232 %xor = xor i32 %y, %x 4233 %cmp = icmp eq i32 %xor, %c 4234 %or = or i32 %y, %x 4235 %and = and i32 %y, %x 4236 %or1 = or i32 %and, %c 4237 %cond = select i1 %cmp, i32 %or, i32 %or1 4238 ret i32 %cond 4239} 4240 4241; Select icmp and/or/xor 4242; NO TRANSFORMED - select condition is compare with not 0 4243define i32 @src_select_and_min_positive_int(i32 %x, i32 %y) { 4244; CHECK-LABEL: @src_select_and_min_positive_int( 4245; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 4246; CHECK-NEXT: [[AND0:%.*]] = icmp eq i32 [[AND]], 1 4247; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]] 4248; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]] 4249; CHECK-NEXT: [[COND:%.*]] = select i1 [[AND0]], i32 [[OR]], i32 [[XOR]] 4250; CHECK-NEXT: ret i32 [[COND]] 4251; 4252 %and = and i32 %x, %y 4253 %and0 = icmp eq i32 %and, 1 4254 %xor = xor i32 %x, %y 4255 %or = or i32 %x, %y 4256 %cond = select i1 %and0, i32 %or, i32 %xor 4257 ret i32 %cond 4258} 4259 4260define i32 @src_select_and_max_positive_int(i32 %x, i32 %y) { 4261; CHECK-LABEL: @src_select_and_max_positive_int( 4262; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 4263; CHECK-NEXT: [[AND0:%.*]] = icmp eq i32 [[AND]], 2147483647 4264; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]] 4265; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]] 4266; CHECK-NEXT: [[COND:%.*]] = select i1 [[AND0]], i32 [[OR]], i32 [[XOR]] 4267; CHECK-NEXT: ret i32 [[COND]] 4268; 4269 %and = and i32 %x, %y 4270 %and0 = icmp eq i32 %and, 2147483647 4271 %xor = xor i32 %x, %y 4272 %or = or i32 %x, %y 4273 %cond = select i1 %and0, i32 %or, i32 %xor 4274 ret i32 %cond 4275} 4276 4277define i32 @src_select_and_min_negative_int(i32 %x, i32 %y) { 4278; CHECK-LABEL: @src_select_and_min_negative_int( 4279; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 4280; CHECK-NEXT: [[AND0:%.*]] = icmp eq i32 [[AND]], -2147483648 4281; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]] 4282; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]] 4283; CHECK-NEXT: [[COND:%.*]] = select i1 [[AND0]], i32 [[OR]], i32 [[XOR]] 4284; CHECK-NEXT: ret i32 [[COND]] 4285; 4286 %and = and i32 %x, %y 4287 %and0 = icmp eq i32 %and, -2147483648 4288 %xor = xor i32 %x, %y 4289 %or = or i32 %x, %y 4290 %cond = select i1 %and0, i32 %or, i32 %xor 4291 ret i32 %cond 4292} 4293 4294define i32 @src_select_or_min_positive_int(i32 %x, i32 %y) { 4295; CHECK-LABEL: @src_select_or_min_positive_int( 4296; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]] 4297; CHECK-NEXT: [[OR0:%.*]] = icmp eq i32 [[OR]], 1 4298; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]] 4299; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]] 4300; CHECK-NEXT: [[COND:%.*]] = select i1 [[OR0]], i32 [[AND]], i32 [[XOR]] 4301; CHECK-NEXT: ret i32 [[COND]] 4302; 4303 %or = or i32 %x, %y 4304 %or0 = icmp eq i32 %or, 1 4305 %and = and i32 %x, %y 4306 %xor = xor i32 %x, %y 4307 %cond = select i1 %or0, i32 %and, i32 %xor 4308 ret i32 %cond 4309} 4310 4311define i32 @src_select_or_max_positive_int(i32 %x, i32 %y) { 4312; CHECK-LABEL: @src_select_or_max_positive_int( 4313; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]] 4314; CHECK-NEXT: [[OR0:%.*]] = icmp eq i32 [[OR]], 2147483647 4315; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]] 4316; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]] 4317; CHECK-NEXT: [[COND:%.*]] = select i1 [[OR0]], i32 [[AND]], i32 [[XOR]] 4318; CHECK-NEXT: ret i32 [[COND]] 4319; 4320 %or = or i32 %x, %y 4321 %or0 = icmp eq i32 %or, 2147483647 4322 %and = and i32 %x, %y 4323 %xor = xor i32 %x, %y 4324 %cond = select i1 %or0, i32 %and, i32 %xor 4325 ret i32 %cond 4326} 4327 4328define i32 @src_select_or_min_negative_int(i32 %x, i32 %y) { 4329; CHECK-LABEL: @src_select_or_min_negative_int( 4330; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]] 4331; CHECK-NEXT: [[OR0:%.*]] = icmp eq i32 [[OR]], -2147483648 4332; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]] 4333; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]] 4334; CHECK-NEXT: [[COND:%.*]] = select i1 [[OR0]], i32 [[AND]], i32 [[XOR]] 4335; CHECK-NEXT: ret i32 [[COND]] 4336; 4337 %or = or i32 %x, %y 4338 %or0 = icmp eq i32 %or, -2147483648 4339 %and = and i32 %x, %y 4340 %xor = xor i32 %x, %y 4341 %cond = select i1 %or0, i32 %and, i32 %xor 4342 ret i32 %cond 4343} 4344 4345define i32 @src_select_or_max_negative_int(i32 %x, i32 %y) { 4346; CHECK-LABEL: @src_select_or_max_negative_int( 4347; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]] 4348; CHECK-NEXT: [[OR0:%.*]] = icmp eq i32 [[OR]], -1 4349; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]] 4350; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]] 4351; CHECK-NEXT: [[COND:%.*]] = select i1 [[OR0]], i32 [[AND]], i32 [[XOR]] 4352; CHECK-NEXT: ret i32 [[COND]] 4353; 4354 %or = or i32 %x, %y 4355 %or0 = icmp eq i32 %or, -1 4356 %and = and i32 %x, %y 4357 %xor = xor i32 %x, %y 4358 %cond = select i1 %or0, i32 %and, i32 %xor 4359 ret i32 %cond 4360} 4361 4362define i32 @src_select_xor_min_positive_int(i32 %x, i32 %y) { 4363; CHECK-LABEL: @src_select_xor_min_positive_int( 4364; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 4365; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[XOR]], 1 4366; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]] 4367; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]] 4368; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[OR]] 4369; CHECK-NEXT: ret i32 [[COND]] 4370; 4371 %xor = xor i32 %x, %y 4372 %xor0 = icmp eq i32 %xor, 1 4373 %and = and i32 %x, %y 4374 %or = or i32 %x, %y 4375 %cond = select i1 %xor0, i32 %and, i32 %or 4376 ret i32 %cond 4377} 4378 4379define i32 @src_select_xor_max_positive_int(i32 %x, i32 %y) { 4380; CHECK-LABEL: @src_select_xor_max_positive_int( 4381; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 4382; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[XOR]], 2147483647 4383; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]] 4384; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]] 4385; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[OR]] 4386; CHECK-NEXT: ret i32 [[COND]] 4387; 4388 %xor = xor i32 %x, %y 4389 %xor0 = icmp eq i32 %xor, 2147483647 4390 %and = and i32 %x, %y 4391 %or = or i32 %x, %y 4392 %cond = select i1 %xor0, i32 %and, i32 %or 4393 ret i32 %cond 4394} 4395 4396define i32 @src_select_xor_min_negative_int(i32 %x, i32 %y) { 4397; CHECK-LABEL: @src_select_xor_min_negative_int( 4398; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 4399; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[XOR]], -2147483648 4400; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]] 4401; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]] 4402; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[OR]] 4403; CHECK-NEXT: ret i32 [[COND]] 4404; 4405 %xor = xor i32 %x, %y 4406 %xor0 = icmp eq i32 %xor, -2147483648 4407 %and = and i32 %x, %y 4408 %or = or i32 %x, %y 4409 %cond = select i1 %xor0, i32 %and, i32 %or 4410 ret i32 %cond 4411} 4412 4413define i32 @src_select_xor_max_negative_int(i32 %x, i32 %y) { 4414; CHECK-LABEL: @src_select_xor_max_negative_int( 4415; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 4416; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[XOR]], -1 4417; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]] 4418; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]] 4419; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[OR]] 4420; CHECK-NEXT: ret i32 [[COND]] 4421; 4422 %xor = xor i32 %x, %y 4423 %xor0 = icmp eq i32 %xor, -1 4424 %and = and i32 %x, %y 4425 %or = or i32 %x, %y 4426 %cond = select i1 %xor0, i32 %and, i32 %or 4427 ret i32 %cond 4428} 4429 4430; Select icmp and/or/xor 4431; https://alive2.llvm.org/ce/z/BVgrJ- 4432; NO TRANSFORMED - not supported 4433define i32 @src_no_trans_select_and_eq0_and_or(i32 %x, i32 %y) { 4434; CHECK-LABEL: @src_no_trans_select_and_eq0_and_or( 4435; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 4436; CHECK-NEXT: [[AND0:%.*]] = icmp eq i32 [[AND]], 0 4437; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]] 4438; CHECK-NEXT: [[COND:%.*]] = select i1 [[AND0]], i32 0, i32 [[OR]] 4439; CHECK-NEXT: ret i32 [[COND]] 4440; 4441 %and = and i32 %x, %y 4442 %and0 = icmp eq i32 %and, 0 4443 %or = or i32 %x, %y 4444 %cond = select i1 %and0, i32 %and, i32 %or 4445 ret i32 %cond 4446} 4447 4448define i32 @src_no_trans_select_and_eq0_and_xor(i32 %x, i32 %y) { 4449; CHECK-LABEL: @src_no_trans_select_and_eq0_and_xor( 4450; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 4451; CHECK-NEXT: [[AND0:%.*]] = icmp eq i32 [[AND]], 0 4452; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]] 4453; CHECK-NEXT: [[COND:%.*]] = select i1 [[AND0]], i32 0, i32 [[XOR]] 4454; CHECK-NEXT: ret i32 [[COND]] 4455; 4456 %and = and i32 %x, %y 4457 %and0 = icmp eq i32 %and, 0 4458 %xor = xor i32 %x, %y 4459 %cond = select i1 %and0, i32 %and, i32 %xor 4460 ret i32 %cond 4461} 4462 4463define i32 @src_no_trans_select_and_eq0_or_and(i32 %x, i32 %y) { 4464; CHECK-LABEL: @src_no_trans_select_and_eq0_or_and( 4465; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 4466; CHECK-NEXT: [[AND0:%.*]] = icmp eq i32 [[AND]], 0 4467; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]] 4468; CHECK-NEXT: [[COND:%.*]] = select i1 [[AND0]], i32 [[OR]], i32 [[AND]] 4469; CHECK-NEXT: ret i32 [[COND]] 4470; 4471 %and = and i32 %x, %y 4472 %and0 = icmp eq i32 %and, 0 4473 %or = or i32 %x, %y 4474 %cond = select i1 %and0, i32 %or, i32 %and 4475 ret i32 %cond 4476} 4477 4478define i32 @src_no_trans_select_and_eq0_xor_and(i32 %x, i32 %y) { 4479; CHECK-LABEL: @src_no_trans_select_and_eq0_xor_and( 4480; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 4481; CHECK-NEXT: [[AND0:%.*]] = icmp eq i32 [[AND]], 0 4482; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]] 4483; CHECK-NEXT: [[COND:%.*]] = select i1 [[AND0]], i32 [[XOR]], i32 [[AND]] 4484; CHECK-NEXT: ret i32 [[COND]] 4485; 4486 %and = and i32 %x, %y 4487 %and0 = icmp eq i32 %and, 0 4488 %xor = xor i32 %x, %y 4489 %cond = select i1 %and0, i32 %xor, i32 %and 4490 ret i32 %cond 4491} 4492 4493define i32 @src_no_trans_select_or_eq0_or_and(i32 %x, i32 %y) { 4494; CHECK-LABEL: @src_no_trans_select_or_eq0_or_and( 4495; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 4496; CHECK-NEXT: ret i32 [[AND]] 4497; 4498 %or = or i32 %x, %y 4499 %or0 = icmp eq i32 %or, 0 4500 %and = and i32 %x, %y 4501 %cond = select i1 %or0, i32 %or, i32 %and 4502 ret i32 %cond 4503} 4504 4505define i32 @src_no_trans_select_or_eq0_or_xor(i32 %x, i32 %y) { 4506; CHECK-LABEL: @src_no_trans_select_or_eq0_or_xor( 4507; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 4508; CHECK-NEXT: ret i32 [[XOR]] 4509; 4510 %or = or i32 %x, %y 4511 %or0 = icmp eq i32 %or, 0 4512 %xor = xor i32 %x, %y 4513 %cond = select i1 %or0, i32 %or, i32 %xor 4514 ret i32 %cond 4515} 4516 4517define i32 @src_no_trans_select_or_eq0_and_or(i32 %x, i32 %y) { 4518; CHECK-LABEL: @src_no_trans_select_or_eq0_and_or( 4519; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]] 4520; CHECK-NEXT: ret i32 [[OR]] 4521; 4522 %or = or i32 %x, %y 4523 %or0 = icmp eq i32 %or, 0 4524 %and = and i32 %x, %y 4525 %cond = select i1 %or0, i32 %and, i32 %or 4526 ret i32 %cond 4527} 4528 4529define i32 @src_no_trans_select_or_eq0_xor_or(i32 %x, i32 %y) { 4530; CHECK-LABEL: @src_no_trans_select_or_eq0_xor_or( 4531; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], [[Y:%.*]] 4532; CHECK-NEXT: ret i32 [[OR]] 4533; 4534 %or = or i32 %x, %y 4535 %or0 = icmp eq i32 %or, 0 4536 %xor = xor i32 %x, %y 4537 %cond = select i1 %or0, i32 %xor, i32 %or 4538 ret i32 %cond 4539} 4540 4541define i32 @src_no_trans_select_and_ne0_xor_or(i32 %x, i32 %y) { 4542; CHECK-LABEL: @src_no_trans_select_and_ne0_xor_or( 4543; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 4544; CHECK-NEXT: ret i32 [[XOR]] 4545; 4546 %or = or i32 %x, %y 4547 %or0 = icmp ne i32 %or, 0 4548 %xor = xor i32 %x, %y 4549 %cond = select i1 %or0, i32 %xor, i32 %or 4550 ret i32 %cond 4551} 4552 4553define i32 @src_no_trans_select_xor_eq0_xor_and(i32 %x, i32 %y) { 4554; CHECK-LABEL: @src_no_trans_select_xor_eq0_xor_and( 4555; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 4556; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]] 4557; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 0, i32 [[AND]] 4558; CHECK-NEXT: ret i32 [[COND]] 4559; 4560 %xor = xor i32 %x, %y 4561 %xor0 = icmp eq i32 %xor, 0 4562 %and = and i32 %x, %y 4563 %cond = select i1 %xor0, i32 %xor, i32 %and 4564 ret i32 %cond 4565} 4566 4567define i32 @src_no_trans_select_xor_eq0_xor_or(i32 %x, i32 %y) { 4568; CHECK-LABEL: @src_no_trans_select_xor_eq0_xor_or( 4569; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 4570; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]] 4571; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 0, i32 [[OR]] 4572; CHECK-NEXT: ret i32 [[COND]] 4573; 4574 %xor = xor i32 %x, %y 4575 %xor0 = icmp eq i32 %xor, 0 4576 %or = or i32 %x, %y 4577 %cond = select i1 %xor0, i32 %xor, i32 %or 4578 ret i32 %cond 4579} 4580 4581define i32 @src_no_trans_select_xor_eq0_and_xor(i32 %x, i32 %y) { 4582; CHECK-LABEL: @src_no_trans_select_xor_eq0_and_xor( 4583; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 4584; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[X]], [[Y]] 4585; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]] 4586; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[XOR]] 4587; CHECK-NEXT: ret i32 [[COND]] 4588; 4589 %xor = xor i32 %x, %y 4590 %xor0 = icmp eq i32 %xor, 0 4591 %and = and i32 %x, %y 4592 %cond = select i1 %xor0, i32 %and, i32 %xor 4593 ret i32 %cond 4594} 4595 4596; https://alive2.llvm.org/ce/z/SBe8ei 4597define i32 @src_no_trans_select_xor_eq0_or_xor(i32 %x, i32 %y) { 4598; CHECK-LABEL: @src_no_trans_select_xor_eq0_or_xor( 4599; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 4600; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[X]], [[Y]] 4601; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]] 4602; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 [[OR]], i32 [[XOR]] 4603; CHECK-NEXT: ret i32 [[COND]] 4604; 4605 %xor = xor i32 %x, %y 4606 %xor0 = icmp eq i32 %xor, 0 4607 %or = or i32 %x, %y 4608 %cond = select i1 %xor0, i32 %or, i32 %xor 4609 ret i32 %cond 4610} 4611 4612; (X == C) ? X : Y -> (X == C) ? C : Y 4613; Fixed #77553 4614define i32 @src_select_xxory_eq0_xorxy_y(i32 %x, i32 %y) { 4615; CHECK-LABEL: @src_select_xxory_eq0_xorxy_y( 4616; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 4617; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 0, i32 [[Y]] 4618; CHECK-NEXT: ret i32 [[COND]] 4619; 4620 %xor = xor i32 %x, %y 4621 %xor0 = icmp eq i32 %xor, 0 4622 %cond = select i1 %xor0, i32 %xor, i32 %y 4623 ret i32 %cond 4624} 4625 4626define i32 @sequence_select_with_same_cond_false(i1 %c1, i1 %c2){ 4627; CHECK-LABEL: @sequence_select_with_same_cond_false( 4628; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], i32 666, i32 45 4629; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1:%.*]], i32 789, i32 [[S2]] 4630; CHECK-NEXT: ret i32 [[S3]] 4631; 4632 %s1 = select i1 %c1, i32 23, i32 45 4633 %s2 = select i1 %c2, i32 666, i32 %s1 4634 %s3 = select i1 %c1, i32 789, i32 %s2 4635 ret i32 %s3 4636} 4637 4638define i32 @sequence_select_with_same_cond_true(i1 %c1, i1 %c2){ 4639; CHECK-LABEL: @sequence_select_with_same_cond_true( 4640; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], i32 45, i32 666 4641; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1:%.*]], i32 [[S2]], i32 789 4642; CHECK-NEXT: ret i32 [[S3]] 4643; 4644 %s1 = select i1 %c1, i32 45, i32 23 4645 %s2 = select i1 %c2, i32 %s1, i32 666 4646 %s3 = select i1 %c1, i32 %s2, i32 789 4647 ret i32 %s3 4648} 4649 4650define double @sequence_select_with_same_cond_double(double %a, i1 %c1, i1 %c2, double %r1, double %r2){ 4651; CHECK-LABEL: @sequence_select_with_same_cond_double( 4652; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1:%.*]], double 1.000000e+00, double 0.000000e+00 4653; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], double [[S1]], double 2.000000e+00 4654; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1]], double [[S2]], double 3.000000e+00 4655; CHECK-NEXT: ret double [[S3]] 4656; 4657 %s1 = select i1 %c1, double 1.0, double 0.0 4658 %s2 = select i1 %c2, double %s1, double 2.0 4659 %s3 = select i1 %c1, double %s2, double 3.0 4660 ret double %s3 4661} 4662 4663declare void @use32(i32) 4664 4665define i32 @sequence_select_with_same_cond_extra_use(i1 %c1, i1 %c2){ 4666; CHECK-LABEL: @sequence_select_with_same_cond_extra_use( 4667; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1:%.*]], i32 23, i32 45 4668; CHECK-NEXT: call void @use32(i32 [[S1]]) 4669; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], i32 666, i32 [[S1]] 4670; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1]], i32 789, i32 [[S2]] 4671; CHECK-NEXT: ret i32 [[S3]] 4672; 4673 %s1 = select i1 %c1, i32 23, i32 45 4674 call void @use32(i32 %s1) 4675 %s2 = select i1 %c2, i32 666, i32 %s1 4676 %s3 = select i1 %c1, i32 789, i32 %s2 4677 ret i32 %s3 4678} 4679 4680define i8 @test_replace_freeze_multiuse(i1 %x, i8 %y) { 4681; CHECK-LABEL: @test_replace_freeze_multiuse( 4682; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[X:%.*]] to i8 4683; CHECK-NEXT: [[SHL:%.*]] = shl nuw i8 [[EXT]], [[Y:%.*]] 4684; CHECK-NEXT: [[SHL_FR:%.*]] = freeze i8 [[SHL]] 4685; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X]], i8 0, i8 [[SHL_FR]] 4686; CHECK-NEXT: [[ADD:%.*]] = add i8 [[SHL_FR]], [[SEL]] 4687; CHECK-NEXT: ret i8 [[ADD]] 4688; 4689 %ext = zext i1 %x to i8 4690 %shl = shl nuw i8 %ext, %y 4691 %shl.fr = freeze i8 %shl 4692 %sel = select i1 %x, i8 0, i8 %shl.fr 4693 %add = add i8 %shl.fr, %sel 4694 ret i8 %add 4695} 4696 4697define i8 @test_replace_freeze_oneuse(i1 %x, i8 %y) { 4698; CHECK-LABEL: @test_replace_freeze_oneuse( 4699; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[X:%.*]] to i8 4700; CHECK-NEXT: [[SHL:%.*]] = shl nuw i8 [[EXT]], [[Y:%.*]] 4701; CHECK-NEXT: [[SHL_FR:%.*]] = freeze i8 [[SHL]] 4702; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X]], i8 0, i8 [[SHL_FR]] 4703; CHECK-NEXT: ret i8 [[SEL]] 4704; 4705 %ext = zext i1 %x to i8 4706 %shl = shl nuw i8 %ext, %y 4707 %shl.fr = freeze i8 %shl 4708 %sel = select i1 %x, i8 0, i8 %shl.fr 4709 ret i8 %sel 4710} 4711 4712define i8 @select_knownbits_simplify(i8 noundef %x) { 4713; CHECK-LABEL: @select_knownbits_simplify( 4714; CHECK-NEXT: [[X_LO:%.*]] = and i8 [[X:%.*]], 1 4715; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0 4716; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -2 4717; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i8 [[AND]], i8 0 4718; CHECK-NEXT: ret i8 [[RES]] 4719; 4720 %x.lo = and i8 %x, 1 4721 %cmp = icmp eq i8 %x.lo, 0 4722 %and = and i8 %x, -2 4723 %res = select i1 %cmp, i8 %and, i8 0 4724 ret i8 %res 4725} 4726 4727define i8 @select_knownbits_simplify_nested(i8 noundef %x) { 4728; CHECK-LABEL: @select_knownbits_simplify_nested( 4729; CHECK-NEXT: [[X_LO:%.*]] = and i8 [[X:%.*]], 1 4730; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0 4731; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -2 4732; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[AND]], [[AND]] 4733; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i8 [[MUL]], i8 0 4734; CHECK-NEXT: ret i8 [[RES]] 4735; 4736 %x.lo = and i8 %x, 1 4737 %cmp = icmp eq i8 %x.lo, 0 4738 %and = and i8 %x, -2 4739 %mul = mul i8 %and, %and 4740 %res = select i1 %cmp, i8 %mul, i8 0 4741 ret i8 %res 4742} 4743 4744define i8 @select_knownbits_simplify_missing_noundef(i8 %x) { 4745; CHECK-LABEL: @select_knownbits_simplify_missing_noundef( 4746; CHECK-NEXT: [[X_LO:%.*]] = and i8 [[X:%.*]], 1 4747; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0 4748; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -2 4749; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i8 [[AND]], i8 0 4750; CHECK-NEXT: ret i8 [[RES]] 4751; 4752 %x.lo = and i8 %x, 1 4753 %cmp = icmp eq i8 %x.lo, 0 4754 %and = and i8 %x, -2 4755 %res = select i1 %cmp, i8 %and, i8 0 4756 ret i8 %res 4757} 4758 4759@g_ext = external global i8 4760 4761; Make sure we don't replace %ptr with @g_ext, which may cause the load to trigger UB. 4762define i32 @pr99436(ptr align 4 dereferenceable(4) %ptr) { 4763; CHECK-LABEL: @pr99436( 4764; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[PTR:%.*]], @g_ext 4765; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[PTR]], align 4 4766; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[VAL]], i32 0 4767; CHECK-NEXT: ret i32 [[RET]] 4768; 4769 %cmp = icmp eq ptr %ptr, @g_ext 4770 %val = load i32, ptr %ptr, align 4 4771 %ret = select i1 %cmp, i32 %val, i32 0 4772 ret i32 %ret 4773} 4774 4775define i8 @sel_trunc_simplify(i1 %c, i8 %x, i16 %y) { 4776; CHECK-LABEL: @sel_trunc_simplify( 4777; CHECK-NEXT: [[TMP1:%.*]] = trunc i16 [[Y:%.*]] to i8 4778; CHECK-NEXT: [[TRUNC:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]] 4779; CHECK-NEXT: ret i8 [[TRUNC]] 4780; 4781 %x.ext = zext i8 %x to i16 4782 %sel = select i1 %c, i16 %x.ext, i16 %y 4783 %trunc = trunc i16 %sel to i8 4784 ret i8 %trunc 4785} 4786 4787define i32 @sel_umin_simplify(i1 %c, i32 %x, i16 %y) { 4788; CHECK-LABEL: @sel_umin_simplify( 4789; CHECK-NEXT: [[ARG2_EXT:%.*]] = zext i16 [[ARG2:%.*]] to i32 4790; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 [[ARG2_EXT]]) 4791; CHECK-NEXT: [[RES:%.*]] = select i1 [[C:%.*]], i32 [[TMP1]], i32 0 4792; CHECK-NEXT: ret i32 [[RES]] 4793; 4794 %sel = select i1 %c, i32 %x, i32 0 4795 %y.ext = zext i16 %y to i32 4796 %res = call i32 @llvm.umin.i32(i32 %sel, i32 %y.ext) 4797 ret i32 %res 4798} 4799 4800define i32 @sel_extractvalue_simplify(i1 %c, { i32, i32 } %agg1, i32 %x, i32 %y) { 4801; CHECK-LABEL: @sel_extractvalue_simplify( 4802; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i32, i32 } [[AGG1:%.*]], 1 4803; CHECK-NEXT: [[RES:%.*]] = select i1 [[C:%.*]], i32 [[TMP1]], i32 [[Y:%.*]] 4804; CHECK-NEXT: ret i32 [[RES]] 4805; 4806 %agg2.0 = insertvalue { i32, i32 } poison, i32 %x, 0 4807 %agg2.1 = insertvalue { i32, i32 } %agg2.0, i32 %y, 1 4808 %sel = select i1 %c, { i32, i32 } %agg1, { i32, i32 } %agg2.1 4809 %res = extractvalue { i32, i32 } %sel, 1 4810 ret i32 %res 4811} 4812 4813define i1 @replace_select_cond_true(i1 %cond, i32 %v1, i32 %v2, i32 %v3) { 4814; CHECK-LABEL: @replace_select_cond_true( 4815; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[SEL:%.*]], [[V2:%.*]] 4816; CHECK-NEXT: [[AND:%.*]] = select i1 [[COND:%.*]], i1 [[CMP]], i1 false 4817; CHECK-NEXT: ret i1 [[AND]] 4818; 4819 %sel = select i1 %cond, i32 %v1, i32 %v3 4820 %cmp = icmp eq i32 %sel, %v2 4821 %and = select i1 %cond, i1 %cmp, i1 false 4822 ret i1 %and 4823} 4824 4825define i1 @replace_select_cond_false(i1 %cond, i32 %v1, i32 %v2, i32 %v3) { 4826; CHECK-LABEL: @replace_select_cond_false( 4827; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[SEL:%.*]], [[V2:%.*]] 4828; CHECK-NEXT: [[OR:%.*]] = select i1 [[COND:%.*]], i1 true, i1 [[CMP]] 4829; CHECK-NEXT: ret i1 [[OR]] 4830; 4831 %sel = select i1 %cond, i32 %v1, i32 %v3 4832 %cmp = icmp eq i32 %sel, %v2 4833 %or = select i1 %cond, i1 true, i1 %cmp 4834 ret i1 %or 4835} 4836 4837define i32 @replace_and_cond(i1 %cond1, i1 %cond2) { 4838; CHECK-LABEL: @replace_and_cond( 4839; CHECK-NEXT: [[SEL:%.*]] = select i1 [[AND:%.*]], i32 3, i32 2 4840; CHECK-NEXT: [[MUX:%.*]] = select i1 [[COND1:%.*]], i32 [[SEL]], i32 1 4841; CHECK-NEXT: ret i32 [[MUX]] 4842; 4843 %and = and i1 %cond1, %cond2 4844 %sel = select i1 %and, i32 3, i32 2 4845 %mux = select i1 %cond1, i32 %sel, i32 1 4846 ret i32 %mux 4847} 4848 4849define <2 x i32> @replace_and_cond_vec(<2 x i1> %cond1, <2 x i1> %cond2) { 4850; CHECK-LABEL: @replace_and_cond_vec( 4851; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[COND2:%.*]], <2 x i32> splat (i32 3), <2 x i32> splat (i32 2) 4852; CHECK-NEXT: [[MUX:%.*]] = select <2 x i1> [[COND1:%.*]], <2 x i32> [[SEL]], <2 x i32> splat (i32 1) 4853; CHECK-NEXT: ret <2 x i32> [[MUX]] 4854; 4855 %and = and <2 x i1> %cond1, %cond2 4856 %sel = select <2 x i1> %and, <2 x i32> splat(i32 3), <2 x i32> splat(i32 2) 4857 %mux = select <2 x i1> %cond1, <2 x i32> %sel, <2 x i32> splat(i32 1) 4858 ret <2 x i32> %mux 4859} 4860 4861; TODO: We can still replace the use of %and with %cond2 4862define i32 @replace_and_cond_multiuse1(i1 %cond1, i1 %cond2) { 4863; CHECK-LABEL: @replace_and_cond_multiuse1( 4864; CHECK-NEXT: [[AND:%.*]] = and i1 [[COND1:%.*]], [[COND2:%.*]] 4865; CHECK-NEXT: call void @use(i1 [[AND]]) 4866; CHECK-NEXT: [[SEL:%.*]] = select i1 [[AND]], i32 3, i32 2 4867; CHECK-NEXT: [[MUX:%.*]] = select i1 [[COND1]], i32 [[SEL]], i32 1 4868; CHECK-NEXT: ret i32 [[MUX]] 4869; 4870 %and = and i1 %cond1, %cond2 4871 call void @use(i1 %and) 4872 %sel = select i1 %and, i32 3, i32 2 4873 %mux = select i1 %cond1, i32 %sel, i32 1 4874 ret i32 %mux 4875} 4876 4877define i32 @replace_and_cond_multiuse2(i1 %cond1, i1 %cond2) { 4878; CHECK-LABEL: @replace_and_cond_multiuse2( 4879; CHECK-NEXT: [[AND:%.*]] = and i1 [[COND1:%.*]], [[COND2:%.*]] 4880; CHECK-NEXT: [[SEL:%.*]] = select i1 [[AND]], i32 3, i32 2 4881; CHECK-NEXT: call void @use32(i32 [[SEL]]) 4882; CHECK-NEXT: [[MUX:%.*]] = select i1 [[COND1]], i32 [[SEL]], i32 1 4883; CHECK-NEXT: ret i32 [[MUX]] 4884; 4885 %and = and i1 %cond1, %cond2 4886 %sel = select i1 %and, i32 3, i32 2 4887 call void @use32(i32 %sel) 4888 %mux = select i1 %cond1, i32 %sel, i32 1 4889 ret i32 %mux 4890} 4891 4892define i32 @src_simplify_2x_at_once_and(i32 %x, i32 %y) { 4893; CHECK-LABEL: @src_simplify_2x_at_once_and( 4894; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 4895; CHECK-NEXT: ret i32 [[XOR]] 4896; 4897 %and = and i32 %x, %y 4898 %and0 = icmp eq i32 %and, -1 4899 %sub = sub i32 %x, %y 4900 %xor = xor i32 %x, %y 4901 %cond = select i1 %and0, i32 %sub, i32 %xor 4902 ret i32 %cond 4903} 4904