diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index e6499d87ef0..b5cc14e56f8 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -24,6 +24,7 @@ #include "llvm/Constants.h" #include "llvm/InlineAsm.h" +#include "llvm/Instructions.h" #include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/CodeGen/RuntimeLibcalls.h" #include "llvm/ADT/APFloat.h" @@ -263,7 +264,27 @@ public: MVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const; - + + /// getTgtMemIntrinsic: Given an intrinsic, checks if on the target the + /// intrinsic will need to map to a MemIntrinsicNode (touches memory). If + /// this is the case, it returns true and store the intrinsic + /// information into the IntrinsicInfo that was passed to the function. + typedef struct IntrinsicInfo { + unsigned opc; // target opcode + MVT memVT; // memory VT + const Value* ptrVal; // value representing memory location + int offset; // offset off of ptrVal + unsigned align; // alignment + bool vol; // is volatile? + bool readMem; // reads memory? + bool writeMem; // writes memory? + } IntrinisicInfo; + + virtual bool getTgtMemIntrinsic(IntrinsicInfo& Info, + CallInst &I, unsigned Intrinsic) { + return false; + } + /// getWidenVectorType: given a vector type, returns the type to widen to /// (e.g., v7i8 to v8i8). If the vector type is legal, it returns itself. /// If there is no vector type that we want to widen to, returns MVT::Other diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index e34e78fca6d..738575380d0 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -2577,9 +2577,14 @@ void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I, Ops.push_back(getRoot()); } } - - // Add the intrinsic ID as an integer operand. - Ops.push_back(DAG.getConstant(Intrinsic, TLI.getPointerTy())); + + // Info is set by getTgtMemInstrinsic + TargetLowering::IntrinsicInfo Info; + bool IsTgtIntrinsic = TLI.getTgtMemIntrinsic(Info, I, Intrinsic); + + // Add the intrinsic ID as an integer operand if it's not a target intrinsic. + if (!IsTgtIntrinsic) + Ops.push_back(DAG.getConstant(Intrinsic, TLI.getPointerTy())); // Add all operands of the call to the operand list. for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) { @@ -2610,7 +2615,15 @@ void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I, // Create the node. SDValue Result; - if (!HasChain) + if (IsTgtIntrinsic) { + // This is target intrinsic that touches memory + Result = DAG.getMemIntrinsicNode(Info.opc, VTList, VTs.size(), + &Ops[0], Ops.size(), + Info.memVT, Info.ptrVal, Info.offset, + Info.align, Info.vol, + Info.readMem, Info.writeMem); + } + else if (!HasChain) Result = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VTList, VTs.size(), &Ops[0], Ops.size()); else if (I.getType() != Type::VoidTy)