diff options
Diffstat (limited to 'lib/Target/X86/X86ISelLowering.cpp')
| -rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 36 | 
1 files changed, 30 insertions, 6 deletions
| diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 76eeb64650ba..716c146811a1 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -15226,9 +15226,15 @@ X86TargetLowering::EmitVAStartSaveXMMRegsWithCustomInserter(      MBB->addSuccessor(EndMBB);    } +  // Make sure the last operand is EFLAGS, which gets clobbered by the branch +  // that was just emitted, but clearly shouldn't be "saved". +  assert((MI->getNumOperands() <= 3 || +          !MI->getOperand(MI->getNumOperands() - 1).isReg() || +          MI->getOperand(MI->getNumOperands() - 1).getReg() == X86::EFLAGS) +         && "Expected last argument to be EFLAGS");    unsigned MOVOpc = Subtarget->hasFp256() ? X86::VMOVAPSmr : X86::MOVAPSmr;    // In the XMM save block, save all the XMM argument registers. -  for (int i = 3, e = MI->getNumOperands(); i != e; ++i) { +  for (int i = 3, e = MI->getNumOperands() - 1; i != e; ++i) {      int64_t Offset = (i - 3) * 16 + VarArgsFPOffset;      MachineMemOperand *MMO =        F->getMachineMemOperand( @@ -17577,12 +17583,30 @@ static SDValue CMPEQCombine(SDNode *N, SelectionDAG &DAG,            // FIXME: need symbolic constants for these magic numbers.            // See X86ATTInstPrinter.cpp:printSSECC().            unsigned x86cc = (cc0 == X86::COND_E) ? 0 : 4; -          SDValue OnesOrZeroesF = DAG.getNode(NTOperator, DL, MVT::f32, CMP00, CMP01, +          SDValue OnesOrZeroesF = DAG.getNode(NTOperator, DL, CMP00.getValueType(), +                                              CMP00, CMP01,                                                DAG.getConstant(x86cc, MVT::i8)); -          SDValue OnesOrZeroesI = DAG.getNode(ISD::BITCAST, DL, MVT::i32, -                                              OnesOrZeroesF); -          SDValue ANDed = DAG.getNode(ISD::AND, DL, MVT::i32, OnesOrZeroesI, -                                      DAG.getConstant(1, MVT::i32)); + +          MVT IntVT = is64BitFP ? MVT::i64 : MVT::i32; + +          if (is64BitFP && !Subtarget->is64Bit()) { +            // On a 32-bit target, we cannot bitcast the 64-bit float to a +            // 64-bit integer, since that's not a legal type. Since +            // OnesOrZeroesF is all ones of all zeroes, we don't need all the +            // bits, but can do this little dance to extract the lowest 32 bits +            // and work with those going forward. +            SDValue Vector64 = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v2f64, +                                           OnesOrZeroesF); +            SDValue Vector32 = DAG.getNode(ISD::BITCAST, DL, MVT::v4f32, +                                           Vector64); +            OnesOrZeroesF = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, +                                        Vector32, DAG.getIntPtrConstant(0)); +            IntVT = MVT::i32; +          } + +          SDValue OnesOrZeroesI = DAG.getNode(ISD::BITCAST, DL, IntVT, OnesOrZeroesF); +          SDValue ANDed = DAG.getNode(ISD::AND, DL, IntVT, OnesOrZeroesI, +                                      DAG.getConstant(1, IntVT));            SDValue OneBitOfTruth = DAG.getNode(ISD::TRUNCATE, DL, MVT::i8, ANDed);            return OneBitOfTruth;          } | 
