assert(BI->isConditional() && "Must be a conditional branch");
BasicBlock *TrueSucc = BI->getSuccessor(0);
BasicBlock *FalseSucc = BI->getSuccessor(1);
+ if (TrueSucc == FalseSucc)
+ return false;
// NOTE: destinations may match, this could be degenerate uncond branch.
ReturnInst *TrueRet = cast<ReturnInst>(TrueSucc->getTerminator());
ReturnInst *FalseRet = cast<ReturnInst>(FalseSucc->getTerminator());
FalseSucc->removePredecessor(BB);
Builder.CreateRetVoid();
EraseTerminatorAndDCECond(BI);
- if (DTU) {
- SmallVector<DominatorTree::UpdateType, 2> Updates;
- Updates.push_back({DominatorTree::Delete, BB, TrueSucc});
- if (TrueSucc != FalseSucc)
- Updates.push_back({DominatorTree::Delete, BB, FalseSucc});
- DTU->applyUpdates(Updates);
- }
+ if (DTU)
+ DTU->applyUpdates({{DominatorTree::Delete, BB, TrueSucc},
+ {DominatorTree::Delete, BB, FalseSucc}});
return true;
}
<< *TrueSucc << "\nFALSEBLOCK: " << *FalseSucc);
EraseTerminatorAndDCECond(BI);
- if (DTU) {
- SmallVector<DominatorTree::UpdateType, 2> Updates;
- Updates.push_back({DominatorTree::Delete, BB, TrueSucc});
- if (TrueSucc != FalseSucc)
- Updates.push_back({DominatorTree::Delete, BB, FalseSucc});
- DTU->applyUpdates(Updates);
- }
+ if (DTU)
+ DTU->applyUpdates({{DominatorTree::Delete, BB, TrueSucc},
+ {DominatorTree::Delete, BB, FalseSucc}});
return true;
}
define i32 @pmat(i32 %m, i32 %n, double* %y) nounwind {
; CHECK-LABEL: @pmat(
; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[M:%.*]], 0
; CHECK-NEXT: ret i32 0
;
entry:
; CHECK: bb0:
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: call void @foo()
-; CHECK-NEXT: br label [[BB3:%.*]]
+; CHECK-NEXT: br label [[BB6:%.*]]
; CHECK: entry.split.nonchr:
; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP0]], 1
; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[TMP3]], 0
; CHECK: bb1.nonchr:
; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP0]], 2
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 0
-; CHECK-NEXT: br i1 [[TMP5]], label [[BB3]], label [[BB2_NONCHR:%.*]], !prof [[PROF16]]
+; CHECK-NEXT: br i1 [[TMP5]], label [[BB6]], label [[BB2_NONCHR:%.*]], !prof [[PROF16]]
; CHECK: bb2.nonchr:
; CHECK-NEXT: call void @foo()
-; CHECK-NEXT: br label [[BB3]]
-; CHECK: bb3:
+; CHECK-NEXT: br label [[BB6]]
+; CHECK: bb6:
; CHECK-NEXT: ret void
;
entry:
; CHECK-NEXT: [[TMP0:%.*]] = fcmp olt <4 x float> [[T_FR]], zeroinitializer
; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i1> [[TMP0]] to i4
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i4 [[TMP1]], -1
-; CHECK-NEXT: br i1 [[TMP2]], label [[COMMON_RET:%.*]], label [[LOR_LHS_FALSE:%.*]]
-; CHECK: common.ret:
-; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi float [ [[SPEC_SELECT:%.*]], [[LOR_LHS_FALSE]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]
-; CHECK-NEXT: ret float [[COMMON_RET_OP]]
+; CHECK-NEXT: br i1 [[TMP2]], label [[RETURN:%.*]], label [[LOR_LHS_FALSE:%.*]]
; CHECK: lor.lhs.false:
; CHECK-NEXT: [[T_FR6:%.*]] = freeze <4 x float> [[T]]
; CHECK-NEXT: [[TMP3:%.*]] = fcmp ogt <4 x float> [[T_FR6]], <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>
; CHECK-NEXT: [[SHIFT:%.*]] = shufflevector <4 x float> [[T]], <4 x float> poison, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
; CHECK-NEXT: [[TMP6:%.*]] = fadd <4 x float> [[SHIFT]], [[T]]
; CHECK-NEXT: [[ADD:%.*]] = extractelement <4 x float> [[TMP6]], i32 0
-; CHECK-NEXT: [[SPEC_SELECT]] = select i1 [[TMP5]], float 0.000000e+00, float [[ADD]]
-; CHECK-NEXT: br label [[COMMON_RET]]
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TMP5]], float 0.000000e+00, float [[ADD]]
+; CHECK-NEXT: br label [[RETURN]]
+; CHECK: return:
+; CHECK-NEXT: [[RETVAL_0:%.*]] = phi float [ 0.000000e+00, [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[LOR_LHS_FALSE]] ]
+; CHECK-NEXT: ret float [[RETVAL_0]]
;
entry:
%vecext = extractelement <4 x float> %t, i32 0
; CHECK-NEXT: [[TMP0:%.*]] = fcmp olt <4 x float> [[T_FR]], zeroinitializer
; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i1> [[TMP0]] to i4
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i4 [[TMP1]], -1
-; CHECK-NEXT: br i1 [[TMP2]], label [[COMMON_RET:%.*]], label [[IF_END:%.*]]
-; CHECK: common.ret:
-; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi float [ [[SPEC_SELECT:%.*]], [[IF_END]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]
-; CHECK-NEXT: ret float [[COMMON_RET_OP]]
+; CHECK-NEXT: br i1 [[TMP2]], label [[RETURN:%.*]], label [[IF_END:%.*]]
; CHECK: if.end:
; CHECK-NEXT: [[T_FR6:%.*]] = freeze <4 x float> [[T]]
; CHECK-NEXT: [[TMP3:%.*]] = fcmp ogt <4 x float> [[T_FR6]], <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>
; CHECK-NEXT: [[SHIFT:%.*]] = shufflevector <4 x float> [[T]], <4 x float> poison, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
; CHECK-NEXT: [[TMP6:%.*]] = fadd <4 x float> [[SHIFT]], [[T]]
; CHECK-NEXT: [[ADD:%.*]] = extractelement <4 x float> [[TMP6]], i32 0
-; CHECK-NEXT: [[SPEC_SELECT]] = select i1 [[TMP5]], float 0.000000e+00, float [[ADD]]
-; CHECK-NEXT: br label [[COMMON_RET]]
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TMP5]], float 0.000000e+00, float [[ADD]]
+; CHECK-NEXT: br label [[RETURN]]
+; CHECK: return:
+; CHECK-NEXT: [[RETVAL_0:%.*]] = phi float [ 0.000000e+00, [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[IF_END]] ]
+; CHECK-NEXT: ret float [[RETVAL_0]]
;
entry:
%vecext = extractelement <4 x float> %t, i32 0
; CHECK-NEXT: [[TMP0:%.*]] = icmp slt <4 x i32> [[T_FR]], <i32 1, i32 1, i32 1, i32 1>
; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i1> [[TMP0]] to i4
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i4 [[TMP1]], -1
-; CHECK-NEXT: br i1 [[TMP2]], label [[COMMON_RET:%.*]], label [[IF_END:%.*]]
-; CHECK: common.ret:
-; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[SPEC_SELECT:%.*]], [[IF_END]] ], [ 0, [[ENTRY:%.*]] ]
-; CHECK-NEXT: ret i32 [[COMMON_RET_OP]]
+; CHECK-NEXT: br i1 [[TMP2]], label [[RETURN:%.*]], label [[IF_END:%.*]]
; CHECK: if.end:
; CHECK-NEXT: [[T_FR6:%.*]] = freeze <4 x i32> [[T]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt <4 x i32> [[T_FR6]], <i32 255, i32 255, i32 255, i32 255>
; CHECK-NEXT: [[SHIFT:%.*]] = shufflevector <4 x i32> [[T]], <4 x i32> poison, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
; CHECK-NEXT: [[TMP6:%.*]] = add nsw <4 x i32> [[SHIFT]], [[T]]
; CHECK-NEXT: [[ADD:%.*]] = extractelement <4 x i32> [[TMP6]], i32 0
-; CHECK-NEXT: [[SPEC_SELECT]] = select i1 [[TMP5]], i32 0, i32 [[ADD]]
-; CHECK-NEXT: br label [[COMMON_RET]]
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TMP5]], i32 0, i32 [[ADD]]
+; CHECK-NEXT: br label [[RETURN]]
+; CHECK: return:
+; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[IF_END]] ]
+; CHECK-NEXT: ret i32 [[RETVAL_0]]
;
entry:
%vecext = extractelement <4 x i32> %t, i32 0
; CHECK-NEXT: [[TMP0:%.*]] = icmp slt <4 x i32> [[T_FR]], <i32 1, i32 1, i32 1, i32 1>
; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i1> [[TMP0]] to i4
; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i4 [[TMP1]], 0
-; CHECK-NEXT: br i1 [[DOTNOT]], label [[IF_END:%.*]], label [[COMMON_RET:%.*]]
-; CHECK: common.ret:
-; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[SPEC_SELECT:%.*]], [[IF_END]] ], [ 0, [[ENTRY:%.*]] ]
-; CHECK-NEXT: ret i32 [[COMMON_RET_OP]]
+; CHECK-NEXT: br i1 [[DOTNOT]], label [[IF_END:%.*]], label [[RETURN:%.*]]
; CHECK: if.end:
; CHECK-NEXT: [[T_FR6:%.*]] = freeze <4 x i32> [[T]]
; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt <4 x i32> [[T_FR6]], <i32 255, i32 255, i32 255, i32 255>
; CHECK-NEXT: [[SHIFT:%.*]] = shufflevector <4 x i32> [[T]], <4 x i32> poison, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
; CHECK-NEXT: [[TMP4:%.*]] = add nuw nsw <4 x i32> [[SHIFT]], [[T]]
; CHECK-NEXT: [[ADD:%.*]] = extractelement <4 x i32> [[TMP4]], i32 0
-; CHECK-NEXT: [[SPEC_SELECT]] = select i1 [[DOTNOT7]], i32 [[ADD]], i32 0
-; CHECK-NEXT: br label [[COMMON_RET]]
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[DOTNOT7]], i32 [[ADD]], i32 0
+; CHECK-NEXT: br label [[RETURN]]
+; CHECK: return:
+; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[IF_END]] ]
+; CHECK-NEXT: ret i32 [[RETVAL_0]]
;
entry:
%vecext = extractelement <4 x i32> %t, i32 0
; CHECK-NEXT: [[CMP:%.*]] = fcmp olt double [[DIV]], 0x3EB0C6F7A0B5ED8D
; CHECK-NEXT: [[CMP4:%.*]] = fcmp olt double [[DIV3]], 0x3EB0C6F7A0B5ED8D
; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[CMP]], i1 [[CMP4]], i1 false
-; CHECK-NEXT: br i1 [[OR_COND]], label [[COMMON_RET:%.*]], label [[LOR_LHS_FALSE:%.*]]
-; CHECK: common.ret:
-; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i1 [ [[OR_COND1:%.*]], [[LOR_LHS_FALSE]] ], [ false, [[ENTRY:%.*]] ]
-; CHECK-NEXT: ret i1 [[COMMON_RET_OP]]
+; CHECK-NEXT: br i1 [[OR_COND]], label [[CLEANUP:%.*]], label [[LOR_LHS_FALSE:%.*]]
; CHECK: lor.lhs.false:
; CHECK-NEXT: [[CMP5:%.*]] = fcmp ule double [[DIV]], 1.000000e+00
; CHECK-NEXT: [[CMP7:%.*]] = fcmp ule double [[DIV3]], 1.000000e+00
-; CHECK-NEXT: [[OR_COND1]] = select i1 [[CMP5]], i1 true, i1 [[CMP7]]
-; CHECK-NEXT: br label [[COMMON_RET]]
+; CHECK-NEXT: [[OR_COND1:%.*]] = select i1 [[CMP5]], i1 true, i1 [[CMP7]]
+; CHECK-NEXT: br label [[CLEANUP]]
+; CHECK: cleanup:
+; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[OR_COND1]], [[LOR_LHS_FALSE]] ]
+; CHECK-NEXT: ret i1 [[RETVAL_0]]
;
entry:
%fneg = fneg double %b
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0
; CHECK-NEXT: br i1 [[TOBOOL]], label [[EXIT:%.*]], label [[BLOCK1:%.*]]
; CHECK: block1:
-; CHECK-NEXT: ret i32* null
+; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
-; CHECK-NEXT: ret i32* select (i1 icmp eq (i64 urem (i64 2, i64 zext (i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a) to i64)), i64 0), i32* null, i32* @a)
+; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32* [ select (i1 icmp eq (i64 urem (i64 2, i64 zext (i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a) to i64)), i64 0), i32* null, i32* @a), [[ENTRY:%.*]] ], [ null, [[BLOCK1]] ]
+; CHECK-NEXT: ret i32* [[STOREMERGE]]
;
entry:
%0 = load i32, i32* @a, align 4
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0
-; CHECK-NEXT: br i1 [[TOBOOL]], label [[EXIT:%.*]], label [[BLOCK1:%.*]]
-; CHECK: block1:
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a), i32* select (i1 icmp eq (i64 add (i64 zext (i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a) to i64), i64 2), i64 0), i32* null, i32* @a), i32* null
-; CHECK-NEXT: ret i32* [[SPEC_SELECT]]
-; CHECK: exit:
-; CHECK-NEXT: ret i32* null
+; CHECK-NEXT: [[STOREMERGE:%.*]] = select i1 [[TOBOOL]], i32* null, i32* [[SPEC_SELECT]]
+; CHECK-NEXT: ret i32* [[STOREMERGE]]
;
entry:
%0 = load i32, i32* @a, align 4
; CHECK-LABEL: @test5(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[T1:%.*]] = icmp eq i32 [[B:%.*]], 0
-; CHECK-NEXT: br i1 [[T1]], label [[BB1:%.*]], label [[BB3:%.*]]
-; CHECK: bb1:
; CHECK-NEXT: [[T2:%.*]] = icmp sgt i32 [[C:%.*]], 1
; CHECK-NEXT: [[T3:%.*]] = load i32*, i32** [[PTR3:%.*]], align 8
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[T2]], i32* [[T3]], i32* [[PTR2:%.*]]
-; CHECK-NEXT: ret i32* [[SPEC_SELECT]]
-; CHECK: bb3:
-; CHECK-NEXT: ret i32* [[PTR1:%.*]]
+; CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32* [[SPEC_SELECT]], i32* [[PTR1:%.*]]
+; CHECK-NEXT: ret i32* [[T4]]
;
entry:
%t1 = icmp eq i32 %b, 0
; CHECK-NEXT: br i1 [[BRMERGE]], label [[EXIT:%.*]], label [[CMP1_TRUE:%.*]]
; CHECK: cmp1_true:
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[CMP2]], i1 [[CMP3]], i1 false
-; CHECK-NEXT: ret i1 [[SPEC_SELECT]]
+; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
-; CHECK-NEXT: ret i1 false
+; CHECK-NEXT: [[R:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[CMP1_TRUE]] ]
+; CHECK-NEXT: ret i1 [[R]]
;
entry:
%cmp = icmp eq <4 x i32> %a, %b
; NODUPRET-NEXT: entry:
; NODUPRET-NEXT: call void @sideeffect0()
; NODUPRET-NEXT: br i1 [[C0:%.*]], label [[T:%.*]], label [[F:%.*]]
+; NODUPRET: end:
+; NODUPRET-NEXT: [[R:%.*]] = phi i32 [ [[V2:%.*]], [[F]] ], [ [[SPEC_SELECT:%.*]], [[T]] ]
+; NODUPRET-NEXT: ret i32 [[R]]
; NODUPRET: T:
; NODUPRET-NEXT: call void @sideeffect1()
-; NODUPRET-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[C1:%.*]], i32 [[V0:%.*]], i32 [[V1:%.*]]
-; NODUPRET-NEXT: ret i32 [[SPEC_SELECT]]
+; NODUPRET-NEXT: [[SPEC_SELECT]] = select i1 [[C1:%.*]], i32 [[V0:%.*]], i32 [[V1:%.*]]
+; NODUPRET-NEXT: br label [[END:%.*]]
; NODUPRET: F:
; NODUPRET-NEXT: call void @sideeffect2()
-; NODUPRET-NEXT: ret i32 [[V2:%.*]]
+; NODUPRET-NEXT: br label [[END]]
;
; DUPRET-LABEL: @test3(
; DUPRET-NEXT: entry:
; DBGINFO-NEXT: entry:
; DBGINFO-NEXT: call void @sideeffect0(), !dbg [[DBG21:![0-9]+]]
; DBGINFO-NEXT: br i1 [[C0:%.*]], label [[T:%.*]], label [[F:%.*]], !dbg [[DBG22:![0-9]+]]
+; DBGINFO: end:
+; DBGINFO-NEXT: [[R:%.*]] = phi i32 [ [[V2:%.*]], [[F]] ], [ [[SPEC_SELECT:%.*]], [[T]] ], !dbg [[DBG23:![0-9]+]]
+; DBGINFO-NEXT: call void @llvm.dbg.value(metadata i32 [[R]], metadata [[META20:![0-9]+]], metadata !DIExpression()), !dbg [[DBG23]]
+; DBGINFO-NEXT: ret i32 [[R]], !dbg [[DBG24:![0-9]+]]
; DBGINFO: T:
-; DBGINFO-NEXT: call void @sideeffect1(), !dbg [[DBG23:![0-9]+]]
-; DBGINFO-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[C1:%.*]], i32 [[V0:%.*]], i32 [[V1:%.*]], !dbg [[DBG24:![0-9]+]]
-; DBGINFO-NEXT: ret i32 [[SPEC_SELECT]], !dbg [[DBG24]]
+; DBGINFO-NEXT: call void @sideeffect1(), !dbg [[DBG25:![0-9]+]]
+; DBGINFO-NEXT: [[SPEC_SELECT]] = select i1 [[C1:%.*]], i32 [[V0:%.*]], i32 [[V1:%.*]], !dbg [[DBG26:![0-9]+]]
+; DBGINFO-NEXT: br label [[END:%.*]], !dbg [[DBG26]]
; DBGINFO: F:
-; DBGINFO-NEXT: call void @sideeffect2(), !dbg [[DBG25:![0-9]+]]
-; DBGINFO-NEXT: call void @llvm.dbg.value(metadata i32 [[V2:%.*]], metadata [[META20:![0-9]+]], metadata !DIExpression()), !dbg [[DBG26:![0-9]+]]
-; DBGINFO-NEXT: ret i32 [[V2]], !dbg [[DBG27:![0-9]+]]
+; DBGINFO-NEXT: call void @sideeffect2(), !dbg [[DBG27:![0-9]+]]
+; DBGINFO-NEXT: br label [[END]], !dbg [[DBG28:![0-9]+]]
;
entry:
call void @sideeffect0()