1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4declare void @use(<2 x i1>) 5declare void @use2(i1) 6declare void @use.i32(i32) 7 8define i32 @select_xor_icmp(i32 %x, i32 %y, i32 %z) { 9; CHECK-LABEL: @select_xor_icmp( 10; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 11; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]] 12; CHECK-NEXT: ret i32 [[C]] 13; 14 %A = icmp eq i32 %x, 0 15 %B = xor i32 %x, %z 16 %C = select i1 %A, i32 %B, i32 %y 17 ret i32 %C 18} 19 20define i32 @select_xor_icmp2(i32 %x, i32 %y, i32 %z) { 21; CHECK-LABEL: @select_xor_icmp2( 22; CHECK-NEXT: [[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], 0 23; CHECK-NEXT: [[C:%.*]] = select i1 [[A_NOT]], i32 [[Z:%.*]], i32 [[Y:%.*]] 24; CHECK-NEXT: ret i32 [[C]] 25; 26 %A = icmp ne i32 %x, 0 27 %B = xor i32 %x, %z 28 %C = select i1 %A, i32 %y, i32 %B 29 ret i32 %C 30} 31 32define i32 @select_xor_icmp_meta(i32 %x, i32 %y, i32 %z) { 33; CHECK-LABEL: @select_xor_icmp_meta( 34; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 35; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]], !prof [[PROF0:![0-9]+]] 36; CHECK-NEXT: ret i32 [[C]] 37; 38 %A = icmp eq i32 %x, 0 39 %B = xor i32 %x, %z 40 %C = select i1 %A, i32 %B, i32 %y, !prof !0 41 ret i32 %C 42} 43 44define i32 @select_mul_icmp(i32 %x, i32 %y, i32 %z) { 45; CHECK-LABEL: @select_mul_icmp( 46; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1 47; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]] 48; CHECK-NEXT: ret i32 [[C]] 49; 50 %A = icmp eq i32 %x, 1 51 %B = mul i32 %x, %z 52 %C = select i1 %A, i32 %B, i32 %y 53 ret i32 %C 54} 55 56define i32 @select_add_icmp(i32 %x, i32 %y, i32 %z) { 57; CHECK-LABEL: @select_add_icmp( 58; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 59; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]] 60; CHECK-NEXT: ret i32 [[C]] 61; 62 %A = icmp eq i32 %x, 0 63 %B = add i32 %x, %z 64 %C = select i1 %A, i32 %B, i32 %y 65 ret i32 %C 66} 67 68define i32 @select_or_icmp(i32 %x, i32 %y, i32 %z) { 69; CHECK-LABEL: @select_or_icmp( 70; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 71; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]] 72; CHECK-NEXT: ret i32 [[C]] 73; 74 %A = icmp eq i32 %x, 0 75 %B = or i32 %x, %z 76 %C = select i1 %A, i32 %B, i32 %y 77 ret i32 %C 78} 79 80define i32 @select_and_icmp(i32 %x, i32 %y, i32 %z) { 81; CHECK-LABEL: @select_and_icmp( 82; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], -1 83; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]] 84; CHECK-NEXT: ret i32 [[C]] 85; 86 %A = icmp eq i32 %x, -1 87 %B = and i32 %x, %z 88 %C = select i1 %A, i32 %B, i32 %y 89 ret i32 %C 90} 91 92define <2 x i8> @select_xor_icmp_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 93; CHECK-LABEL: @select_xor_icmp_vec( 94; CHECK-NEXT: [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], zeroinitializer 95; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[Z:%.*]], <2 x i8> [[Y:%.*]] 96; CHECK-NEXT: ret <2 x i8> [[C]] 97; 98 %A = icmp eq <2 x i8> %x, <i8 0, i8 0> 99 %B = xor <2 x i8> %x, %z 100 %C = select <2 x i1> %A, <2 x i8> %B, <2 x i8> %y 101 ret <2 x i8> %C 102} 103 104define <2 x i8> @select_xor_icmp_vec_use(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 105; CHECK-LABEL: @select_xor_icmp_vec_use( 106; CHECK-NEXT: [[A:%.*]] = icmp ne <2 x i8> [[X:%.*]], zeroinitializer 107; CHECK-NEXT: call void @use(<2 x i1> [[A]]) 108; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[Y:%.*]], <2 x i8> [[Z:%.*]] 109; CHECK-NEXT: ret <2 x i8> [[C]] 110; 111 %A = icmp ne <2 x i8> %x, <i8 0, i8 0> 112 call void @use(<2 x i1> %A) 113 %B = xor <2 x i8> %x, %z 114 %C = select <2 x i1> %A, <2 x i8> %y, <2 x i8> %B 115 ret <2 x i8> %C 116} 117 118define i32 @select_xor_inv_icmp(i32 %x, i32 %y, i32 %z) { 119; CHECK-LABEL: @select_xor_inv_icmp( 120; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 121; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]] 122; CHECK-NEXT: ret i32 [[C]] 123; 124 %A = icmp eq i32 %x, 0 125 %B = xor i32 %z, %x 126 %C = select i1 %A, i32 %B, i32 %y 127 ret i32 %C 128} 129 130define i32 @select_xor_inv_icmp2(i32 %x, i32 %y, i32 %z) { 131; CHECK-LABEL: @select_xor_inv_icmp2( 132; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0 133; CHECK-NEXT: call void @use2(i1 [[A]]) 134; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]] 135; CHECK-NEXT: ret i32 [[C]] 136; 137 %A = icmp ne i32 %x, 0 138 call void @use2(i1 %A) ; thwart predicate canonicalization 139 %B = xor i32 %x, %z 140 %C = select i1 %A, i32 %y, i32 %B 141 ret i32 %C 142} 143 144define float @select_fadd_fcmp(float %x, float %y, float %z) { 145; CHECK-LABEL: @select_fadd_fcmp( 146; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 147; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]] 148; CHECK-NEXT: ret float [[C]] 149; 150 %A = fcmp oeq float %x, -0.0 151 %B = fadd nsz float %x, %z 152 %C = select i1 %A, float %B, float %y 153 ret float %C 154} 155 156; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0. 157 158define float @select_fadd_fcmp_poszero(float %x, float %y, float %z) { 159; CHECK-LABEL: @select_fadd_fcmp_poszero( 160; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 161; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]] 162; CHECK-NEXT: ret float [[C]] 163; 164 %A = fcmp oeq float %x, 0.0 165 %B = fadd nsz float %z, %x 166 %C = select i1 %A, float %B, float %y 167 ret float %C 168} 169 170define float @select_fadd_fcmp_2(float %x, float %y, float %v) { 171; CHECK-LABEL: @select_fadd_fcmp_2( 172; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 173; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00 174; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]] 175; CHECK-NEXT: ret float [[C]] 176; 177 %A = fcmp une float %x, -0.0 178 %z = fadd float %v, 0.0 ; cannot produce -0.0 179 %B = fadd float %z, %x 180 %C = select i1 %A, float %y, float %B 181 ret float %C 182} 183 184; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0. 185 186define float @select_fadd_fcmp_2_poszero(float %x, float %y, float %v) { 187; CHECK-LABEL: @select_fadd_fcmp_2_poszero( 188; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 189; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00 190; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]] 191; CHECK-NEXT: ret float [[C]] 192; 193 %A = fcmp une float %x, 0.0 194 %z = fadd float %v, 0.0 ; cannot produce -0.0 195 %B = fadd float %z, %x 196 %C = select i1 %A, float %y, float %B 197 ret float %C 198} 199 200define float @select_fadd_fcmp_3(float %x, float %y) { 201; CHECK-LABEL: @select_fadd_fcmp_3( 202; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 203; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float 6.000000e+00 204; CHECK-NEXT: ret float [[C]] 205; 206 %A = fcmp une float %x, -0.0 207 %B = fadd float 6.0, %x 208 %C = select i1 %A, float %y, float %B 209 ret float %C 210} 211 212; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0. 213 214define float @select_fadd_fcmp_3_poszero(float %x, float %y) { 215; CHECK-LABEL: @select_fadd_fcmp_3_poszero( 216; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 217; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float 6.000000e+00 218; CHECK-NEXT: ret float [[C]] 219; 220 %A = fcmp une float %x, 0.0 221 %B = fadd float 6.0, %x 222 %C = select i1 %A, float %y, float %B 223 ret float %C 224} 225 226define float @select_fadd_fcmp_4(float %x, float %y, float %z) { 227; CHECK-LABEL: @select_fadd_fcmp_4( 228; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 229; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z:%.*]] 230; CHECK-NEXT: ret float [[C]] 231; 232 %A = fcmp une float %x, -0.0 233 %B = fadd nsz float %z, %x 234 %C = select i1 %A, float %y, float %B 235 ret float %C 236} 237 238; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0. 239 240define float @select_fadd_fcmp_4_poszero(float %x, float %y, float %z) { 241; CHECK-LABEL: @select_fadd_fcmp_4_poszero( 242; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 243; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z:%.*]] 244; CHECK-NEXT: ret float [[C]] 245; 246 %A = fcmp une float %x, 0.0 247 %B = fadd nsz float %z, %x 248 %C = select i1 %A, float %y, float %B 249 ret float %C 250} 251 252define float @select_fadd_fcmp_5(float %x, float %y, float %v) { 253; CHECK-LABEL: @select_fadd_fcmp_5( 254; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 255; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00 256; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z]], float [[Y:%.*]] 257; CHECK-NEXT: ret float [[C]] 258; 259 %A = fcmp oeq float %x, -0.0 260 %z = fadd float %v, 0.0 ; cannot produce -0.0 261 %B = fadd float %z, %x 262 %C = select i1 %A, float %B, float %y 263 ret float %C 264} 265 266; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0. 267 268define float @select_fadd_fcmp_5_poszero(float %x, float %y, float %v) { 269; CHECK-LABEL: @select_fadd_fcmp_5_poszero( 270; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 271; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00 272; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z]], float [[Y:%.*]] 273; CHECK-NEXT: ret float [[C]] 274; 275 %A = fcmp oeq float %x, 0.0 276 %z = fadd float %v, 0.0 ; cannot produce -0.0 277 %B = fadd float %z, %x 278 %C = select i1 %A, float %B, float %y 279 ret float %C 280} 281 282define float @select_fadd_fcmp_6(float %x, float %y, float %z) { 283; CHECK-LABEL: @select_fadd_fcmp_6( 284; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 285; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float 6.000000e+00, float [[Y:%.*]] 286; CHECK-NEXT: ret float [[C]] 287; 288 %A = fcmp oeq float %x, -0.0 289 %B = fadd float %x, 6.0 290 %C = select i1 %A, float %B, float %y 291 ret float %C 292} 293 294; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0. 295 296define float @select_fadd_fcmp_6_poszero(float %x, float %y, float %z) { 297; CHECK-LABEL: @select_fadd_fcmp_6_poszero( 298; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 299; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float 6.000000e+00, float [[Y:%.*]] 300; CHECK-NEXT: ret float [[C]] 301; 302 %A = fcmp oeq float %x, 0.0 303 %B = fadd float %x, 6.0 304 %C = select i1 %A, float %B, float %y 305 ret float %C 306} 307 308define float @select_fmul_fcmp(float %x, float %y, float %z) { 309; CHECK-LABEL: @select_fmul_fcmp( 310; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00 311; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]] 312; CHECK-NEXT: ret float [[C]] 313; 314 %A = fcmp oeq float %x, 1.0 315 %B = fmul nsz float %x, %z 316 %C = select i1 %A, float %B, float %y 317 ret float %C 318} 319 320define float @select_fsub_fcmp(float %x, float %y, float %z) { 321; CHECK-LABEL: @select_fsub_fcmp( 322; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 323; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]] 324; CHECK-NEXT: ret float [[C]] 325; 326 %A = fcmp oeq float %x, 0.0 327 %B = fsub nsz float %z, %x 328 %C = select i1 %A, float %B, float %y 329 ret float %C 330} 331 332; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0. 333 334define float @select_fsub_fcmp_negzero(float %x, float %y, float %z) { 335; CHECK-LABEL: @select_fsub_fcmp_negzero( 336; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 337; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]] 338; CHECK-NEXT: ret float [[C]] 339; 340 %A = fcmp oeq float %x, -0.0 341 %B = fsub nsz float %z, %x 342 %C = select i1 %A, float %B, float %y 343 ret float %C 344} 345 346define float @select_fdiv_fcmp(float %x, float %y, float %z) { 347; CHECK-LABEL: @select_fdiv_fcmp( 348; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00 349; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]] 350; CHECK-NEXT: ret float [[C]] 351; 352 %A = fcmp oeq float %x, 1.0 353 %B = fdiv nsz float %z, %x 354 %C = select i1 %A, float %B, float %y 355 ret float %C 356} 357 358define i32 @select_sub_icmp(i32 %x, i32 %y, i32 %z) { 359; CHECK-LABEL: @select_sub_icmp( 360; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 361; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]] 362; CHECK-NEXT: ret i32 [[C]] 363; 364 %A = icmp eq i32 %x, 0 365 %B = sub i32 %z, %x 366 %C = select i1 %A, i32 %B, i32 %y 367 ret i32 %C 368} 369 370define i32 @select_sub_icmp_2(i32 %x, i32 %y, i32 %z) { 371; CHECK-LABEL: @select_sub_icmp_2( 372; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 373; CHECK-NEXT: call void @use2(i1 [[A]]) 374; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]] 375; CHECK-NEXT: ret i32 [[C]] 376; 377 %A = icmp eq i32 %x, 0 378 call void @use2(i1 %A) 379 %B = sub i32 %z, %x 380 %C = select i1 %A, i32 %B, i32 %y 381 ret i32 %C 382} 383 384define i32 @select_sub_icmp_3(i32 %x, i32 %y, i32 %z) { 385; CHECK-LABEL: @select_sub_icmp_3( 386; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0 387; CHECK-NEXT: call void @use2(i1 [[A]]) 388; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]] 389; CHECK-NEXT: ret i32 [[C]] 390; 391 %A = icmp ne i32 %x, 0 392 call void @use2(i1 %A) 393 %B = sub i32 %z, %x 394 %C = select i1 %A, i32 %y, i32 %B 395 ret i32 %C 396} 397 398define <2 x i8> @select_sub_icmp_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 399; CHECK-LABEL: @select_sub_icmp_vec( 400; CHECK-NEXT: [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], zeroinitializer 401; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[Z:%.*]], <2 x i8> [[Y:%.*]] 402; CHECK-NEXT: ret <2 x i8> [[C]] 403; 404 %A = icmp eq <2 x i8> %x, <i8 0, i8 0> 405 %B = sub <2 x i8> %z, %x 406 %C = select <2 x i1> %A, <2 x i8> %B, <2 x i8> %y 407 ret <2 x i8> %C 408} 409 410define i32 @select_shl_icmp(i32 %x, i32 %y, i32 %z) { 411; CHECK-LABEL: @select_shl_icmp( 412; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0 413; CHECK-NEXT: call void @use2(i1 [[A]]) 414; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]] 415; CHECK-NEXT: ret i32 [[C]] 416; 417 %A = icmp ne i32 %x, 0 418 call void @use2(i1 %A) ; thwart predicate canonicalization 419 %B = shl i32 %z, %x 420 %C = select i1 %A, i32 %y, i32 %B 421 ret i32 %C 422} 423 424define i32 @select_lshr_icmp(i32 %x, i32 %y, i32 %z) { 425; CHECK-LABEL: @select_lshr_icmp( 426; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 427; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]] 428; CHECK-NEXT: ret i32 [[C]] 429; 430 %A = icmp eq i32 %x, 0 431 %B = lshr i32 %z, %x 432 %C = select i1 %A, i32 %B, i32 %y 433 ret i32 %C 434} 435 436define i32 @select_ashr_icmp(i32 %x, i32 %y, i32 %z) { 437; CHECK-LABEL: @select_ashr_icmp( 438; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0 439; CHECK-NEXT: call void @use2(i1 [[A]]) 440; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]] 441; CHECK-NEXT: ret i32 [[C]] 442; 443 %A = icmp ne i32 %x, 0 444 call void @use2(i1 %A) ; thwart predicate canonicalization 445 %B = ashr i32 %z, %x 446 %C = select i1 %A, i32 %y, i32 %B 447 ret i32 %C 448} 449 450define i32 @select_udiv_icmp(i32 %x, i32 %y, i32 %z) { 451; CHECK-LABEL: @select_udiv_icmp( 452; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1 453; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]] 454; CHECK-NEXT: ret i32 [[C]] 455; 456 %A = icmp eq i32 %x, 1 457 %B = udiv i32 %z, %x 458 %C = select i1 %A, i32 %B, i32 %y 459 ret i32 %C 460} 461 462define i32 @select_sdiv_icmp(i32 %x, i32 %y, i32 %z) { 463; CHECK-LABEL: @select_sdiv_icmp( 464; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 1 465; CHECK-NEXT: call void @use2(i1 [[A]]) 466; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]] 467; CHECK-NEXT: ret i32 [[C]] 468; 469 %A = icmp ne i32 %x, 1 470 call void @use2(i1 %A) ; thwart predicate canonicalization 471 %B = sdiv i32 %z, %x 472 %C = select i1 %A, i32 %y, i32 %B 473 ret i32 %C 474} 475 476; Negative tests 477define i32 @select_xor_icmp_bad_1(i32 %x, i32 %y, i32 %z, i32 %k) { 478; CHECK-LABEL: @select_xor_icmp_bad_1( 479; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], [[K:%.*]] 480; CHECK-NEXT: [[B:%.*]] = xor i32 [[X]], [[Z:%.*]] 481; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 482; CHECK-NEXT: ret i32 [[C]] 483; 484 %A = icmp eq i32 %x, %k 485 %B = xor i32 %x, %z 486 %C = select i1 %A, i32 %B, i32 %y 487 ret i32 %C 488} 489 490define i32 @select_xor_icmp_bad_2(i32 %x, i32 %y, i32 %z, i32 %k) { 491; CHECK-LABEL: @select_xor_icmp_bad_2( 492; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 493; CHECK-NEXT: [[B:%.*]] = xor i32 [[K:%.*]], [[Z:%.*]] 494; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 495; CHECK-NEXT: ret i32 [[C]] 496; 497 %A = icmp eq i32 %x, 0 498 %B = xor i32 %k, %z 499 %C = select i1 %A, i32 %B, i32 %y 500 ret i32 %C 501} 502 503define i32 @select_xor_icmp_bad_3(i32 %x, i32 %y, i32 %z) { 504; CHECK-LABEL: @select_xor_icmp_bad_3( 505; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 3 506; CHECK-NEXT: [[B:%.*]] = xor i32 [[Z:%.*]], 3 507; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 508; CHECK-NEXT: ret i32 [[C]] 509; 510 %A = icmp eq i32 %x, 3 511 %B = xor i32 %x, %z 512 %C = select i1 %A, i32 %B, i32 %y 513 ret i32 %C 514} 515 516define i32 @select_xor_fcmp_bad_4(i32 %x, i32 %y, i32 %z, float %k) { 517; CHECK-LABEL: @select_xor_fcmp_bad_4( 518; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[K:%.*]], 0.000000e+00 519; CHECK-NEXT: [[B:%.*]] = xor i32 [[X:%.*]], [[Z:%.*]] 520; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 521; CHECK-NEXT: ret i32 [[C]] 522; 523 %A = fcmp oeq float %k, 0.0 524 %B = xor i32 %x, %z 525 %C = select i1 %A, i32 %B, i32 %y 526 ret i32 %C 527} 528 529define i32 @select_xor_icmp_bad_5(i32 %x, i32 %y, i32 %z) { 530; CHECK-LABEL: @select_xor_icmp_bad_5( 531; CHECK-NEXT: [[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], 0 532; CHECK-NEXT: [[B:%.*]] = xor i32 [[X]], [[Z:%.*]] 533; CHECK-NEXT: [[C:%.*]] = select i1 [[A_NOT]], i32 [[Y:%.*]], i32 [[B]] 534; CHECK-NEXT: ret i32 [[C]] 535; 536 %A = icmp ne i32 %x, 0 537 %B = xor i32 %x, %z 538 %C = select i1 %A, i32 %B, i32 %y 539 ret i32 %C 540} 541 542define i32 @select_xor_icmp_bad_6(i32 %x, i32 %y, i32 %z) { 543; CHECK-LABEL: @select_xor_icmp_bad_6( 544; CHECK-NEXT: [[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], 1 545; CHECK-NEXT: [[B:%.*]] = xor i32 [[Z:%.*]], 1 546; CHECK-NEXT: [[C:%.*]] = select i1 [[A_NOT]], i32 [[B]], i32 [[Y:%.*]] 547; CHECK-NEXT: ret i32 [[C]] 548; 549 %A = icmp ne i32 %x, 1 550 %B = xor i32 %x, %z 551 %C = select i1 %A, i32 %y, i32 %B 552 ret i32 %C 553} 554 555; Value equivalence substitution is valid. 556 557define <2 x i8> @select_xor_icmp_vec_equivalence(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 558; CHECK-LABEL: @select_xor_icmp_vec_equivalence( 559; CHECK-NEXT: [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 5, i8 3> 560; CHECK-NEXT: [[B:%.*]] = xor <2 x i8> [[Z:%.*]], <i8 5, i8 3> 561; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[B]], <2 x i8> [[Y:%.*]] 562; CHECK-NEXT: ret <2 x i8> [[C]] 563; 564 %A = icmp eq <2 x i8> %x, <i8 5, i8 3> 565 %B = xor <2 x i8> %x, %z 566 %C = select <2 x i1> %A, <2 x i8> %B, <2 x i8> %y 567 ret <2 x i8> %C 568} 569 570; Value equivalence substitution is invalid due to lane-crossing shufflevector. 571 572define <2 x i32> @vec_select_no_equivalence(<2 x i32> %x) { 573; CHECK-LABEL: @vec_select_no_equivalence( 574; CHECK-NEXT: [[X10:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> <i32 1, i32 0> 575; CHECK-NEXT: [[COND:%.*]] = icmp eq <2 x i32> [[X]], zeroinitializer 576; CHECK-NEXT: [[S:%.*]] = select <2 x i1> [[COND]], <2 x i32> [[X10]], <2 x i32> [[X]] 577; CHECK-NEXT: ret <2 x i32> [[S]] 578; 579 %x10 = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> <i32 1, i32 0> 580 %cond = icmp eq <2 x i32> %x, zeroinitializer 581 %s = select <2 x i1> %cond, <2 x i32> %x10, <2 x i32> %x 582 ret <2 x i32> %s 583} 584 585; Folding this would only be legal if we sanitized undef to 0. 586define <2 x i8> @select_xor_icmp_vec_undef(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) { 587; CHECK-LABEL: @select_xor_icmp_vec_undef( 588; CHECK-NEXT: [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 0, i8 undef> 589; CHECK-NEXT: [[B:%.*]] = xor <2 x i8> [[X]], [[Z:%.*]] 590; CHECK-NEXT: [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[B]], <2 x i8> [[Y:%.*]] 591; CHECK-NEXT: ret <2 x i8> [[C]] 592; 593 %A = icmp eq <2 x i8> %x, <i8 0, i8 undef> 594 %B = xor <2 x i8> %x, %z 595 %C = select <2 x i1> %A, <2 x i8> %B, <2 x i8> %y 596 ret <2 x i8> %C 597} 598 599define i32 @select_mul_icmp_bad(i32 %x, i32 %y, i32 %z, i32 %k) { 600; CHECK-LABEL: @select_mul_icmp_bad( 601; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 3 602; CHECK-NEXT: [[B:%.*]] = mul i32 [[Z:%.*]], 3 603; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 604; CHECK-NEXT: ret i32 [[C]] 605; 606 %A = icmp eq i32 %x, 3 607 %B = mul i32 %x, %z 608 %C = select i1 %A, i32 %B, i32 %y 609 ret i32 %C 610} 611 612define i32 @select_add_icmp_bad(i32 %x, i32 %y, i32 %z) { 613; CHECK-LABEL: @select_add_icmp_bad( 614; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1 615; CHECK-NEXT: [[B:%.*]] = add i32 [[Z:%.*]], 1 616; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 617; CHECK-NEXT: ret i32 [[C]] 618; 619 %A = icmp eq i32 %x, 1 620 %B = add i32 %x, %z 621 %C = select i1 %A, i32 %B, i32 %y 622 ret i32 %C 623} 624 625define i32 @select_and_icmp_zero(i32 %x, i32 %y, i32 %z) { 626; CHECK-LABEL: @select_and_icmp_zero( 627; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 628; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 0, i32 [[Y:%.*]] 629; CHECK-NEXT: ret i32 [[C]] 630; 631 %A = icmp eq i32 %x, 0 632 %B = and i32 %x, %z 633 %C = select i1 %A, i32 %B, i32 %y 634 ret i32 %C 635} 636 637define i32 @select_or_icmp_bad(i32 %x, i32 %y, i32 %z) { 638; CHECK-LABEL: @select_or_icmp_bad( 639; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 3 640; CHECK-NEXT: [[B:%.*]] = or i32 [[Z:%.*]], 3 641; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 642; CHECK-NEXT: ret i32 [[C]] 643; 644 %A = icmp eq i32 %x, 3 645 %B = or i32 %x, %z 646 %C = select i1 %A, i32 %B, i32 %y 647 ret i32 %C 648} 649 650define i32 @select_lshr_icmp_const(i32 %x) { 651; CHECK-LABEL: @select_lshr_icmp_const( 652; CHECK-NEXT: [[B:%.*]] = lshr i32 [[X:%.*]], 5 653; CHECK-NEXT: ret i32 [[B]] 654; 655 %A = icmp ugt i32 %x, 31 656 %B = lshr i32 %x, 5 657 %C = select i1 %A, i32 %B, i32 0 658 ret i32 %C 659} 660 661define i32 @select_lshr_icmp_const_reordered(i32 %x) { 662; CHECK-LABEL: @select_lshr_icmp_const_reordered( 663; CHECK-NEXT: [[B:%.*]] = lshr i32 [[X:%.*]], 5 664; CHECK-NEXT: ret i32 [[B]] 665; 666 %A = icmp ult i32 %x, 32 667 %B = lshr i32 %x, 5 668 %C = select i1 %A, i32 0, i32 %B 669 ret i32 %C 670} 671 672define i32 @select_exact_lshr_icmp_const(i32 %x) { 673; CHECK-LABEL: @select_exact_lshr_icmp_const( 674; CHECK-NEXT: [[B:%.*]] = lshr i32 [[X:%.*]], 5 675; CHECK-NEXT: ret i32 [[B]] 676; 677 %A = icmp ugt i32 %x, 31 678 %B = lshr exact i32 %x, 5 679 %C = select i1 %A, i32 %B, i32 0 680 ret i32 %C 681} 682 683define i32 @select_lshr_icmp_const_large_exact_range(i32 %x) { 684; CHECK-LABEL: @select_lshr_icmp_const_large_exact_range( 685; CHECK-NEXT: [[A:%.*]] = icmp ugt i32 [[X:%.*]], 63 686; CHECK-NEXT: [[B:%.*]] = lshr i32 [[X]], 5 687; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 0 688; CHECK-NEXT: ret i32 [[C]] 689; 690 %A = icmp ugt i32 %x, 63 691 %B = lshr i32 %x, 5 692 %C = select i1 %A, i32 %B, i32 0 693 ret i32 %C 694} 695 696define i32 @select_lshr_icmp_const_different_values(i32 %x, i32 %y) { 697; CHECK-LABEL: @select_lshr_icmp_const_different_values( 698; CHECK-NEXT: [[A:%.*]] = icmp ugt i32 [[X:%.*]], 31 699; CHECK-NEXT: [[B:%.*]] = lshr i32 [[Y:%.*]], 5 700; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 0 701; CHECK-NEXT: ret i32 [[C]] 702; 703 %A = icmp ugt i32 %x, 31 704 %B = lshr i32 %y, 5 705 %C = select i1 %A, i32 %B, i32 0 706 ret i32 %C 707} 708 709define float @select_fadd_fcmp_equiv(float %x, float %y, float %z) { 710; CHECK-LABEL: @select_fadd_fcmp_equiv( 711; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], -1.000000e+00 712; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], -1.000000e+00 713; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 714; CHECK-NEXT: ret float [[C]] 715; 716 %A = fcmp oeq float %x, -1.0 717 %B = fadd nsz float %x, %z 718 %C = select i1 %A, float %B, float %y 719 ret float %C 720} 721 722define float @select_fadd_fcmp_equiv2(float %x, float %y, float %z) { 723; CHECK-LABEL: @select_fadd_fcmp_equiv2( 724; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], -1.000000e+00 725; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], -1.000000e+00 726; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]] 727; CHECK-NEXT: ret float [[C]] 728; 729 %A = fcmp une float %x, -1.0 730 %B = fadd nsz float %x, %z 731 %C = select i1 %A, float %y, float %B 732 ret float %C 733} 734 735; Invalid comparison type 736define float @select_fadd_fcmp_bad_2(float %x, float %y, float %z) { 737; CHECK-LABEL: @select_fadd_fcmp_bad_2( 738; CHECK-NEXT: [[A:%.*]] = fcmp ueq float [[X:%.*]], -1.000000e+00 739; CHECK-NEXT: [[B:%.*]] = fadd float [[X]], [[Z:%.*]] 740; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 741; CHECK-NEXT: ret float [[C]] 742; 743 %A = fcmp ueq float %x, -1.0 744 %B = fadd float %x, %z 745 %C = select i1 %A, float %B, float %y 746 ret float %C 747} 748 749; Invalid comparison type 750define float @select_fadd_fcmp_bad_3(float %x, float %y, float %z, float %k) { 751; CHECK-LABEL: @select_fadd_fcmp_bad_3( 752; CHECK-NEXT: [[A:%.*]] = fcmp one float [[X:%.*]], [[K:%.*]] 753; CHECK-NEXT: [[B:%.*]] = fadd float [[X]], [[Z:%.*]] 754; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]] 755; CHECK-NEXT: ret float [[C]] 756; 757 %A = fcmp one float %x, %k 758 %B = fadd float %x, %z 759 %C = select i1 %A, float %y, float %B 760 ret float %C 761} 762 763; Invalid order of operands of select 764define float @select_fadd_fcmp_bad_4(float %x, float %y, float %z) { 765; CHECK-LABEL: @select_fadd_fcmp_bad_4( 766; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 767; CHECK-NEXT: [[B:%.*]] = fadd float [[X]], [[Z:%.*]] 768; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 769; CHECK-NEXT: ret float [[C]] 770; 771 %A = fcmp une float %x, -0.0 772 %B = fadd float %x, %z 773 %C = select i1 %A, float %B, float %y 774 ret float %C 775} 776 777; Invalid comparison type 778define float @select_fadd_fcmp_bad_5(float %x, float %y, float %z) { 779; CHECK-LABEL: @select_fadd_fcmp_bad_5( 780; CHECK-NEXT: [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00 781; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]] 782; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]] 783; CHECK-NEXT: ret float [[C]] 784; 785 %A = fcmp one float %x, -0.0 786 %B = fadd nsz float %z, %x 787 %C = select i1 %A, float %y, float %B 788 ret float %C 789} 790 791; Invalid order of operands of select 792define float @select_fadd_fcmp_bad_6(float %x, float %y, float %z) { 793; CHECK-LABEL: @select_fadd_fcmp_bad_6( 794; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 795; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]] 796; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]] 797; CHECK-NEXT: ret float [[C]] 798; 799 %A = fcmp oeq float %x, -0.0 800 %B = fadd nsz float %z, %x 801 %C = select i1 %A, float %y, float %B 802 ret float %C 803} 804 805; Do not transform if we have signed zeros and if Z is possibly negative zero 806define float @select_fadd_fcmp_bad_7(float %x, float %y, float %z) { 807; CHECK-LABEL: @select_fadd_fcmp_bad_7( 808; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 809; CHECK-NEXT: [[B:%.*]] = fadd float [[X]], [[Z:%.*]] 810; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 811; CHECK-NEXT: ret float [[C]] 812; 813 %A = fcmp oeq float %x, -0.0 814 %B = fadd float %x, %z 815 %C = select i1 %A, float %B, float %y 816 ret float %C 817} 818 819; Invalid comparison type 820define float @select_fadd_fcmp_bad_8(float %x, float %y, float %v) { 821; CHECK-LABEL: @select_fadd_fcmp_bad_8( 822; CHECK-NEXT: [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00 823; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], -1.000000e+00 824; CHECK-NEXT: [[B:%.*]] = fadd float [[Z]], [[X]] 825; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]] 826; CHECK-NEXT: ret float [[C]] 827; 828 %A = fcmp one float %x, -0.0 829 %z = fadd float %v, -1.0 830 %B = fadd float %z, %x 831 %C = select i1 %A, float %y, float %B 832 ret float %C 833} 834 835; Invalid comparison type 836define float @select_fadd_fcmp_bad_9(float %x, float %y, float %z) { 837; CHECK-LABEL: @select_fadd_fcmp_bad_9( 838; CHECK-NEXT: [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00 839; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]] 840; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]] 841; CHECK-NEXT: ret float [[C]] 842; 843 %A = fcmp one float %x, -0.0 844 %B = fadd nsz float %z, %x 845 %C = select i1 %A, float %y, float %B 846 ret float %C 847} 848 849; Invalid comparison type 850define float @select_fadd_fcmp_bad_10(float %x, float %y, float %v) { 851; CHECK-LABEL: @select_fadd_fcmp_bad_10( 852; CHECK-NEXT: [[A:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00 853; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00 854; CHECK-NEXT: [[B:%.*]] = fadd float [[Z]], [[X]] 855; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]] 856; CHECK-NEXT: ret float [[C]] 857; 858 %A = fcmp one float %x, -0.0 859 %z = fadd float %v, 0.0 ; cannot produce -0.0 860 %B = fadd float %z, %x 861 %C = select i1 %A, float %y, float %B 862 ret float %C 863} 864 865; Do not transform if Z is possibly negative zero 866define float @select_fadd_fcmp_bad_11(float %x, float %y, float %v) { 867; CHECK-LABEL: @select_fadd_fcmp_bad_11( 868; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 869; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], -1.000000e+00 870; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]] 871; CHECK-NEXT: ret float [[C]] 872; 873 %A = fcmp une float %x, -0.0 874 %z = fadd float %v, -1.0 875 %B = fadd nsz float %z, %x 876 %C = select i1 %A, float %y, float %B 877 ret float %C 878} 879 880; Do not transform if we have signed zeros and if Z is possibly negative zero 881define float @select_fadd_fcmp_bad_12(float %x, float %y, float %z) { 882; CHECK-LABEL: @select_fadd_fcmp_bad_12( 883; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00 884; CHECK-NEXT: [[B:%.*]] = fadd float [[Z:%.*]], [[X]] 885; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]] 886; CHECK-NEXT: ret float [[C]] 887; 888 %A = fcmp une float %x, -0.0 889 %B = fadd float %z, %x 890 %C = select i1 %A, float %y, float %B 891 ret float %C 892} 893 894; Invalid order of operands of select 895define float @select_fadd_fcmp_bad_13(float %x, float %y, float %z) { 896; CHECK-LABEL: @select_fadd_fcmp_bad_13( 897; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 898; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[X]], [[Z:%.*]] 899; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]] 900; CHECK-NEXT: ret float [[C]] 901; 902 %A = fcmp oeq float %x, -0.0 903 %B = fadd nsz float %x, %z 904 %C = select i1 %A, float %y, float %B 905 ret float %C 906} 907 908define float @select_fmul_fcmp_equiv(float %x, float %y, float %z) { 909; CHECK-LABEL: @select_fmul_fcmp_equiv( 910; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 3.000000e+00 911; CHECK-NEXT: [[B:%.*]] = fmul nsz float [[Z:%.*]], 3.000000e+00 912; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 913; CHECK-NEXT: ret float [[C]] 914; 915 %A = fcmp oeq float %x, 3.0 916 %B = fmul nsz float %x, %z 917 %C = select i1 %A, float %B, float %y 918 ret float %C 919} 920 921define float @select_fmul_fcmp_equiv2(float %x, float %y, float %z) { 922; CHECK-LABEL: @select_fmul_fcmp_equiv2( 923; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00 924; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B:%.*]], float [[Y:%.*]] 925; CHECK-NEXT: ret float [[C]] 926; 927 %A = fcmp oeq float %x, 1.0 928 %B = fmul float %x, %z 929 %C = select i1 %A, float %B, float %y 930 ret float %C 931} 932 933define float @select_fmul_icmp_bad(float %x, float %y, float %z, i32 %k) { 934; CHECK-LABEL: @select_fmul_icmp_bad( 935; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[K:%.*]], 0 936; CHECK-NEXT: [[B:%.*]] = fmul float [[X:%.*]], [[Z:%.*]] 937; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 938; CHECK-NEXT: ret float [[C]] 939; 940 %A = icmp eq i32 %k, 0 941 %B = fmul float %x, %z 942 %C = select i1 %A, float %B, float %y 943 ret float %C 944} 945 946define float @select_fmul_icmp_bad_2(float %x, float %y, float %z, i32 %k) { 947; CHECK-LABEL: @select_fmul_icmp_bad_2( 948; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[K:%.*]], 0 949; CHECK-NEXT: [[B:%.*]] = fmul nsz float [[X:%.*]], [[Z:%.*]] 950; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 951; CHECK-NEXT: ret float [[C]] 952; 953 %A = icmp eq i32 %k, 0 954 %B = fmul nsz float %x, %z 955 %C = select i1 %A, float %B, float %y 956 ret float %C 957} 958 959define float @select_fdiv_fcmp_equiv(float %x, float %y, float %z) { 960; CHECK-LABEL: @select_fdiv_fcmp_equiv( 961; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00 962; CHECK-NEXT: [[B:%.*]] = fdiv float 1.000000e+00, [[Z:%.*]] 963; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 964; CHECK-NEXT: ret float [[C]] 965; 966 %A = fcmp oeq float %x, 1.0 967 %B = fdiv float %x, %z 968 %C = select i1 %A, float %B, float %y 969 ret float %C 970} 971 972define float @select_fdiv_fcmp_equiv2(float %x, float %y, float %z) { 973; CHECK-LABEL: @select_fdiv_fcmp_equiv2( 974; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 3.000000e+00 975; CHECK-NEXT: [[B:%.*]] = fdiv nsz float 3.000000e+00, [[Z:%.*]] 976; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 977; CHECK-NEXT: ret float [[C]] 978; 979 %A = fcmp oeq float %x, 3.0 980 %B = fdiv nsz float %x, %z 981 %C = select i1 %A, float %B, float %y 982 ret float %C 983} 984 985; The transform is not valid when x = -0.0 and z = -0.0 986; (optimized code would return -0.0, but this returns +0.0). 987 988define float @select_fsub_fcmp_bad(float %x, float %y, float %z) { 989; CHECK-LABEL: @select_fsub_fcmp_bad( 990; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00 991; CHECK-NEXT: [[B:%.*]] = fsub float [[Z:%.*]], [[X]] 992; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 993; CHECK-NEXT: ret float [[C]] 994; 995 %A = fcmp oeq float %x, 0.0 996 %B = fsub float %z, %x 997 %C = select i1 %A, float %B, float %y 998 ret float %C 999} 1000 1001define float @select_fsub_fcmp_equiv(float %x, float %y, float %z) { 1002; CHECK-LABEL: @select_fsub_fcmp_equiv( 1003; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 1.000000e+00 1004; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], -1.000000e+00 1005; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]] 1006; CHECK-NEXT: ret float [[C]] 1007; 1008 %A = fcmp oeq float %x, 1.0 1009 %B = fsub nsz float %z, %x 1010 %C = select i1 %A, float %B, float %y 1011 ret float %C 1012} 1013 1014define i32 @select_sub_icmp_bad(i32 %x, i32 %y, i32 %z) { 1015; CHECK-LABEL: @select_sub_icmp_bad( 1016; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 1017; CHECK-NEXT: [[B:%.*]] = sub i32 0, [[Z:%.*]] 1018; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 1019; CHECK-NEXT: ret i32 [[C]] 1020; 1021 %A = icmp eq i32 %x, 0 1022 %B = sub i32 %x, %z 1023 %C = select i1 %A, i32 %B, i32 %y 1024 ret i32 %C 1025} 1026 1027define i32 @select_sub_icmp_bad_2(i32 %x, i32 %y, i32 %z) { 1028; CHECK-LABEL: @select_sub_icmp_bad_2( 1029; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1 1030; CHECK-NEXT: [[B:%.*]] = add i32 [[Z:%.*]], -1 1031; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 1032; CHECK-NEXT: ret i32 [[C]] 1033; 1034 %A = icmp eq i32 %x, 1 1035 %B = sub i32 %z, %x 1036 %C = select i1 %A, i32 %B, i32 %y 1037 ret i32 %C 1038} 1039 1040define i32 @select_sub_icmp_bad_3(i32 %x, i32 %y, i32 %z) { 1041; CHECK-LABEL: @select_sub_icmp_bad_3( 1042; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0 1043; CHECK-NEXT: call void @use2(i1 [[A]]) 1044; CHECK-NEXT: [[B:%.*]] = sub i32 [[Z:%.*]], [[X]] 1045; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 1046; CHECK-NEXT: ret i32 [[C]] 1047; 1048 %A = icmp ne i32 %x, 0 1049 call void @use2(i1 %A) 1050 %B = sub i32 %z, %x 1051 %C = select i1 %A, i32 %B, i32 %y 1052 ret i32 %C 1053} 1054 1055define i32 @select_sub_icmp_4(i32 %x, i32 %y, i32 %z) { 1056; CHECK-LABEL: @select_sub_icmp_4( 1057; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], 0 1058; CHECK-NEXT: call void @use2(i1 [[A]]) 1059; CHECK-NEXT: [[B:%.*]] = sub i32 [[Z:%.*]], [[X]] 1060; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 1061; CHECK-NEXT: ret i32 [[C]] 1062; 1063 %A = icmp ne i32 %x, 0 1064 call void @use2(i1 %A) 1065 %B = sub i32 %z, %x 1066 %C = select i1 %A, i32 %B, i32 %y 1067 ret i32 %C 1068} 1069 1070define i32 @select_sub_icmp_bad_4(i32 %x, i32 %y, i32 %z, i32 %k) { 1071; CHECK-LABEL: @select_sub_icmp_bad_4( 1072; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 0 1073; CHECK-NEXT: [[B:%.*]] = sub i32 [[Z:%.*]], [[K:%.*]] 1074; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 1075; CHECK-NEXT: ret i32 [[C]] 1076; 1077 %A = icmp eq i32 %x, 0 1078 %B = sub i32 %z, %k 1079 %C = select i1 %A, i32 %B, i32 %y 1080 ret i32 %C 1081} 1082 1083define i32 @select_sub_icmp_bad_5(i32 %x, i32 %y, i32 %z, i32 %k) { 1084; CHECK-LABEL: @select_sub_icmp_bad_5( 1085; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], [[K:%.*]] 1086; CHECK-NEXT: [[B:%.*]] = sub i32 [[Z:%.*]], [[X]] 1087; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 1088; CHECK-NEXT: ret i32 [[C]] 1089; 1090 %A = icmp eq i32 %x, %k 1091 %B = sub i32 %z, %x 1092 %C = select i1 %A, i32 %B, i32 %y 1093 ret i32 %C 1094} 1095 1096define i32 @select_shl_icmp_bad(i32 %x, i32 %y, i32 %z) { 1097; CHECK-LABEL: @select_shl_icmp_bad( 1098; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1 1099; CHECK-NEXT: [[B:%.*]] = shl i32 [[Z:%.*]], 1 1100; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 1101; CHECK-NEXT: ret i32 [[C]] 1102; 1103 %A = icmp eq i32 %x, 1 1104 %B = shl i32 %z, %x 1105 %C = select i1 %A, i32 %B, i32 %y 1106 ret i32 %C 1107} 1108 1109define i32 @select_lshr_icmp_bad(i32 %x, i32 %y, i32 %z) { 1110; CHECK-LABEL: @select_lshr_icmp_bad( 1111; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1 1112; CHECK-NEXT: [[B:%.*]] = lshr i32 [[Z:%.*]], 1 1113; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 1114; CHECK-NEXT: ret i32 [[C]] 1115; 1116 %A = icmp eq i32 %x, 1 1117 %B = lshr i32 %z, %x 1118 %C = select i1 %A, i32 %B, i32 %y 1119 ret i32 %C 1120} 1121 1122define i32 @select_ashr_icmp_bad(i32 %x, i32 %y, i32 %z) { 1123; CHECK-LABEL: @select_ashr_icmp_bad( 1124; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 1 1125; CHECK-NEXT: [[B:%.*]] = ashr i32 [[Z:%.*]], 1 1126; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 1127; CHECK-NEXT: ret i32 [[C]] 1128; 1129 %A = icmp eq i32 %x, 1 1130 %B = ashr i32 %z, %x 1131 %C = select i1 %A, i32 %B, i32 %y 1132 ret i32 %C 1133} 1134 1135define i32 @select_udiv_icmp_bad(i32 %x, i32 %y, i32 %z) { 1136; CHECK-LABEL: @select_udiv_icmp_bad( 1137; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 3 1138; CHECK-NEXT: [[B:%.*]] = udiv i32 [[Z:%.*]], [[X]] 1139; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 1140; CHECK-NEXT: ret i32 [[C]] 1141; 1142 %A = icmp eq i32 %x, 3 1143 %B = udiv i32 %z, %x 1144 %C = select i1 %A, i32 %B, i32 %y 1145 ret i32 %C 1146} 1147 1148define i32 @select_sdiv_icmp_bad(i32 %x, i32 %y, i32 %z) { 1149; CHECK-LABEL: @select_sdiv_icmp_bad( 1150; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 3 1151; CHECK-NEXT: [[B:%.*]] = sdiv i32 [[Z:%.*]], [[X]] 1152; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]] 1153; CHECK-NEXT: ret i32 [[C]] 1154; 1155 %A = icmp eq i32 %x, 3 1156 %B = sdiv i32 %z, %x 1157 %C = select i1 %A, i32 %B, i32 %y 1158 ret i32 %C 1159} 1160 1161; Can replace %x with 0, because sub is only used in the select. 1162define i32 @select_replace_one_use(i32 %x, i32 %y) { 1163; CHECK-LABEL: @select_replace_one_use( 1164; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0 1165; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[Y:%.*]] 1166; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[SUB]], i32 [[Y]] 1167; CHECK-NEXT: ret i32 [[S]] 1168; 1169 %c = icmp eq i32 %x, 0 1170 %sub = sub i32 %x, %y 1171 %s = select i1 %c, i32 %sub, i32 %y 1172 ret i32 %s 1173} 1174 1175; Can not replace %x with 0, because %sub has other uses as well. 1176define i32 @select_replace_multi_use(i32 %x, i32 %y) { 1177; CHECK-LABEL: @select_replace_multi_use( 1178; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0 1179; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X]], [[Y:%.*]] 1180; CHECK-NEXT: call void @use_i32(i32 [[SUB]]) 1181; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[SUB]], i32 [[Y]] 1182; CHECK-NEXT: ret i32 [[S]] 1183; 1184 %c = icmp eq i32 %x, 0 1185 %sub = sub i32 %x, %y 1186 call void @use_i32(i32 %sub) 1187 %s = select i1 %c, i32 %sub, i32 %y 1188 ret i32 %s 1189} 1190 1191; Case where the replacement allows the instruction to fold away. 1192define i32 @select_replace_fold(i32 %x, i32 %y, i32 %z) { 1193; CHECK-LABEL: @select_replace_fold( 1194; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0 1195; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[Z:%.*]], i32 [[Y:%.*]] 1196; CHECK-NEXT: ret i32 [[S]] 1197; 1198 %c = icmp eq i32 %x, 0 1199 %fshr = call i32 @llvm.fshr.i32(i32 %y, i32 %z, i32 %x) 1200 %s = select i1 %c, i32 %fshr, i32 %y 1201 ret i32 %s 1202} 1203 1204 1205; Case where the use of %x is in a nested instruction. 1206define i32 @select_replace_nested(i32 %x, i32 %y, i32 %z) { 1207; CHECK-LABEL: @select_replace_nested( 1208; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0 1209; CHECK-NEXT: [[ADD:%.*]] = select i1 [[C]], i32 [[Z:%.*]], i32 0 1210; CHECK-NEXT: [[S:%.*]] = add i32 [[Y:%.*]], [[ADD]] 1211; CHECK-NEXT: ret i32 [[S]] 1212; 1213 %c = icmp eq i32 %x, 0 1214 %sub = sub i32 %y, %x 1215 %add = add i32 %sub, %z 1216 %s = select i1 %c, i32 %add, i32 %y 1217 ret i32 %s 1218} 1219 1220define i32 @select_replace_nested_extra_use(i32 %x, i32 %y, i32 %z) { 1221; CHECK-LABEL: @select_replace_nested_extra_use( 1222; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0 1223; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[Y:%.*]], [[X]] 1224; CHECK-NEXT: call void @use.i32(i32 [[SUB]]) 1225; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SUB]], [[Z:%.*]] 1226; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[ADD]], i32 [[Y]] 1227; CHECK-NEXT: ret i32 [[S]] 1228; 1229 %c = icmp eq i32 %x, 0 1230 %sub = sub i32 %y, %x 1231 call void @use.i32(i32 %sub) 1232 %add = add i32 %sub, %z 1233 %s = select i1 %c, i32 %add, i32 %y 1234 ret i32 %s 1235} 1236 1237define i32 @select_replace_nested_no_simplify(i32 %x, i32 %y, i32 %z) { 1238; CHECK-LABEL: @select_replace_nested_no_simplify( 1239; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 1 1240; CHECK-NEXT: [[SUB:%.*]] = add i32 [[Y:%.*]], -1 1241; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SUB]], [[Z:%.*]] 1242; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[ADD]], i32 [[Y]] 1243; CHECK-NEXT: ret i32 [[S]] 1244; 1245 %c = icmp eq i32 %x, 1 1246 %sub = sub i32 %y, %x 1247 %add = add i32 %sub, %z 1248 %s = select i1 %c, i32 %add, i32 %y 1249 ret i32 %s 1250} 1251 1252; FIXME: We only perform replacements two levels up right now. 1253define i32 @select_replace_deeply_nested(i32 %x, i32 %y, i32 %z) { 1254; CHECK-LABEL: @select_replace_deeply_nested( 1255; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0 1256; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[Y:%.*]], [[X]] 1257; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SUB]], [[Z:%.*]] 1258; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[ADD]], 1 1259; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[SHL]], i32 [[Y]] 1260; CHECK-NEXT: ret i32 [[S]] 1261; 1262 %c = icmp eq i32 %x, 0 1263 %sub = sub i32 %y, %x 1264 %add = add i32 %sub, %z 1265 %shl = shl i32 %add, 1 1266 %s = select i1 %c, i32 %shl, i32 %y 1267 ret i32 %s 1268} 1269 1270; Do not replace with constant expressions. The profitability in this case is 1271; unclear, and such replacements have historically lead to infinite combine 1272; loops. 1273define i32 @select_replace_constexpr(i32 %x, i32 %y, i32 %z) { 1274; CHECK-LABEL: @select_replace_constexpr( 1275; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], ptrtoint (ptr @g to i32) 1276; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X]], [[Y:%.*]] 1277; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[ADD]], i32 [[Z:%.*]] 1278; CHECK-NEXT: ret i32 [[S]] 1279; 1280 %c = icmp eq i32 %x, ptrtoint (ptr @g to i32) 1281 %add = add i32 %x, %y 1282 %s = select i1 %c, i32 %add, i32 %z 1283 ret i32 %s 1284} 1285 1286; Don't replace with a potentially undef constant, as undef could evaluate 1287; to different values for both uses. 1288define <2 x i32> @select_replace_undef(<2 x i32> %x, <2 x i32> %y) { 1289; CHECK-LABEL: @select_replace_undef( 1290; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 0, i32 undef> 1291; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i32> [[X]], [[Y:%.*]] 1292; CHECK-NEXT: [[S:%.*]] = select <2 x i1> [[C]], <2 x i32> [[SUB]], <2 x i32> [[Y]] 1293; CHECK-NEXT: ret <2 x i32> [[S]] 1294; 1295 %c = icmp eq <2 x i32> %x, <i32 0, i32 undef> 1296 %sub = sub <2 x i32> %x, %y 1297 %s = select <2 x i1> %c, <2 x i32> %sub, <2 x i32> %y 1298 ret <2 x i32> %s 1299} 1300 1301; We can replace the call arguments, as the call is speculatable. 1302define i32 @select_replace_call_speculatable(i32 %x, i32 %y) { 1303; CHECK-LABEL: @select_replace_call_speculatable( 1304; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0 1305; CHECK-NEXT: [[CALL:%.*]] = call i32 @call_speculatable(i32 0, i32 0) 1306; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[CALL]], i32 [[Y:%.*]] 1307; CHECK-NEXT: ret i32 [[S]] 1308; 1309 %c = icmp eq i32 %x, 0 1310 %call = call i32 @call_speculatable(i32 %x, i32 %x) 1311 %s = select i1 %c, i32 %call, i32 %y 1312 ret i32 %s 1313} 1314 1315define i32 @select_replace_call_speculatable_intrinsic(i32 %x, i32 %y) { 1316; CHECK-LABEL: @select_replace_call_speculatable_intrinsic( 1317; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0 1318; CHECK-NEXT: [[CALL:%.*]] = call i32 @llvm.smax.i32(i32 [[Y:%.*]], i32 0) 1319; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[CALL]], i32 [[Y]] 1320; CHECK-NEXT: ret i32 [[S]] 1321; 1322 %c = icmp eq i32 %x, 0 1323 %call = call i32 @llvm.smax.i32(i32 %x, i32 %y) 1324 %s = select i1 %c, i32 %call, i32 %y 1325 ret i32 %s 1326} 1327 1328; We can't replace the call arguments, as the call is not speculatable. We 1329; may end up changing side-effects or causing undefined behavior. 1330define i32 @select_replace_call_non_speculatable(i32 %x, i32 %y) { 1331; CHECK-LABEL: @select_replace_call_non_speculatable( 1332; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0 1333; CHECK-NEXT: [[CALL:%.*]] = call i32 @call_non_speculatable(i32 [[X]], i32 [[X]]) 1334; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[CALL]], i32 [[Y:%.*]] 1335; CHECK-NEXT: ret i32 [[S]] 1336; 1337 %c = icmp eq i32 %x, 0 1338 %call = call i32 @call_non_speculatable(i32 %x, i32 %x) 1339 %s = select i1 %c, i32 %call, i32 %y 1340 ret i32 %s 1341} 1342 1343; We can replace %x by 2 here, because division by two cannot cause UB. 1344; FIXME: As we check speculation prior to replacement, we don't catch this. 1345define i32 @select_replace_sdiv_speculatable(i32 %x, i32 %y) { 1346; CHECK-LABEL: @select_replace_sdiv_speculatable( 1347; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 2 1348; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[Y:%.*]], [[X]] 1349; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[DIV]], i32 [[Y]] 1350; CHECK-NEXT: ret i32 [[S]] 1351; 1352 %c = icmp eq i32 %x, 2 1353 %div = sdiv i32 %y, %x 1354 %s = select i1 %c, i32 %div, i32 %y 1355 ret i32 %s 1356} 1357 1358; We cannot replace %x by -1, because division by -1 can cause UB. 1359define i32 @select_replace_sdiv_non_speculatable(i32 %x, i32 %y) { 1360; CHECK-LABEL: @select_replace_sdiv_non_speculatable( 1361; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], -1 1362; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[Y:%.*]], [[X]] 1363; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[DIV]], i32 [[Y]] 1364; CHECK-NEXT: ret i32 [[S]] 1365; 1366 %c = icmp eq i32 %x, -1 1367 %div = sdiv i32 %y, %x 1368 %s = select i1 %c, i32 %div, i32 %y 1369 ret i32 %s 1370} 1371 1372; We can replace %x by 2 here, because division by two cannot cause UB. 1373; FIXME: As we check speculation prior to replacement, we don't catch this. 1374define i32 @select_replace_udiv_speculatable(i32 %x, i32 %y) { 1375; CHECK-LABEL: @select_replace_udiv_speculatable( 1376; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 2 1377; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[Y:%.*]], [[X]] 1378; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[DIV]], i32 [[Y]] 1379; CHECK-NEXT: ret i32 [[S]] 1380; 1381 %c = icmp eq i32 %x, 2 1382 %div = udiv i32 %y, %x 1383 %s = select i1 %c, i32 %div, i32 %y 1384 ret i32 %s 1385} 1386 1387; We can't replace %x by 0 here, because that would cause UB. However, 1388; replacing the udiv result by poison is fine. 1389define i32 @select_replace_udiv_non_speculatable(i32 %x, i32 %y) { 1390; CHECK-LABEL: @select_replace_udiv_non_speculatable( 1391; CHECK-NEXT: ret i32 [[Y:%.*]] 1392; 1393 %c = icmp eq i32 %x, 0 1394 %div = udiv i32 %y, %x 1395 %s = select i1 %c, i32 %div, i32 %y 1396 ret i32 %s 1397} 1398 1399; We can't replace %i in the phi node here, because it refers to %i from 1400; the previous loop iteration, not the current one. 1401define void @select_replace_phi(i32 %x) { 1402; CHECK-LABEL: @select_replace_phi( 1403; CHECK-NEXT: entry: 1404; CHECK-NEXT: br label [[LOOP:%.*]] 1405; CHECK: loop: 1406; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 1407; CHECK-NEXT: [[I_PREV:%.*]] = phi i32 [ -1, [[ENTRY]] ], [ [[I]], [[LOOP]] ] 1408; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 1409; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[I]], 0 1410; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[I_PREV]], i32 2 1411; CHECK-NEXT: call void @use_i32(i32 [[S]]) 1412; CHECK-NEXT: br label [[LOOP]] 1413; 1414entry: 1415 br label %loop 1416 1417loop: 1418 %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] 1419 %i.prev = phi i32 [ -1, %entry], [ %i, %loop ] 1420 %i.next = add i32 %i, 1 1421 %c = icmp eq i32 %i, 0 1422 %s = select i1 %c, i32 %i.prev, i32 2 1423 call void @use_i32(i32 %s) 1424 br label %loop 1425} 1426 1427@g = global i32 0 1428declare i32 @llvm.fshr.i32(i32, i32, i32) 1429declare i32 @call_speculatable(i32, i32) speculatable 1430declare i32 @call_non_speculatable(i32, i32) 1431declare void @use_i32(i32) 1432 1433!0 = !{!"branch_weights", i32 2, i32 10} 1434