Cond = Cmp;
addTest = false;
}
+ // Also, recognize the pattern generated by an FCMP_UNE. We can emit
+ // two branches instead of an explicit OR instruction with a
+ // separate test.
+ } else if (Cond.getOpcode() == ISD::OR &&
+ Cond.hasOneUse() &&
+ Cond.getOperand(0).getOpcode() == X86ISD::SETCC &&
+ Cond.getOperand(0).hasOneUse() &&
+ Cond.getOperand(1).getOpcode() == X86ISD::SETCC &&
+ Cond.getOperand(1).hasOneUse()) {
+ SDValue Cmp = Cond.getOperand(0).getOperand(1);
+ unsigned Opc = Cmp.getOpcode();
+ if (Cmp == Cond.getOperand(1).getOperand(1) &&
+ (Opc == X86ISD::CMP ||
+ Opc == X86ISD::COMI ||
+ Opc == X86ISD::UCOMI)) {
+ CC = Cond.getOperand(0).getOperand(0);
+ Chain = DAG.getNode(X86ISD::BRCOND, Op.getValueType(),
+ Chain, Dest, CC, Cmp);
+ CC = Cond.getOperand(1).getOperand(0);
+ Cond = Cmp;
+ addTest = false;
+ }
+ // Also, recognize the pattern generated by an FCMP_OEQ. We can emit
+ // two branches instead of an explicit AND instruction with a
+ // separate test. However, we only do this if this block doesn't
+ // have a fall-through edge, because this requires an explicit
+ // jmp when the condition is false.
+ } else if (Cond.getOpcode() == ISD::AND &&
+ Cond.hasOneUse() &&
+ Cond.getOperand(0).getOpcode() == X86ISD::SETCC &&
+ Cond.getOperand(0).hasOneUse() &&
+ Cond.getOperand(1).getOpcode() == X86ISD::SETCC &&
+ Cond.getOperand(1).hasOneUse()) {
+ SDValue Cmp = Cond.getOperand(0).getOperand(1);
+ unsigned Opc = Cmp.getOpcode();
+ if (Cmp == Cond.getOperand(1).getOperand(1) &&
+ (Opc == X86ISD::CMP ||
+ Opc == X86ISD::COMI ||
+ Opc == X86ISD::UCOMI) &&
+ Op.getNode()->hasOneUse()) {
+ X86::CondCode CCode =
+ (X86::CondCode)Cond.getOperand(0).getConstantOperandVal(0);
+ CCode = X86::GetOppositeBranchCondition(CCode);
+ CC = DAG.getConstant(CCode, MVT::i8);
+ SDValue User = SDValue(*Op.getNode()->use_begin(), 0);
+ // Look for an unconditional branch following this conditional branch.
+ // We need this because we need to reverse the successors in order
+ // to implement FCMP_OEQ.
+ if (User.getOpcode() == ISD::BR) {
+ SDValue FalseBB = User.getOperand(1);
+ SDValue NewBR =
+ DAG.UpdateNodeOperands(User, User.getOperand(0), Dest);
+ assert(NewBR == User);
+ Dest = FalseBB;
+
+ Chain = DAG.getNode(X86ISD::BRCOND, Op.getValueType(),
+ Chain, Dest, CC, Cmp);
+ X86::CondCode CCode =
+ (X86::CondCode)Cond.getOperand(1).getConstantOperandVal(0);
+ CCode = X86::GetOppositeBranchCondition(CCode);
+ CC = DAG.getConstant(CCode, MVT::i8);
+ Cond = Cmp;
+ addTest = false;
+ }
+ }
}
if (addTest) {
Cond= DAG.getNode(X86ISD::CMP, MVT::i32, Cond, DAG.getConstant(0, MVT::i8));
}
return DAG.getNode(X86ISD::BRCOND, Op.getValueType(),
- Chain, Op.getOperand(2), CC, Cond);
+ Chain, Dest, CC, Cond);
}