diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -117,6 +117,8 @@ def IntrNoReturn : IntrinsicProperty; +def IntrNoFree : IntrinsicProperty; + def IntrWillReturn : IntrinsicProperty; // IntrCold - Calls to this intrinsic are cold. @@ -329,12 +331,25 @@ list param_types = [], list intr_properties = [], string name = "", - list sd_properties = []> : SDPatternOperator { + list sd_properties = [], + list optout_intr_properties = []> : SDPatternOperator { string LLVMName = name; string TargetPrefix = ""; // Set to a prefix for target-specific intrinsics. list RetTypes = ret_types; list ParamTypes = param_types; - list IntrProperties = intr_properties; + list DefaultIntrProperties = [IntrNoSync, IntrNoFree, IntrWillReturn]; + + list default_properties = !foldl( + [], DefaultIntrProperties, a, b, + !listconcat( + a, !if (!size(!foldl( + [], optout_intr_properties, c, d, + !listconcat(c, + !if (!eq(!cast(b), !cast(d)), + [d], [])))), + [], [b]))); + + list IntrProperties = !listconcat(intr_properties, default_properties); let Properties = sd_properties; bit isTarget = 0; @@ -567,9 +582,9 @@ def int_memset : Intrinsic<[], [llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty, llvm_i1_ty], - [IntrWriteMem, IntrArgMemOnly, IntrWillReturn, + [IntrWriteMem, IntrArgMemOnly, NoCapture>, WriteOnly>, - ImmArg>]>; + ImmArg>], "", [], [IntrNoSync, IntrNoFree]>; // FIXME: Add version of these floating point intrinsics which allow non-default // rounding modes and FP exception handling. diff --git a/llvm/utils/TableGen/CodeGenIntrinsics.h b/llvm/utils/TableGen/CodeGenIntrinsics.h --- a/llvm/utils/TableGen/CodeGenIntrinsics.h +++ b/llvm/utils/TableGen/CodeGenIntrinsics.h @@ -126,6 +126,9 @@ /// True if the intrinsic is no-sync. bool isNoSync; + /// True if the intrinsic is no-free. + bool isNoFree; + /// True if the intrinsic is will-return. bool isWillReturn; diff --git a/llvm/utils/TableGen/CodeGenTarget.cpp b/llvm/utils/TableGen/CodeGenTarget.cpp --- a/llvm/utils/TableGen/CodeGenTarget.cpp +++ b/llvm/utils/TableGen/CodeGenTarget.cpp @@ -619,6 +619,7 @@ canThrow = false; isNoReturn = false; isNoSync = false; + isNoFree = false; isWillReturn = false; isCold = false; isNoDuplicate = false; @@ -785,6 +786,8 @@ isNoReturn = true; else if (Property->getName() == "IntrNoSync") isNoSync = true; + else if (Property->getName() == "IntrNoFree") + isNoFree = true; else if (Property->getName() == "IntrWillReturn") isWillReturn = true; else if (Property->getName() == "IntrCold") diff --git a/llvm/utils/TableGen/IntrinsicEmitter.cpp b/llvm/utils/TableGen/IntrinsicEmitter.cpp --- a/llvm/utils/TableGen/IntrinsicEmitter.cpp +++ b/llvm/utils/TableGen/IntrinsicEmitter.cpp @@ -584,6 +584,9 @@ if (L->isNoSync != R->isNoSync) return R->isNoSync; + if (L->isNoFree != R->isNoFree) + return R->isNoFree; + if (L->isWillReturn != R->isWillReturn) return R->isWillReturn; @@ -751,10 +754,11 @@ } if (!intrinsic.canThrow || - (intrinsic.ModRef != CodeGenIntrinsic::ReadWriteMem && !intrinsic.hasSideEffects) || - intrinsic.isNoReturn || intrinsic.isNoSync || intrinsic.isWillReturn || - intrinsic.isCold || intrinsic.isNoDuplicate || intrinsic.isConvergent || - intrinsic.isSpeculatable) { + (intrinsic.ModRef != CodeGenIntrinsic::ReadWriteMem && + !intrinsic.hasSideEffects) || + intrinsic.isNoReturn || intrinsic.isNoSync || intrinsic.isNoFree || + intrinsic.isWillReturn || intrinsic.isCold || intrinsic.isNoDuplicate || + intrinsic.isConvergent || intrinsic.isSpeculatable) { OS << " const Attribute::AttrKind Atts[] = {"; bool addComma = false; if (!intrinsic.canThrow) { @@ -773,6 +777,12 @@ OS << "Attribute::NoSync"; addComma = true; } + if (intrinsic.isNoFree) { + if (addComma) + OS << ","; + OS << "Attribute::NoFree"; + addComma = true; + } if (intrinsic.isWillReturn) { if (addComma) OS << ",";