diff --git a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp --- a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp +++ b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp @@ -1315,7 +1315,7 @@ if (isEligibleBB(*Pred1MBB) && isEligibleForMoveCmp(*Pred2MBB)) { // We assume Pred1MBB is the BB containing the compare to be merged and // Pred2MBB is the BB to which we will append a compare instruction. - // Hence we can proceed as is. + // Proceed as is if Pred1MBB is different from MBB. } else if (isEligibleBB(*Pred2MBB) && isEligibleForMoveCmp(*Pred1MBB)) { // We need to swap Pred1MBB and Pred2MBB to canonicalize. @@ -1323,6 +1323,9 @@ } else return false; + if (Pred1MBB == &MBB) + return false; + // Here, Pred2MBB is the BB to which we need to append a compare inst. // We cannot move the compare instruction if operands are not available // in Pred2MBB (i.e. defined in MBB by an instruction other than PHI). diff --git a/llvm/test/CodeGen/PowerPC/cmp_elimination.ll b/llvm/test/CodeGen/PowerPC/cmp_elimination.ll --- a/llvm/test/CodeGen/PowerPC/cmp_elimination.ll +++ b/llvm/test/CodeGen/PowerPC/cmp_elimination.ll @@ -779,6 +779,29 @@ ret void } +;; The result of %cmp may change in a tail call. Don't lift %cmp to the entry block. +; CHECK-LABEL: func_tailrecurse: +; CHECK-NOT: cmp +; CHECK: .LBB{{.*}}: +; CHECK: cmplw +; CHECK: blt +define fastcc zeroext i32 @func_tailrecurse(i32 zeroext %a, i32 zeroext %b) { +entry: + br label %tailrecurse + +tailrecurse: ; preds = %tailrecurse, %entry + %a.tr = phi i32 [ %a, %entry ], [ %b.tr, %tailrecurse ] + %b.tr = phi i32 [ %b, %entry ], [ %a.tr, %tailrecurse ] + %cmp = icmp ult i32 %a.tr, %b.tr + %conv = zext i1 %cmp to i32 + %ignore = call signext i32 (i32) @func(i32 %conv) + br i1 %cmp, label %tailrecurse, label %if.end + +if.end: ; preds = %tailrecurse + %sub = sub nsw i32 %a.tr, %b.tr + ret i32 %sub +} + declare void @dummy1() declare void @dummy2() declare void @dummy3()