/// 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));
+ }
}
}
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) {
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;
}
}
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 ||
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)