Index: llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h =================================================================== --- llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h +++ llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h @@ -70,6 +70,22 @@ /// Assume the condition register is set by MI(a,b), return the predicate if /// we modify the instructions such that condition register is set by MI(b,a). Predicate getSwappedPredicate(Predicate Opcode); + + /// Return the condition without hint bits. + inline unsigned getPredicateCondition(Predicate Opcode) { + return (unsigned)(Opcode & ~BR_HINT_MASK); + } + + /// Return the hint bits of the predicate. + inline unsigned getPredicateHint(Predicate Opcode) { + return (unsigned)(Opcode & BR_HINT_MASK); + } + + /// Return predicate consisting of specified condition and hint bits. + inline Predicate getPredicate(unsigned Condition, unsigned Hint) { + return (Predicate)((Condition & ~BR_HINT_MASK) | + (Hint & BR_HINT_MASK)); + } } } Index: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -1640,8 +1640,10 @@ I != IE; ++I) { MachineInstr *UseMI = &*I; if (UseMI->getOpcode() == PPC::BCC) { - unsigned Pred = UseMI->getOperand(0).getImm(); - if (Pred != PPC::PRED_EQ && Pred != PPC::PRED_NE) + PPC::Predicate Pred = (PPC::Predicate)UseMI->getOperand(0).getImm(); + unsigned PredCond = PPC::getPredicateCondition(Pred); + // We ignore hint bits when checking for non-equality comparisons. + if (PredCond != PPC::PRED_EQ && PredCond != PPC::PRED_NE) return false; } else if (UseMI->getOpcode() == PPC::ISEL || UseMI->getOpcode() == PPC::ISEL8) { @@ -1695,19 +1697,23 @@ MachineInstr *UseMI = &*MRI->use_instr_begin(CRReg); if (UseMI->getOpcode() == PPC::BCC) { PPC::Predicate Pred = (PPC::Predicate)UseMI->getOperand(0).getImm(); + unsigned PredCond = PPC::getPredicateCondition(Pred); + unsigned PredHint = PPC::getPredicateHint(Pred); int16_t Immed = (int16_t)Value; - if (Immed == -1 && Pred == PPC::PRED_GT) { + // When modyfing the condition in the predicate, we propagate hint bits + // from the original predicate to the new one. + if (Immed == -1 && PredCond == PPC::PRED_GT) { // We convert "greater than -1" into "greater than or equal to 0", // since we are assuming signed comparison by !equalityOnly PredsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(0)), - PPC::PRED_GE)); + PPC::getPredicate(PPC::PRED_GE, PredHint))); Success = true; } - else if (Immed == 1 && Pred == PPC::PRED_LT) { + else if (Immed == 1 && PredCond == PPC::PRED_LT) { // We convert "less than 1" into "less than or equal to 0". PredsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(0)), - PPC::PRED_LE)); + PPC::getPredicate(PPC::PRED_LE, PredHint))); Success = true; } } @@ -1804,9 +1810,11 @@ MachineInstr *UseMI = &*I; if (UseMI->getOpcode() == PPC::BCC) { PPC::Predicate Pred = (PPC::Predicate) UseMI->getOperand(0).getImm(); + unsigned PredCond = PPC::getPredicateCondition(Pred); assert((!equalityOnly || - Pred == PPC::PRED_EQ || Pred == PPC::PRED_NE) && + PredCond == PPC::PRED_EQ || PredCond == PPC::PRED_NE) && "Invalid predicate for equality-only optimization"); + (void)PredCond; // To suppress warning in release build. PredsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(0)), PPC::getSwappedPredicate(Pred))); } else if (UseMI->getOpcode() == PPC::ISEL || Index: llvm/trunk/test/CodeGen/PowerPC/opt-cmp-inst-cr0-live.ll =================================================================== --- llvm/trunk/test/CodeGen/PowerPC/opt-cmp-inst-cr0-live.ll +++ llvm/trunk/test/CodeGen/PowerPC/opt-cmp-inst-cr0-live.ll @@ -54,3 +54,27 @@ bar: ret i32 0 } + +; This test case confirms that a record-form instruction is +; generated even if the branch has a static branch hint. + +; CHECK-LABEL: fn4 +define i64 @fn4(i64 %a, i64 %b) { +; CHECK: ADD8o +; CHECK-NOT: CMP +; CHECK: BCC 71 + +entry: + %add = add nsw i64 %b, %a + %cmp = icmp eq i64 %add, 0 + br i1 %cmp, label %if.then, label %if.end + +if.then: + tail call void @exit(i32 signext 0) #3 + unreachable + +if.end: + ret i64 %add +} + +declare void @exit(i32 signext)