1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; RUN: opt -passes=instcombine -S < %s | FileCheck %s 3 4declare void @dummy() 5 6declare i32 @llvm.smax.i32(i32 %a, i32 %b) 7declare i32 @llvm.smin.i32(i32 %a, i32 %b) 8declare i32 @llvm.umax.i32(i32 %a, i32 %b) 9declare i32 @llvm.umin.i32(i32 %a, i32 %b) 10declare float @llvm.maxnum.f32(float %a, float %b) 11declare float @llvm.minnum.f32(float %a, float %b) 12declare float @llvm.maximum.f32(float %a, float %b) 13declare float @llvm.minimum.f32(float %a, float %b) 14declare float @llvm.pow.f32(float %a, float %b) 15 16define i8 @fold_phi_mul(i1 %c, i8 %a, i8 %b) { 17; CHECK-LABEL: define i8 @fold_phi_mul( 18; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { 19; CHECK-NEXT: entry: 20; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 21; CHECK: then: 22; CHECK-NEXT: call void @dummy() 23; CHECK-NEXT: br label [[END]] 24; CHECK: end: 25; CHECK-NEXT: [[RET:%.*]] = mul i8 [[A]], [[B]] 26; CHECK-NEXT: ret i8 [[RET]] 27; 28entry: 29 br i1 %c, label %then, label %end 30then: 31 call void @dummy() 32 br label %end 33end: 34 %phi1 = phi i8 [%a, %entry], [%b, %then] 35 %phi2 = phi i8 [%b, %entry], [%a, %then] 36 %ret = mul i8 %phi1, %phi2 37 ret i8 %ret 38} 39 40define i8 @fold_phi_mul_three(i1 %c, i1 %d, i8 %a, i8 %b) { 41; CHECK-LABEL: define i8 @fold_phi_mul_three( 42; CHECK-SAME: i1 [[C:%.*]], i1 [[D:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { 43; CHECK-NEXT: entry: 44; CHECK-NEXT: br i1 [[C]], label [[THEN1:%.*]], label [[END:%.*]] 45; CHECK: then1: 46; CHECK-NEXT: call void @dummy() 47; CHECK-NEXT: br i1 [[D]], label [[THEN2:%.*]], label [[END]] 48; CHECK: then2: 49; CHECK-NEXT: call void @dummy() 50; CHECK-NEXT: br label [[END]] 51; CHECK: end: 52; CHECK-NEXT: [[RET:%.*]] = mul i8 [[A]], [[B]] 53; CHECK-NEXT: ret i8 [[RET]] 54; 55entry: 56 br i1 %c, label %then1, label %end 57then1: 58 call void @dummy() 59 br i1 %d, label %then2, label %end 60then2: 61 call void @dummy() 62 br label %end 63end: 64 %phi1 = phi i8 [%a, %entry], [%b, %then1], [%a, %then2] 65 %phi2 = phi i8 [%b, %entry], [%a, %then1], [%b, %then2] 66 %ret = mul i8 %phi1, %phi2 67 ret i8 %ret 68} 69 70define i8 @fold_phi_mul_three_notopt(i1 %c, i1 %d, i8 %a, i8 %b) { 71; CHECK-LABEL: define i8 @fold_phi_mul_three_notopt( 72; CHECK-SAME: i1 [[C:%.*]], i1 [[D:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { 73; CHECK-NEXT: entry: 74; CHECK-NEXT: br i1 [[C]], label [[THEN1:%.*]], label [[END:%.*]] 75; CHECK: then1: 76; CHECK-NEXT: call void @dummy() 77; CHECK-NEXT: br i1 [[D]], label [[THEN2:%.*]], label [[END]] 78; CHECK: then2: 79; CHECK-NEXT: call void @dummy() 80; CHECK-NEXT: br label [[END]] 81; CHECK: end: 82; CHECK-NEXT: [[PHI1:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[THEN1]] ], [ [[A]], [[THEN2]] ] 83; CHECK-NEXT: [[PHI2:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[A]], [[THEN1]] ], [ [[A]], [[THEN2]] ] 84; CHECK-NEXT: [[RET:%.*]] = mul i8 [[PHI1]], [[PHI2]] 85; CHECK-NEXT: ret i8 [[RET]] 86; 87entry: 88 br i1 %c, label %then1, label %end 89then1: 90 call void @dummy() 91 br i1 %d, label %then2, label %end 92then2: 93 call void @dummy() 94 br label %end 95end: 96 %phi1 = phi i8 [%a, %entry], [%b, %then1], [%a, %then2] 97 %phi2 = phi i8 [%b, %entry], [%a, %then1], [%a, %then2] 98 %ret = mul i8 %phi1, %phi2 99 ret i8 %ret 100} 101 102define i8 @fold_phi_mul_nsw_nuw(i1 %c, i8 %a, i8 %b) { 103; CHECK-LABEL: define i8 @fold_phi_mul_nsw_nuw( 104; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { 105; CHECK-NEXT: entry: 106; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 107; CHECK: then: 108; CHECK-NEXT: call void @dummy() 109; CHECK-NEXT: br label [[END]] 110; CHECK: end: 111; CHECK-NEXT: [[RET:%.*]] = mul nuw nsw i8 [[A]], [[B]] 112; CHECK-NEXT: ret i8 [[RET]] 113; 114entry: 115 br i1 %c, label %then, label %end 116then: 117 call void @dummy() 118 br label %end 119end: 120 %phi1 = phi i8 [%a, %entry], [%b, %then] 121 %phi2 = phi i8 [%b, %entry], [%a, %then] 122 %ret = mul nsw nuw i8 %phi1, %phi2 123 ret i8 %ret 124} 125 126define <2 x i8> @fold_phi_mul_fix_vec(i1 %c, <2 x i8> %a, <2 x i8> %b) { 127; CHECK-LABEL: define <2 x i8> @fold_phi_mul_fix_vec( 128; CHECK-SAME: i1 [[C:%.*]], <2 x i8> [[A:%.*]], <2 x i8> [[B:%.*]]) { 129; CHECK-NEXT: entry: 130; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 131; CHECK: then: 132; CHECK-NEXT: call void @dummy() 133; CHECK-NEXT: br label [[END]] 134; CHECK: end: 135; CHECK-NEXT: [[RET:%.*]] = mul <2 x i8> [[A]], [[B]] 136; CHECK-NEXT: ret <2 x i8> [[RET]] 137; 138entry: 139 br i1 %c, label %then, label %end 140then: 141 call void @dummy() 142 br label %end 143end: 144 %phi1 = phi <2 x i8> [%a, %entry], [%b, %then] 145 %phi2 = phi <2 x i8> [%b, %entry], [%a, %then] 146 %ret = mul <2 x i8> %phi1, %phi2 147 ret <2 x i8> %ret 148} 149 150define <vscale x 2 x i8> @fold_phi_mul_scale_vec(i1 %c, <vscale x 2 x i8> %a, <vscale x 2 x i8> %b) { 151; CHECK-LABEL: define <vscale x 2 x i8> @fold_phi_mul_scale_vec( 152; CHECK-SAME: i1 [[C:%.*]], <vscale x 2 x i8> [[A:%.*]], <vscale x 2 x i8> [[B:%.*]]) { 153; CHECK-NEXT: entry: 154; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 155; CHECK: then: 156; CHECK-NEXT: call void @dummy() 157; CHECK-NEXT: br label [[END]] 158; CHECK: end: 159; CHECK-NEXT: [[RET:%.*]] = mul <vscale x 2 x i8> [[A]], [[B]] 160; CHECK-NEXT: ret <vscale x 2 x i8> [[RET]] 161; 162entry: 163 br i1 %c, label %then, label %end 164then: 165 call void @dummy() 166 br label %end 167end: 168 %phi1 = phi <vscale x 2 x i8> [%a, %entry], [%b, %then] 169 %phi2 = phi <vscale x 2 x i8> [%b, %entry], [%a, %then] 170 %ret = mul <vscale x 2 x i8> %phi1, %phi2 171 ret <vscale x 2 x i8> %ret 172} 173 174define i8 @fold_phi_mul_commute(i1 %c, i8 %a, i8 %b) { 175; CHECK-LABEL: define i8 @fold_phi_mul_commute( 176; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { 177; CHECK-NEXT: entry: 178; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 179; CHECK: then: 180; CHECK-NEXT: call void @dummy() 181; CHECK-NEXT: br label [[END]] 182; CHECK: end: 183; CHECK-NEXT: [[RET:%.*]] = mul i8 [[A]], [[B]] 184; CHECK-NEXT: ret i8 [[RET]] 185; 186entry: 187 br i1 %c, label %then, label %end 188then: 189 call void @dummy() 190 br label %end 191end: 192 %phi1 = phi i8 [%a, %entry], [%b, %then] 193 %phi2 = phi i8 [%a, %then], [%b, %entry] 194 %ret = mul i8 %phi1, %phi2 195 ret i8 %ret 196} 197 198 199define i8 @fold_phi_mul_notopt(i1 %c, i8 %a, i8 %b, i8 %d) { 200; CHECK-LABEL: define i8 @fold_phi_mul_notopt( 201; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]], i8 [[D:%.*]]) { 202; CHECK-NEXT: entry: 203; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 204; CHECK: then: 205; CHECK-NEXT: call void @dummy() 206; CHECK-NEXT: br label [[END]] 207; CHECK: end: 208; CHECK-NEXT: [[PHI1:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[THEN]] ] 209; CHECK-NEXT: [[PHI2:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[D]], [[THEN]] ] 210; CHECK-NEXT: [[RET:%.*]] = mul i8 [[PHI1]], [[PHI2]] 211; CHECK-NEXT: ret i8 [[RET]] 212; 213entry: 214 br i1 %c, label %then, label %end 215then: 216 call void @dummy() 217 br label %end 218end: 219 %phi1 = phi i8 [%a, %entry], [%b, %then] 220 %phi2 = phi i8 [%b, %entry], [%d, %then] 221 %ret = mul i8 %phi1, %phi2 222 ret i8 %ret 223} 224 225 226define i8 @fold_phi_sub(i1 %c, i8 %a, i8 %b) { 227; CHECK-LABEL: define i8 @fold_phi_sub( 228; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { 229; CHECK-NEXT: entry: 230; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 231; CHECK: then: 232; CHECK-NEXT: call void @dummy() 233; CHECK-NEXT: br label [[END]] 234; CHECK: end: 235; CHECK-NEXT: [[PHI1:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[THEN]] ] 236; CHECK-NEXT: [[PHI2:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[A]], [[THEN]] ] 237; CHECK-NEXT: [[RET:%.*]] = sub i8 [[PHI1]], [[PHI2]] 238; CHECK-NEXT: ret i8 [[RET]] 239; 240entry: 241 br i1 %c, label %then, label %end 242then: 243 call void @dummy() 244 br label %end 245end: 246 %phi1 = phi i8 [%a, %entry], [%b, %then] 247 %phi2 = phi i8 [%b, %entry], [%a, %then] 248 %ret = sub i8 %phi1, %phi2 249 ret i8 %ret 250} 251 252 253define i8 @fold_phi_add(i1 %c, i8 %a, i8 %b) { 254; CHECK-LABEL: define i8 @fold_phi_add( 255; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { 256; CHECK-NEXT: entry: 257; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 258; CHECK: then: 259; CHECK-NEXT: call void @dummy() 260; CHECK-NEXT: br label [[END]] 261; CHECK: end: 262; CHECK-NEXT: [[RET:%.*]] = add i8 [[A]], [[B]] 263; CHECK-NEXT: ret i8 [[RET]] 264; 265entry: 266 br i1 %c, label %then, label %end 267then: 268 call void @dummy() 269 br label %end 270end: 271 %phi1 = phi i8 [%a, %entry], [%b, %then] 272 %phi2 = phi i8 [%b, %entry], [%a, %then] 273 %ret = add i8 %phi1, %phi2 274 ret i8 %ret 275} 276 277define i8 @fold_phi_and(i1 %c, i8 %a, i8 %b) { 278; CHECK-LABEL: define i8 @fold_phi_and( 279; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { 280; CHECK-NEXT: entry: 281; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 282; CHECK: then: 283; CHECK-NEXT: call void @dummy() 284; CHECK-NEXT: br label [[END]] 285; CHECK: end: 286; CHECK-NEXT: [[RET:%.*]] = and i8 [[A]], [[B]] 287; CHECK-NEXT: ret i8 [[RET]] 288; 289entry: 290 br i1 %c, label %then, label %end 291then: 292 call void @dummy() 293 br label %end 294end: 295 %phi1 = phi i8 [%a, %entry], [%b, %then] 296 %phi2 = phi i8 [%b, %entry], [%a, %then] 297 %ret = and i8 %phi1, %phi2 298 ret i8 %ret 299} 300 301define i8 @fold_phi_or(i1 %c, i8 %a, i8 %b) { 302; CHECK-LABEL: define i8 @fold_phi_or( 303; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { 304; CHECK-NEXT: entry: 305; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 306; CHECK: then: 307; CHECK-NEXT: call void @dummy() 308; CHECK-NEXT: br label [[END]] 309; CHECK: end: 310; CHECK-NEXT: [[RET:%.*]] = or i8 [[A]], [[B]] 311; CHECK-NEXT: ret i8 [[RET]] 312; 313entry: 314 br i1 %c, label %then, label %end 315then: 316 call void @dummy() 317 br label %end 318end: 319 %phi1 = phi i8 [%a, %entry], [%b, %then] 320 %phi2 = phi i8 [%b, %entry], [%a, %then] 321 %ret = or i8 %phi1, %phi2 322 ret i8 %ret 323} 324 325 326define i8 @fold_phi_xor(i1 %c, i8 %a, i8 %b) { 327; CHECK-LABEL: define i8 @fold_phi_xor( 328; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { 329; CHECK-NEXT: entry: 330; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 331; CHECK: then: 332; CHECK-NEXT: call void @dummy() 333; CHECK-NEXT: br label [[END]] 334; CHECK: end: 335; CHECK-NEXT: [[RET:%.*]] = xor i8 [[A]], [[B]] 336; CHECK-NEXT: ret i8 [[RET]] 337; 338entry: 339 br i1 %c, label %then, label %end 340then: 341 call void @dummy() 342 br label %end 343end: 344 %phi1 = phi i8 [%a, %entry], [%b, %then] 345 %phi2 = phi i8 [%b, %entry], [%a, %then] 346 %ret = xor i8 %phi1, %phi2 347 ret i8 %ret 348} 349 350 351define float @fold_phi_fadd(i1 %c, float %a, float %b) { 352; CHECK-LABEL: define float @fold_phi_fadd( 353; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { 354; CHECK-NEXT: entry: 355; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 356; CHECK: then: 357; CHECK-NEXT: call void @dummy() 358; CHECK-NEXT: br label [[END]] 359; CHECK: end: 360; CHECK-NEXT: [[RET:%.*]] = fadd float [[A]], [[B]] 361; CHECK-NEXT: ret float [[RET]] 362; 363entry: 364 br i1 %c, label %then, label %end 365then: 366 call void @dummy() 367 br label %end 368end: 369 %phi1 = phi float [%a, %entry], [%b, %then] 370 %phi2 = phi float [%b, %entry], [%a, %then] 371 %ret = fadd float %phi1, %phi2 372 ret float %ret 373} 374 375define float @fold_phi_fadd_nnan(i1 %c, float %a, float %b) { 376; CHECK-LABEL: define float @fold_phi_fadd_nnan( 377; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { 378; CHECK-NEXT: entry: 379; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 380; CHECK: then: 381; CHECK-NEXT: call void @dummy() 382; CHECK-NEXT: br label [[END]] 383; CHECK: end: 384; CHECK-NEXT: [[RET:%.*]] = fadd nnan float [[A]], [[B]] 385; CHECK-NEXT: ret float [[RET]] 386; 387entry: 388 br i1 %c, label %then, label %end 389then: 390 call void @dummy() 391 br label %end 392end: 393 %phi1 = phi float [%a, %entry], [%b, %then] 394 %phi2 = phi float [%b, %entry], [%a, %then] 395 %ret = fadd nnan float %phi1, %phi2 396 ret float %ret 397} 398 399 400define float @fold_phi_fmul(i1 %c, float %a, float %b) { 401; CHECK-LABEL: define float @fold_phi_fmul( 402; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { 403; CHECK-NEXT: entry: 404; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 405; CHECK: then: 406; CHECK-NEXT: call void @dummy() 407; CHECK-NEXT: br label [[END]] 408; CHECK: end: 409; CHECK-NEXT: [[RET:%.*]] = fmul float [[A]], [[B]] 410; CHECK-NEXT: ret float [[RET]] 411; 412entry: 413 br i1 %c, label %then, label %end 414then: 415 call void @dummy() 416 br label %end 417end: 418 %phi1 = phi float [%a, %entry], [%b, %then] 419 %phi2 = phi float [%b, %entry], [%a, %then] 420 %ret = fmul float %phi1, %phi2 421 ret float %ret 422} 423 424 425define i32 @fold_phi_smax(i1 %c, i32 %a, i32 %b) { 426; CHECK-LABEL: define i32 @fold_phi_smax( 427; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { 428; CHECK-NEXT: entry: 429; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 430; CHECK: then: 431; CHECK-NEXT: call void @dummy() 432; CHECK-NEXT: br label [[END]] 433; CHECK: end: 434; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.smax.i32(i32 [[A]], i32 [[B]]) 435; CHECK-NEXT: ret i32 [[RET]] 436; 437entry: 438 br i1 %c, label %then, label %end 439then: 440 call void @dummy() 441 br label %end 442end: 443 %phi1 = phi i32 [%a, %entry], [%b, %then] 444 %phi2 = phi i32 [%b, %entry], [%a, %then] 445 %ret = call i32 @llvm.smax.i32(i32 %phi1, i32 %phi2) 446 ret i32 %ret 447} 448 449 450define i32 @fold_phi_smin(i1 %c, i32 %a, i32 %b) { 451; CHECK-LABEL: define i32 @fold_phi_smin( 452; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { 453; CHECK-NEXT: entry: 454; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 455; CHECK: then: 456; CHECK-NEXT: call void @dummy() 457; CHECK-NEXT: br label [[END]] 458; CHECK: end: 459; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.smin.i32(i32 [[A]], i32 [[B]]) 460; CHECK-NEXT: ret i32 [[RET]] 461; 462entry: 463 br i1 %c, label %then, label %end 464then: 465 call void @dummy() 466 br label %end 467end: 468 %phi1 = phi i32 [%a, %entry], [%b, %then] 469 %phi2 = phi i32 [%b, %entry], [%a, %then] 470 %ret = call i32 @llvm.smin.i32(i32 %phi1, i32 %phi2) 471 ret i32 %ret 472} 473 474 475define i32 @fold_phi_umax(i1 %c, i32 %a, i32 %b) { 476; CHECK-LABEL: define i32 @fold_phi_umax( 477; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { 478; CHECK-NEXT: entry: 479; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 480; CHECK: then: 481; CHECK-NEXT: call void @dummy() 482; CHECK-NEXT: br label [[END]] 483; CHECK: end: 484; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.umax.i32(i32 [[A]], i32 [[B]]) 485; CHECK-NEXT: ret i32 [[RET]] 486; 487entry: 488 br i1 %c, label %then, label %end 489then: 490 call void @dummy() 491 br label %end 492end: 493 %phi1 = phi i32 [%a, %entry], [%b, %then] 494 %phi2 = phi i32 [%b, %entry], [%a, %then] 495 %ret = call i32 @llvm.umax.i32(i32 %phi1, i32 %phi2) 496 ret i32 %ret 497} 498 499define i32 @fold_phi_umin(i1 %c, i32 %a, i32 %b) { 500; CHECK-LABEL: define i32 @fold_phi_umin( 501; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { 502; CHECK-NEXT: entry: 503; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 504; CHECK: then: 505; CHECK-NEXT: call void @dummy() 506; CHECK-NEXT: br label [[END]] 507; CHECK: end: 508; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.umin.i32(i32 [[A]], i32 [[B]]) 509; CHECK-NEXT: ret i32 [[RET]] 510; 511entry: 512 br i1 %c, label %then, label %end 513then: 514 call void @dummy() 515 br label %end 516end: 517 %phi1 = phi i32 [%a, %entry], [%b, %then] 518 %phi2 = phi i32 [%b, %entry], [%a, %then] 519 %ret = call i32 @llvm.umin.i32(i32 %phi1, i32 %phi2) 520 ret i32 %ret 521} 522 523 524define float @fold_phi_maxnum(i1 %c, float %a, float %b) { 525; CHECK-LABEL: define float @fold_phi_maxnum( 526; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { 527; CHECK-NEXT: entry: 528; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 529; CHECK: then: 530; CHECK-NEXT: call void @dummy() 531; CHECK-NEXT: br label [[END]] 532; CHECK: end: 533; CHECK-NEXT: [[RET:%.*]] = call float @llvm.maxnum.f32(float [[A]], float [[B]]) 534; CHECK-NEXT: ret float [[RET]] 535; 536entry: 537 br i1 %c, label %then, label %end 538then: 539 call void @dummy() 540 br label %end 541end: 542 %phi1 = phi float [%a, %entry], [%b, %then] 543 %phi2 = phi float [%b, %entry], [%a, %then] 544 %ret = call float @llvm.maxnum.f32(float %phi1, float %phi2) 545 ret float %ret 546} 547 548define float @fold_phi_pow(i1 %c, float %a, float %b) { 549; CHECK-LABEL: define float @fold_phi_pow( 550; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { 551; CHECK-NEXT: entry: 552; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 553; CHECK: then: 554; CHECK-NEXT: call void @dummy() 555; CHECK-NEXT: br label [[END]] 556; CHECK: end: 557; CHECK-NEXT: [[PHI1:%.*]] = phi float [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[THEN]] ] 558; CHECK-NEXT: [[PHI2:%.*]] = phi float [ [[B]], [[ENTRY]] ], [ [[A]], [[THEN]] ] 559; CHECK-NEXT: [[RET:%.*]] = call float @llvm.pow.f32(float [[PHI1]], float [[PHI2]]) 560; CHECK-NEXT: ret float [[RET]] 561; 562entry: 563 br i1 %c, label %then, label %end 564then: 565 call void @dummy() 566 br label %end 567end: 568 %phi1 = phi float [%a, %entry], [%b, %then] 569 %phi2 = phi float [%b, %entry], [%a, %then] 570 %ret = call float @llvm.pow.f32(float %phi1, float %phi2) 571 ret float %ret 572} 573 574define float @fold_phi_minnum(i1 %c, float %a, float %b) { 575; CHECK-LABEL: define float @fold_phi_minnum( 576; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { 577; CHECK-NEXT: entry: 578; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 579; CHECK: then: 580; CHECK-NEXT: call void @dummy() 581; CHECK-NEXT: br label [[END]] 582; CHECK: end: 583; CHECK-NEXT: [[RET:%.*]] = call float @llvm.minnum.f32(float [[A]], float [[B]]) 584; CHECK-NEXT: ret float [[RET]] 585; 586entry: 587 br i1 %c, label %then, label %end 588then: 589 call void @dummy() 590 br label %end 591end: 592 %phi1 = phi float [%a, %entry], [%b, %then] 593 %phi2 = phi float [%b, %entry], [%a, %then] 594 %ret = call float @llvm.minnum.f32(float %phi1, float %phi2) 595 ret float %ret 596} 597 598define float @fold_phi_maximum(i1 %c, float %a, float %b) { 599; CHECK-LABEL: define float @fold_phi_maximum( 600; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { 601; CHECK-NEXT: entry: 602; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 603; CHECK: then: 604; CHECK-NEXT: call void @dummy() 605; CHECK-NEXT: br label [[END]] 606; CHECK: end: 607; CHECK-NEXT: [[RET:%.*]] = call float @llvm.maximum.f32(float [[A]], float [[B]]) 608; CHECK-NEXT: ret float [[RET]] 609; 610entry: 611 br i1 %c, label %then, label %end 612then: 613 call void @dummy() 614 br label %end 615end: 616 %phi1 = phi float [%a, %entry], [%b, %then] 617 %phi2 = phi float [%b, %entry], [%a, %then] 618 %ret = call float @llvm.maximum.f32(float %phi1, float %phi2) 619 ret float %ret 620} 621 622define float @fold_phi_minimum(i1 %c, float %a, float %b) { 623; CHECK-LABEL: define float @fold_phi_minimum( 624; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { 625; CHECK-NEXT: entry: 626; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] 627; CHECK: then: 628; CHECK-NEXT: call void @dummy() 629; CHECK-NEXT: br label [[END]] 630; CHECK: end: 631; CHECK-NEXT: [[RET:%.*]] = call float @llvm.minimum.f32(float [[A]], float [[B]]) 632; CHECK-NEXT: ret float [[RET]] 633; 634entry: 635 br i1 %c, label %then, label %end 636then: 637 call void @dummy() 638 br label %end 639end: 640 %phi1 = phi float [%a, %entry], [%b, %then] 641 %phi2 = phi float [%b, %entry], [%a, %then] 642 %ret = call float @llvm.minimum.f32(float %phi1, float %phi2) 643 ret float %ret 644} 645 646