Index: include/llvm/IR/Intrinsics.td =================================================================== --- include/llvm/IR/Intrinsics.td +++ include/llvm/IR/Intrinsics.td @@ -92,6 +92,15 @@ // This property indicates that the intrinsic is safe to speculate. def IntrSpeculatable : IntrinsicProperty; +// This property can be used to override the 'has no other side effects' +// language of the IntrNoMem, IntrReadMem, IntrWriteMem, and IntrArgMemOnly +// intrinsic properties. By default, intrinsics are assumed to have side +// effects, so this property is only necessary if you have defined one of +// the memory properties listed above. +// For this property, 'side effects' has the same meaning as 'side effects' +// defined by the hasSideEffects property of the TableGen Instruction class. +def IntrHasSideEffects : IntrinsicProperty; + //===----------------------------------------------------------------------===// // Types used by intrinsics. //===----------------------------------------------------------------------===// Index: utils/TableGen/CodeGenDAGPatterns.cpp =================================================================== --- utils/TableGen/CodeGenDAGPatterns.cpp +++ utils/TableGen/CodeGenDAGPatterns.cpp @@ -2822,7 +2822,8 @@ if (IntInfo->ModRef & CodeGenIntrinsic::MR_Mod) mayStore = true;// Intrinsics that can write to memory are 'mayStore'. - if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteMem) + if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteMem || + IntInfo->hasSideEffects) // ReadWriteMem intrinsics can have other strange effects. hasSideEffects = true; } Index: utils/TableGen/CodeGenIntrinsics.h =================================================================== --- utils/TableGen/CodeGenIntrinsics.h +++ utils/TableGen/CodeGenIntrinsics.h @@ -108,6 +108,10 @@ /// True if the intrinsic is marked as convergent. bool isConvergent; + /// True if the intrinsic has side effects that aren't captured by any + /// of the other flags. + bool hasSideEffects; + // True if the intrinsic is marked as speculatable. bool isSpeculatable; Index: utils/TableGen/CodeGenTarget.cpp =================================================================== --- utils/TableGen/CodeGenTarget.cpp +++ utils/TableGen/CodeGenTarget.cpp @@ -456,6 +456,7 @@ isNoDuplicate = false; isConvergent = false; isSpeculatable = false; + hasSideEffects = false; if (DefName.size() <= 4 || std::string(DefName.begin(), DefName.begin() + 4) != "int_") @@ -592,6 +593,8 @@ isNoReturn = true; else if (Property->getName() == "IntrSpeculatable") isSpeculatable = true; + else if (Property->getName() == "IntrHasSideEffects") + hasSideEffects = true; else if (Property->isSubClassOf("NoCapture")) { unsigned ArgNo = Property->getValueAsInt("ArgNo"); ArgumentAttributes.push_back(std::make_pair(ArgNo, NoCapture)); Index: utils/TableGen/IntrinsicEmitter.cpp =================================================================== --- utils/TableGen/IntrinsicEmitter.cpp +++ utils/TableGen/IntrinsicEmitter.cpp @@ -464,6 +464,9 @@ if (L->isSpeculatable != R->isSpeculatable) return R->isSpeculatable; + if (L->hasSideEffects != R->hasSideEffects) + return R->hasSideEffects; + // Try to order by readonly/readnone attribute. CodeGenIntrinsic::ModRefBehavior LK = L->ModRef; CodeGenIntrinsic::ModRefBehavior RK = R->ModRef;