Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -19820,7 +19820,8 @@ // // where Op could be BRCOND or CMOV. // -static SDValue checkBoolTestSetCCCombine(SDValue Cmp, X86::CondCode &CC) { +static SDValue checkBoolTestSetCCCombine(SDValue Chain, SDValue Cmp, + X86::CondCode &CC) { // Quit if not CMP and SUB with its value result used. if (Cmp.getOpcode() != X86ISD::CMP && (Cmp.getOpcode() != X86ISD::SUB || Cmp.getNode()->hasAnyUseOfValue(0))) @@ -19887,12 +19888,21 @@ assert(X86::CondCode(SetCC.getConstantOperandVal(0)) == X86::COND_B && "Invalid use of SETCC_CARRY!"); // FALL THROUGH - case X86ISD::SETCC: + case X86ISD::SETCC: { + // If the operand is CopyFromReg, applying this simplification may create + // a situation later where we need to copy EFLAGS. Since this isn't + // supported, we will generate incorrect code. To avoid this situation, + // we forbid this simplification if the operand is CopyFromReg and it + // is not directly chained to us. + SDValue Op = SetCC.getOperand(1); + if (Chain && Op.getOpcode() == ISD::CopyFromReg && Op.getValue(1) != Chain) + break; // Set the condition code or opposite one if necessary. CC = X86::CondCode(SetCC.getConstantOperandVal(0)); if (needOppositeCond) CC = X86::GetOppositeBranchCondition(CC); - return SetCC.getOperand(1); + return Op; + } case X86ISD::CMOV: { // Check whether false/true value has canonical one, i.e. 0 or 1. ConstantSDNode *FVal = dyn_cast(SetCC.getOperand(0)); @@ -19965,7 +19975,7 @@ SDValue Flags; - Flags = checkBoolTestSetCCCombine(Cond, CC); + Flags = checkBoolTestSetCCCombine(SDValue(), Cond, CC); if (Flags.getNode() && // Extra check as FCMOV only supports a subset of X86 cond. (FalseOp.getValueType() != MVT::f80 || hasFPCMov(CC))) { @@ -21803,7 +21813,7 @@ SDValue Flags; - Flags = checkBoolTestSetCCCombine(EFLAGS, CC); + Flags = checkBoolTestSetCCCombine(SDValue(), EFLAGS, CC); if (Flags.getNode()) { SDValue Cond = DAG.getConstant(CC, MVT::i8); return DAG.getNode(X86ISD::SETCC, DL, N->getVTList(), Cond, Flags); @@ -21825,7 +21835,7 @@ SDValue Flags; - Flags = checkBoolTestSetCCCombine(EFLAGS, CC); + Flags = checkBoolTestSetCCCombine(Chain, EFLAGS, CC); if (Flags.getNode()) { SDValue Cond = DAG.getConstant(CC, MVT::i8); return DAG.getNode(X86ISD::BRCOND, DL, N->getVTList(), Chain, Dest, Cond,