Index: lib/Transforms/Utils/SimplifyCFG.cpp =================================================================== --- lib/Transforms/Utils/SimplifyCFG.cpp +++ lib/Transforms/Utils/SimplifyCFG.cpp @@ -1680,8 +1680,10 @@ // SmallVector UnconditionalPreds; Instruction *Cond = nullptr; + unsigned num_of_preds = 0; for (auto *B : predecessors(BBEnd)) { auto *T = B->getTerminator(); + ++num_of_preds; if (isa(T) && cast(T)->isUnconditional()) UnconditionalPreds.push_back(B); else if ((isa(T) || isa(T)) && !Cond) @@ -1689,9 +1691,11 @@ else return false; } + if (UnconditionalPreds.size() < 2) return false; + unsigned NumOfConditionsPreds = num_of_preds - UnconditionalPreds.size(); bool Changed = false; // We take a two-step approach to tail sinking. First we scan from the end of // each block upwards in lockstep. If the n'th instruction from the end of each @@ -1711,6 +1715,36 @@ --LRI; } + auto CountNumberOfMovesForPHIOperands = [&](LockstepReverseIterator &LRI) { + unsigned NumOfMovesForPHIdOperands = 0; + while (LRI.isValid()) { + for (auto *I : *LRI) { + for (auto *V : PHIOperands[I]) { + // If the phi operand is a constant, we are likely to have a move + // instruction. + if (InstructionsToSink.count(V) == 0 && isa(V)) + ++NumOfMovesForPHIdOperands; + } + } + --LRI; + } + return NumOfMovesForPHIdOperands; + }; + + // If the number of moves is greater than the number of reuced instructions + // (which is InstructionsToSink.size() / 2), we bail out. + // Do this only for BBend that has two unconditional predecessors and one + // conditional predecessors. If there is only unconditional predecessors, + // there is chance to use select and generate code with using moves. + LRI.reset(); + unsigned NumOfMoves = CountNumberOfMovesForPHIOperands(LRI); + if (InstructionsToSink.size() > 0 && NumOfConditionsPreds == 1 && + NumOfMoves >= InstructionsToSink.size() / 2) { + DEBUG(dbgs() << "SINK: stopping, too many move instructions (" << NumOfMoves + << ") need to be inserted.\n"); + return false; + } + auto ProfitableToSinkInstruction = [&](LockstepReverseIterator &LRI) { unsigned NumPHIdValues = 0; for (auto *I : *LRI) @@ -1720,7 +1754,7 @@ DEBUG(dbgs() << "SINK: #phid values: " << NumPHIdValues << "\n"); unsigned NumPHIInsts = NumPHIdValues / UnconditionalPreds.size(); if ((NumPHIdValues % UnconditionalPreds.size()) != 0) - NumPHIInsts++; + NumPHIInsts++; return NumPHIInsts <= 1; }; Index: test/Transforms/SimplifyCFG/sink-common-code.ll =================================================================== --- test/Transforms/SimplifyCFG/sink-common-code.ll +++ test/Transforms/SimplifyCFG/sink-common-code.ll @@ -842,6 +842,71 @@ ; CHECK: insertvalue ; CHECK-NOT: insertvalue +; Tail sinking should not happen due to extra moves for the PHI. +define zeroext i1 @test19(i64 %s, i32* nocapture %idx) { +entry: + %cmp = icmp ult i64 %s, 1025 + br i1 %cmp, label %if.then, label %if.else + +if.then: + %conv1 = trunc i64 %s to i32 + %add = add i32 %conv1, 7 + %shr = lshr i32 %add, 3 + store i32 %shr, i32* %idx, align 4 + br label %return + +if.else: + %cmp2 = icmp ult i64 %s, 4097 + br i1 %cmp2, label %if.then2, label %return + +if.then2: + %conv4 = trunc i64 %s to i32 + %add6 = add i32 %conv4, 15487 + %shr7 = lshr i32 %add6, 7 + store i32 %shr7, i32* %idx, align 4 + br label %return + +return: + %retval.0 = phi i1 [ true, %if.then ], [ true, %if.then2 ], [ false, %if.else ] + ret i1 %retval.0 +} +; CHECK-LABEL: @test19 +; CHECK-NOT: return.sink.split + +; Tail sinking should happen. +define zeroext i1 @test20(i64 %s, i32* nocapture %idx, i32 %c1) { +entry: + %cmp = icmp ult i64 %s, 1025 + br i1 %cmp, label %if.then, label %if.else + +if.then: + %c2 = add i32 %c1, 100 + %conv1 = trunc i64 %s to i32 + %add = add i32 %conv1, %c2 + %shr = lshr i32 %add, 3 + store i32 %shr, i32* %idx, align 4 + br label %return + +if.else: + %cmp2 = icmp ult i64 %s, 4097 + br i1 %cmp2, label %if.then2, label %return + +if.then2: + %c3 = mul i32 %c1, 3 + %conv4 = trunc i64 %s to i32 + %add6 = add i32 %conv4, %c3 + %shr7 = lshr i32 %add6, 7 + store i32 %shr7, i32* %idx, align 4 + br label %return + +return: + %retval.0 = phi i1 [ true, %if.then ], [ true, %if.then2 ], [ false, %if.else ] + ret i1 %retval.0 +} +; CHECK-LABEL: @test20 +; CHECK: return.sink.split + + ; CHECK: ![[TBAA]] = !{![[TYPE:[0-9]]], ![[TYPE]], i64 0} ; CHECK: ![[TYPE]] = !{!"float", ![[TEXT:[0-9]]]} ; CHECK: ![[TEXT]] = !{!"an example type tree"}