; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 ; RUN: opt -passes=instcombine -S < %s | FileCheck %s define i32 @phi_freeze_same_consts(i1 %c0, i1 %c1) { ; CHECK-LABEL: define i32 @phi_freeze_same_consts( ; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: br i1 [[C0]], label %[[BB_FREEZE:.*]], label %[[BB_OTHER:.*]] ; CHECK: [[BB_FREEZE]]: ; CHECK-NEXT: br label %[[FINAL:.*]] ; CHECK: [[BB_OTHER]]: ; CHECK-NEXT: br i1 [[C1]], label %[[CA:.*]], label %[[CB:.*]] ; CHECK: [[CA]]: ; CHECK-NEXT: br label %[[FINAL]] ; CHECK: [[CB]]: ; CHECK-NEXT: br label %[[FINAL]] ; CHECK: [[FINAL]]: ; CHECK-NEXT: ret i32 42 ; entry: br i1 %c0, label %bb_freeze, label %bb_other bb_freeze: %f = freeze i32 undef br label %final bb_other: br i1 %c1, label %cA, label %cB cA: br label %final cB: br label %final final: %phi = phi i32 [ %f, %bb_freeze ], [ 42, %cA ], [ 42, %cB ] ret i32 %phi } define i32 @phi_freeze_mixed_consts(i1 %c0, i1 %c1) { ; CHECK-LABEL: define i32 @phi_freeze_mixed_consts( ; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: br i1 [[C0]], label %[[BB_FREEZE:.*]], label %[[BB_OTHER:.*]] ; CHECK: [[BB_FREEZE]]: ; CHECK-NEXT: br label %[[FINAL:.*]] ; CHECK: [[BB_OTHER]]: ; CHECK-NEXT: br i1 [[C1]], label %[[CA:.*]], label %[[CB:.*]] ; CHECK: [[CA]]: ; CHECK-NEXT: br label %[[FINAL]] ; CHECK: [[CB]]: ; CHECK-NEXT: br label %[[FINAL]] ; CHECK: [[FINAL]]: ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, %[[BB_FREEZE]] ], [ 42, %[[CA]] ], [ 7, %[[CB]] ] ; CHECK-NEXT: ret i32 [[PHI]] ; entry: br i1 %c0, label %bb_freeze, label %bb_other bb_freeze: %f = freeze i32 undef br label %final bb_other: br i1 %c1, label %cA, label %cB cA: br label %final cB: br label %final final: %phi = phi i32 [ %f, %bb_freeze ], [ 42, %cA ], [ 7, %cB ] ret i32 %phi } define i32 @phi_freeze_with_nonconst_incoming(i32 %x, i1 %c0, i1 %c1) { ; CHECK-LABEL: define i32 @phi_freeze_with_nonconst_incoming( ; CHECK-SAME: i32 [[X:%.*]], i1 [[C0:%.*]], i1 [[C1:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: br i1 [[C0]], label %[[BB_FREEZE:.*]], label %[[BB_OTHER:.*]] ; CHECK: [[BB_FREEZE]]: ; CHECK-NEXT: br label %[[FINAL:.*]] ; CHECK: [[BB_OTHER]]: ; CHECK-NEXT: br i1 [[C1]], label %[[CA:.*]], label %[[CB:.*]] ; CHECK: [[CA]]: ; CHECK-NEXT: br label %[[FINAL]] ; CHECK: [[CB]]: ; CHECK-NEXT: br label %[[FINAL]] ; CHECK: [[FINAL]]: ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, %[[BB_FREEZE]] ], [ [[X]], %[[CA]] ], [ 13, %[[CB]] ] ; CHECK-NEXT: ret i32 [[PHI]] ; entry: br i1 %c0, label %bb_freeze, label %bb_other bb_freeze: %f = freeze i32 undef br label %final bb_other: br i1 %c1, label %cA, label %cB cA: br label %final cB: br label %final final: %phi = phi i32 [ %f, %bb_freeze ], [ %x, %cA ], [ 13, %cB ] ret i32 %phi } define <4 x i8> @phi_freeze_vector(i1 %c0, i1 %c1) { ; CHECK-LABEL: define <4 x i8> @phi_freeze_vector( ; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: br i1 [[C0]], label %[[BB_FREEZE:.*]], label %[[BB_OTHER:.*]] ; CHECK: [[BB_FREEZE]]: ; CHECK-NEXT: br label %[[FINAL:.*]] ; CHECK: [[BB_OTHER]]: ; CHECK-NEXT: br i1 [[C1]], label %[[CA:.*]], label %[[CB:.*]] ; CHECK: [[CA]]: ; CHECK-NEXT: br label %[[FINAL]] ; CHECK: [[CB]]: ; CHECK-NEXT: br label %[[FINAL]] ; CHECK: [[FINAL]]: ; CHECK-NEXT: ret <4 x i8> splat (i8 9) ; entry: br i1 %c0, label %bb_freeze, label %bb_other bb_freeze: %f = freeze <4 x i8> undef br label %final bb_other: br i1 %c1, label %cA, label %cB cA: br label %final cB: br label %final final: %phi = phi <4 x i8> [ %f, %bb_freeze ], [, %cA ], [, %cB ] ret <4 x i8> %phi } define i32 @multi_use_one_folds_one_not_zero(i1 %c0, i1 %c1, i1 %c2) { ; CHECK-LABEL: define i32 @multi_use_one_folds_one_not_zero( ; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: br i1 [[C0]], label %[[BB_OTHER3:.*]], label %[[CC1:.*]] ; CHECK: [[BB_OTHER3]]: ; CHECK-NEXT: br label %[[MID:.*]] ; CHECK: [[CC1]]: ; CHECK-NEXT: br i1 [[C1]], label %[[CA:.*]], label %[[CB:.*]] ; CHECK: [[CA]]: ; CHECK-NEXT: br label %[[MID]] ; CHECK: [[CB]]: ; CHECK-NEXT: br label %[[MID]] ; CHECK: [[MID]]: ; CHECK-NEXT: [[PHI_FOLD:%.*]] = phi i32 [ 0, %[[BB_OTHER3]] ], [ 1, %[[CA]] ], [ 1, %[[CB]] ] ; CHECK-NEXT: br i1 [[C2]], label %[[BB_FREEZE2:.*]], label %[[CD:.*]] ; CHECK: [[BB_FREEZE2]]: ; CHECK-NEXT: br label %[[FINAL:.*]] ; CHECK: [[BB_OTHER2:.*:]] ; CHECK-NEXT: br i1 true, label %[[CA]], label %[[CB]] ; CHECK: [[CC:.*:]] ; CHECK-NEXT: br label %[[FINAL]] ; CHECK: [[CD]]: ; CHECK-NEXT: br label %[[FINAL]] ; CHECK: [[FINAL]]: ; CHECK-NEXT: ret i32 [[PHI_FOLD]] ; entry: %f = freeze i32 undef br i1 %c0, label %bb_freeze, label %bb_other bb_freeze: br label %mid bb_other: br i1 %c1, label %cA, label %cB cA: br label %mid cB: br label %mid mid: %phi_no_fold = phi i32 [ %f, %bb_freeze ], [ 1, %cA ], [ 1, %cB ] br i1 %c2, label %bb_freeze2, label %cD bb_freeze2: br label %final bb_other2: br i1 %c1, label %cA, label %cB cC: br label %final cD: br label %final final: %phi_fold = phi i32 [ %f, %bb_freeze2 ], [ 0, %cC ], [ 0, %cD ] %a = add i32 %phi_fold, %phi_no_fold ret i32 %a } define i32 @phi_freeze_poison(i1 %c0, i1 %c1) { ; CHECK-LABEL: define i32 @phi_freeze_poison( ; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: br i1 [[C0]], label %[[BB_FREEZE:.*]], label %[[BB_OTHER:.*]] ; CHECK: [[BB_FREEZE]]: ; CHECK-NEXT: br label %[[FINAL:.*]] ; CHECK: [[BB_OTHER]]: ; CHECK-NEXT: br i1 [[C1]], label %[[CA:.*]], label %[[CB:.*]] ; CHECK: [[CA]]: ; CHECK-NEXT: br label %[[FINAL]] ; CHECK: [[CB]]: ; CHECK-NEXT: br label %[[FINAL]] ; CHECK: [[FINAL]]: ; CHECK-NEXT: ret i32 0 ; entry: br i1 %c0, label %bb_freeze, label %bb_other bb_freeze: %f = freeze i32 undef br label %final bb_other: br i1 %c1, label %cA, label %cB cA: br label %final cB: br label %final final: %phi = phi i32 [ %f, %bb_freeze ], [ poison, %cA ], [ poison, %cB ] ret i32 %phi } define <2 x i32> @phi_freeze_poison_vec(i1 %c0, i1 %c1) { ; CHECK-LABEL: define <2 x i32> @phi_freeze_poison_vec( ; CHECK-SAME: i1 [[C0:%.*]], i1 [[C1:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: br i1 [[C0]], label %[[BB_FREEZE:.*]], label %[[BB_OTHER:.*]] ; CHECK: [[BB_FREEZE]]: ; CHECK-NEXT: br label %[[FINAL:.*]] ; CHECK: [[BB_OTHER]]: ; CHECK-NEXT: br i1 [[C1]], label %[[CA:.*]], label %[[CB:.*]] ; CHECK: [[CA]]: ; CHECK-NEXT: br label %[[FINAL]] ; CHECK: [[CB]]: ; CHECK-NEXT: br label %[[FINAL]] ; CHECK: [[FINAL]]: ; CHECK-NEXT: [[PHI:%.*]] = phi <2 x i32> [ zeroinitializer, %[[BB_FREEZE]] ], [ , %[[CA]] ], [ , %[[CB]] ] ; CHECK-NEXT: ret <2 x i32> [[PHI]] ; entry: br i1 %c0, label %bb_freeze, label %bb_other bb_freeze: %f = freeze <2 x i32> undef br label %final bb_other: br i1 %c1, label %cA, label %cB cA: br label %final cB: br label %final final: %phi = phi <2 x i32> [ %f, %bb_freeze ], [ , %cA ], [ , %cB ] ret <2 x i32> %phi }