; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 ; RUN: opt -passes=instcombine -S < %s | FileCheck %s declare void @dummy() declare i32 @llvm.smax.i32(i32 %a, i32 %b) declare i32 @llvm.smin.i32(i32 %a, i32 %b) declare i32 @llvm.umax.i32(i32 %a, i32 %b) declare i32 @llvm.umin.i32(i32 %a, i32 %b) declare float @llvm.maxnum.f32(float %a, float %b) declare float @llvm.minnum.f32(float %a, float %b) declare float @llvm.maximum.f32(float %a, float %b) declare float @llvm.minimum.f32(float %a, float %b) declare float @llvm.pow.f32(float %a, float %b) define i8 @fold_phi_mul(i1 %c, i8 %a, i8 %b) { ; CHECK-LABEL: define i8 @fold_phi_mul( ; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = mul i8 [[A]], [[B]] ; CHECK-NEXT: ret i8 [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi i8 [%a, %entry], [%b, %then] %phi2 = phi i8 [%b, %entry], [%a, %then] %ret = mul i8 %phi1, %phi2 ret i8 %ret } define i8 @fold_phi_mul_three(i1 %c, i1 %d, i8 %a, i8 %b) { ; CHECK-LABEL: define i8 @fold_phi_mul_three( ; CHECK-SAME: i1 [[C:%.*]], i1 [[D:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN1:%.*]], label [[END:%.*]] ; CHECK: then1: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br i1 [[D]], label [[THEN2:%.*]], label [[END]] ; CHECK: then2: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = mul i8 [[A]], [[B]] ; CHECK-NEXT: ret i8 [[RET]] ; entry: br i1 %c, label %then1, label %end then1: call void @dummy() br i1 %d, label %then2, label %end then2: call void @dummy() br label %end end: %phi1 = phi i8 [%a, %entry], [%b, %then1], [%a, %then2] %phi2 = phi i8 [%b, %entry], [%a, %then1], [%b, %then2] %ret = mul i8 %phi1, %phi2 ret i8 %ret } define i8 @fold_phi_mul_three_notopt(i1 %c, i1 %d, i8 %a, i8 %b) { ; CHECK-LABEL: define i8 @fold_phi_mul_three_notopt( ; CHECK-SAME: i1 [[C:%.*]], i1 [[D:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN1:%.*]], label [[END:%.*]] ; CHECK: then1: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br i1 [[D]], label [[THEN2:%.*]], label [[END]] ; CHECK: then2: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[PHI1:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[THEN1]] ], [ [[A]], [[THEN2]] ] ; CHECK-NEXT: [[PHI2:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[A]], [[THEN1]] ], [ [[A]], [[THEN2]] ] ; CHECK-NEXT: [[RET:%.*]] = mul i8 [[PHI1]], [[PHI2]] ; CHECK-NEXT: ret i8 [[RET]] ; entry: br i1 %c, label %then1, label %end then1: call void @dummy() br i1 %d, label %then2, label %end then2: call void @dummy() br label %end end: %phi1 = phi i8 [%a, %entry], [%b, %then1], [%a, %then2] %phi2 = phi i8 [%b, %entry], [%a, %then1], [%a, %then2] %ret = mul i8 %phi1, %phi2 ret i8 %ret } define i8 @fold_phi_mul_nsw_nuw(i1 %c, i8 %a, i8 %b) { ; CHECK-LABEL: define i8 @fold_phi_mul_nsw_nuw( ; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = mul nuw nsw i8 [[A]], [[B]] ; CHECK-NEXT: ret i8 [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi i8 [%a, %entry], [%b, %then] %phi2 = phi i8 [%b, %entry], [%a, %then] %ret = mul nsw nuw i8 %phi1, %phi2 ret i8 %ret } define <2 x i8> @fold_phi_mul_fix_vec(i1 %c, <2 x i8> %a, <2 x i8> %b) { ; CHECK-LABEL: define <2 x i8> @fold_phi_mul_fix_vec( ; CHECK-SAME: i1 [[C:%.*]], <2 x i8> [[A:%.*]], <2 x i8> [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = mul <2 x i8> [[A]], [[B]] ; CHECK-NEXT: ret <2 x i8> [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi <2 x i8> [%a, %entry], [%b, %then] %phi2 = phi <2 x i8> [%b, %entry], [%a, %then] %ret = mul <2 x i8> %phi1, %phi2 ret <2 x i8> %ret } define @fold_phi_mul_scale_vec(i1 %c, %a, %b) { ; CHECK-LABEL: define @fold_phi_mul_scale_vec( ; CHECK-SAME: i1 [[C:%.*]], [[A:%.*]], [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = mul [[A]], [[B]] ; CHECK-NEXT: ret [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi [%a, %entry], [%b, %then] %phi2 = phi [%b, %entry], [%a, %then] %ret = mul %phi1, %phi2 ret %ret } define i8 @fold_phi_mul_commute(i1 %c, i8 %a, i8 %b) { ; CHECK-LABEL: define i8 @fold_phi_mul_commute( ; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = mul i8 [[A]], [[B]] ; CHECK-NEXT: ret i8 [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi i8 [%a, %entry], [%b, %then] %phi2 = phi i8 [%a, %then], [%b, %entry] %ret = mul i8 %phi1, %phi2 ret i8 %ret } define i8 @fold_phi_mul_notopt(i1 %c, i8 %a, i8 %b, i8 %d) { ; CHECK-LABEL: define i8 @fold_phi_mul_notopt( ; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]], i8 [[D:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[PHI1:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[THEN]] ] ; CHECK-NEXT: [[PHI2:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[D]], [[THEN]] ] ; CHECK-NEXT: [[RET:%.*]] = mul i8 [[PHI1]], [[PHI2]] ; CHECK-NEXT: ret i8 [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi i8 [%a, %entry], [%b, %then] %phi2 = phi i8 [%b, %entry], [%d, %then] %ret = mul i8 %phi1, %phi2 ret i8 %ret } define i8 @fold_phi_sub(i1 %c, i8 %a, i8 %b) { ; CHECK-LABEL: define i8 @fold_phi_sub( ; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[PHI1:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[THEN]] ] ; CHECK-NEXT: [[PHI2:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[A]], [[THEN]] ] ; CHECK-NEXT: [[RET:%.*]] = sub i8 [[PHI1]], [[PHI2]] ; CHECK-NEXT: ret i8 [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi i8 [%a, %entry], [%b, %then] %phi2 = phi i8 [%b, %entry], [%a, %then] %ret = sub i8 %phi1, %phi2 ret i8 %ret } define i8 @fold_phi_add(i1 %c, i8 %a, i8 %b) { ; CHECK-LABEL: define i8 @fold_phi_add( ; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = add i8 [[A]], [[B]] ; CHECK-NEXT: ret i8 [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi i8 [%a, %entry], [%b, %then] %phi2 = phi i8 [%b, %entry], [%a, %then] %ret = add i8 %phi1, %phi2 ret i8 %ret } define i8 @fold_phi_and(i1 %c, i8 %a, i8 %b) { ; CHECK-LABEL: define i8 @fold_phi_and( ; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = and i8 [[A]], [[B]] ; CHECK-NEXT: ret i8 [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi i8 [%a, %entry], [%b, %then] %phi2 = phi i8 [%b, %entry], [%a, %then] %ret = and i8 %phi1, %phi2 ret i8 %ret } define i8 @fold_phi_or(i1 %c, i8 %a, i8 %b) { ; CHECK-LABEL: define i8 @fold_phi_or( ; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = or i8 [[A]], [[B]] ; CHECK-NEXT: ret i8 [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi i8 [%a, %entry], [%b, %then] %phi2 = phi i8 [%b, %entry], [%a, %then] %ret = or i8 %phi1, %phi2 ret i8 %ret } define i8 @fold_phi_xor(i1 %c, i8 %a, i8 %b) { ; CHECK-LABEL: define i8 @fold_phi_xor( ; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = xor i8 [[A]], [[B]] ; CHECK-NEXT: ret i8 [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi i8 [%a, %entry], [%b, %then] %phi2 = phi i8 [%b, %entry], [%a, %then] %ret = xor i8 %phi1, %phi2 ret i8 %ret } define float @fold_phi_fadd(i1 %c, float %a, float %b) { ; CHECK-LABEL: define float @fold_phi_fadd( ; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = fadd float [[A]], [[B]] ; CHECK-NEXT: ret float [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi float [%a, %entry], [%b, %then] %phi2 = phi float [%b, %entry], [%a, %then] %ret = fadd float %phi1, %phi2 ret float %ret } define float @fold_phi_fadd_nnan(i1 %c, float %a, float %b) { ; CHECK-LABEL: define float @fold_phi_fadd_nnan( ; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = fadd nnan float [[A]], [[B]] ; CHECK-NEXT: ret float [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi float [%a, %entry], [%b, %then] %phi2 = phi float [%b, %entry], [%a, %then] %ret = fadd nnan float %phi1, %phi2 ret float %ret } define float @fold_phi_fmul(i1 %c, float %a, float %b) { ; CHECK-LABEL: define float @fold_phi_fmul( ; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = fmul float [[A]], [[B]] ; CHECK-NEXT: ret float [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi float [%a, %entry], [%b, %then] %phi2 = phi float [%b, %entry], [%a, %then] %ret = fmul float %phi1, %phi2 ret float %ret } define i32 @fold_phi_smax(i1 %c, i32 %a, i32 %b) { ; CHECK-LABEL: define i32 @fold_phi_smax( ; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.smax.i32(i32 [[A]], i32 [[B]]) ; CHECK-NEXT: ret i32 [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi i32 [%a, %entry], [%b, %then] %phi2 = phi i32 [%b, %entry], [%a, %then] %ret = call i32 @llvm.smax.i32(i32 %phi1, i32 %phi2) ret i32 %ret } define i32 @fold_phi_smin(i1 %c, i32 %a, i32 %b) { ; CHECK-LABEL: define i32 @fold_phi_smin( ; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.smin.i32(i32 [[A]], i32 [[B]]) ; CHECK-NEXT: ret i32 [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi i32 [%a, %entry], [%b, %then] %phi2 = phi i32 [%b, %entry], [%a, %then] %ret = call i32 @llvm.smin.i32(i32 %phi1, i32 %phi2) ret i32 %ret } define i32 @fold_phi_umax(i1 %c, i32 %a, i32 %b) { ; CHECK-LABEL: define i32 @fold_phi_umax( ; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.umax.i32(i32 [[A]], i32 [[B]]) ; CHECK-NEXT: ret i32 [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi i32 [%a, %entry], [%b, %then] %phi2 = phi i32 [%b, %entry], [%a, %then] %ret = call i32 @llvm.umax.i32(i32 %phi1, i32 %phi2) ret i32 %ret } define i32 @fold_phi_umin(i1 %c, i32 %a, i32 %b) { ; CHECK-LABEL: define i32 @fold_phi_umin( ; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.umin.i32(i32 [[A]], i32 [[B]]) ; CHECK-NEXT: ret i32 [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi i32 [%a, %entry], [%b, %then] %phi2 = phi i32 [%b, %entry], [%a, %then] %ret = call i32 @llvm.umin.i32(i32 %phi1, i32 %phi2) ret i32 %ret } define float @fold_phi_maxnum(i1 %c, float %a, float %b) { ; CHECK-LABEL: define float @fold_phi_maxnum( ; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.maxnum.f32(float [[A]], float [[B]]) ; CHECK-NEXT: ret float [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi float [%a, %entry], [%b, %then] %phi2 = phi float [%b, %entry], [%a, %then] %ret = call float @llvm.maxnum.f32(float %phi1, float %phi2) ret float %ret } define float @fold_phi_pow(i1 %c, float %a, float %b) { ; CHECK-LABEL: define float @fold_phi_pow( ; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[PHI1:%.*]] = phi float [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[THEN]] ] ; CHECK-NEXT: [[PHI2:%.*]] = phi float [ [[B]], [[ENTRY]] ], [ [[A]], [[THEN]] ] ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.pow.f32(float [[PHI1]], float [[PHI2]]) ; CHECK-NEXT: ret float [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi float [%a, %entry], [%b, %then] %phi2 = phi float [%b, %entry], [%a, %then] %ret = call float @llvm.pow.f32(float %phi1, float %phi2) ret float %ret } define float @fold_phi_minnum(i1 %c, float %a, float %b) { ; CHECK-LABEL: define float @fold_phi_minnum( ; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.minnum.f32(float [[A]], float [[B]]) ; CHECK-NEXT: ret float [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi float [%a, %entry], [%b, %then] %phi2 = phi float [%b, %entry], [%a, %then] %ret = call float @llvm.minnum.f32(float %phi1, float %phi2) ret float %ret } define float @fold_phi_maximum(i1 %c, float %a, float %b) { ; CHECK-LABEL: define float @fold_phi_maximum( ; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.maximum.f32(float [[A]], float [[B]]) ; CHECK-NEXT: ret float [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi float [%a, %entry], [%b, %then] %phi2 = phi float [%b, %entry], [%a, %then] %ret = call float @llvm.maximum.f32(float %phi1, float %phi2) ret float %ret } define float @fold_phi_minimum(i1 %c, float %a, float %b) { ; CHECK-LABEL: define float @fold_phi_minimum( ; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] ; CHECK: then: ; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.minimum.f32(float [[A]], float [[B]]) ; CHECK-NEXT: ret float [[RET]] ; entry: br i1 %c, label %then, label %end then: call void @dummy() br label %end end: %phi1 = phi float [%a, %entry], [%b, %then] %phi2 = phi float [%b, %entry], [%a, %then] %ret = call float @llvm.minimum.f32(float %phi1, float %phi2) ret float %ret }