[X86] Lower SEXTLOAD using SIGN_EXTEND_VECTOR_INREG. NCI.
[oota-llvm.git] / lib / Target / X86 / X86ISelLowering.cpp
index 0ed196a4acb5f55b92fafcd47f83653e11c86b84..b1e1dfa5f79fe9ab62659ce4a00d883d987bbd70 100644 (file)
@@ -2945,20 +2945,6 @@ static SDValue getMOVL(SelectionDAG &DAG, SDLoc dl, EVT VT, SDValue V1,
   return DAG.getVectorShuffle(VT, dl, V1, V2, &Mask[0]);
 }
 
-/// Check if the fall through instruction after a call site is unreachable.
-/// FIXME: This will fail if there are interesting non-code generating IR
-/// instructions between the call and the unreachable (lifetime.end). In
-/// practice, this should be rare because optimizations like to delete non-call
-/// code before unreachable.
-static bool isCallFollowedByUnreachable(ImmutableCallSite CS) {
-  const Instruction *NextInst;
-  if (auto *II = dyn_cast<InvokeInst>(CS.getInstruction()))
-    NextInst = II->getNormalDest()->getFirstNonPHIOrDbg();
-  else
-    NextInst = CS.getInstruction()->getNextNode();
-  return isa<UnreachableInst>(NextInst);
-}
-
 SDValue
 X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
                              SmallVectorImpl<SDValue> &InVals) const {
@@ -3464,15 +3450,6 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
     InFlag = Chain.getValue(1);
   }
 
-  if (Subtarget->isTargetWin64() && CLI.CS) {
-    // Look for a call followed by unreachable. On Win64, we need to ensure that
-    // the call does not accidentally fall through to something that looks like
-    // an epilogue. We do this by inserting a DEBUGTRAP, which lowers to int3,
-    // which is what MSVC emits after noreturn calls.
-    if (isCallFollowedByUnreachable(*CLI.CS))
-      Chain = DAG.getNode(ISD::DEBUGTRAP, dl, MVT::Other, Chain);
-  }
-
   // Handle result values, copying them out of physregs into vregs that we
   // return.
   return LowerCallResult(Chain, InFlag, CallConv, isVarArg,
@@ -12490,6 +12467,15 @@ static SDValue lowerUINT_TO_FP_vXi32(SDValue Op, SelectionDAG &DAG,
   //     float4 fhi = (float4) hi - (0x1.0p39f + 0x1.0p23f);
   //     return (float4) lo + fhi;
 
+  // We shouldn't use it when unsafe-fp-math is enabled though: we might later
+  // reassociate the two FADDs, and if we do that, the algorithm fails
+  // spectacularly (PR24512).
+  // FIXME: If we ever have some kind of Machine FMF, this should be marked
+  // as non-fast and always be enabled. Why isn't SDAG FMF enough? Because
+  // there's also the MachineCombiner reassociations happening on Machine IR.
+  if (DAG.getTarget().Options.UnsafeFPMath)
+    return SDValue();
+
   SDLoc DL(Op);
   SDValue V = Op->getOperand(0);
   EVT VecIntVT = V.getValueType();
@@ -15071,29 +15057,12 @@ static SDValue LowerExtendedLoad(SDValue Op, const X86Subtarget *Subtarget,
       return Sext;
     }
 
-    // Otherwise we'll shuffle the small elements in the high bits of the
-    // larger type and perform an arithmetic shift. If the shift is not legal
-    // it's better to scalarize.
-    assert(TLI.isOperationLegalOrCustom(ISD::SRA, RegVT) &&
-           "We can't implement a sext load without an arithmetic right shift!");
-
-    // Redistribute the loaded elements into the different locations.
-    SmallVector<int, 16> ShuffleVec(NumElems * SizeRatio, -1);
-    for (unsigned i = 0; i != NumElems; ++i)
-      ShuffleVec[i * SizeRatio + SizeRatio - 1] = i;
-
-    SDValue Shuff = DAG.getVectorShuffle(
-        WideVecVT, dl, SlicedVec, DAG.getUNDEF(WideVecVT), &ShuffleVec[0]);
-
-    Shuff = DAG.getBitcast(RegVT, Shuff);
-
-    // Build the arithmetic shift.
-    unsigned Amt = RegVT.getVectorElementType().getSizeInBits() -
-                   MemVT.getVectorElementType().getSizeInBits();
-    Shuff =
-        DAG.getNode(ISD::SRA, dl, RegVT, Shuff,
-                    DAG.getConstant(Amt, dl, RegVT));
+    // Otherwise we'll use SIGN_EXTEND_VECTOR_INREG to sign extend the lowest
+    // lanes.
+    assert(TLI.isOperationLegalOrCustom(ISD::SIGN_EXTEND_VECTOR_INREG, RegVT) &&
+           "We can't implement a sext load without SIGN_EXTEND_VECTOR_INREG!");
 
+    SDValue Shuff = DAG.getSignExtendVectorInReg(SlicedVec, dl, RegVT);
     DAG.ReplaceAllUsesOfValueWith(SDValue(Ld, 1), TF);
     return Shuff;
   }