1/// Attribute base class.
2class Attr<string S> {
3  // String representation of this attribute in the IR.
4  string AttrString = S;
5}
6
7/// Enum attribute.
8class EnumAttr<string S> : Attr<S>;
9
10/// Int attribute.
11class IntAttr<string S> : Attr<S>;
12
13/// StringBool attribute.
14class StrBoolAttr<string S> : Attr<S>;
15
16/// Type attribute.
17class TypeAttr<string S> : Attr<S>;
18
19/// Target-independent enum attributes.
20
21/// Alignment of parameter (5 bits) stored as log2 of alignment with +1 bias.
22/// 0 means unaligned (different from align(1)).
23def Alignment : IntAttr<"align">;
24
25/// The result of the function is guaranteed to point to a number of bytes that
26/// we can determine if we know the value of the function's arguments.
27def AllocSize : IntAttr<"allocsize">;
28
29/// inline=always.
30def AlwaysInline : EnumAttr<"alwaysinline">;
31
32/// Function can access memory only using pointers based on its arguments.
33def ArgMemOnly : EnumAttr<"argmemonly">;
34
35/// Callee is recognized as a builtin, despite nobuiltin attribute on its
36/// declaration.
37def Builtin : EnumAttr<"builtin">;
38
39/// Pass structure by value.
40def ByVal : TypeAttr<"byval">;
41
42/// Parameter or return value may not contain uninitialized or poison bits.
43def NoUndef : EnumAttr<"noundef">;
44
45/// Marks function as being in a cold path.
46def Cold : EnumAttr<"cold">;
47
48/// Can only be moved to control-equivalent blocks.
49def Convergent : EnumAttr<"convergent">;
50
51/// Pointer is known to be dereferenceable.
52def Dereferenceable : IntAttr<"dereferenceable">;
53
54/// Pointer is either null or dereferenceable.
55def DereferenceableOrNull : IntAttr<"dereferenceable_or_null">;
56
57/// Function may only access memory that is inaccessible from IR.
58def InaccessibleMemOnly : EnumAttr<"inaccessiblememonly">;
59
60/// Function may only access memory that is either inaccessible from the IR,
61/// or pointed to by its pointer arguments.
62def InaccessibleMemOrArgMemOnly : EnumAttr<"inaccessiblemem_or_argmemonly">;
63
64/// Pass structure in an alloca.
65def InAlloca : EnumAttr<"inalloca">;
66
67/// Source said inlining was desirable.
68def InlineHint : EnumAttr<"inlinehint">;
69
70/// Force argument to be passed in register.
71def InReg : EnumAttr<"inreg">;
72
73/// Build jump-instruction tables and replace refs.
74def JumpTable : EnumAttr<"jumptable">;
75
76/// Function must be optimized for size first.
77def MinSize : EnumAttr<"minsize">;
78
79/// Naked function.
80def Naked : EnumAttr<"naked">;
81
82/// Nested function static chain.
83def Nest : EnumAttr<"nest">;
84
85/// Considered to not alias after call.
86def NoAlias : EnumAttr<"noalias">;
87
88/// Callee isn't recognized as a builtin.
89def NoBuiltin : EnumAttr<"nobuiltin">;
90
91/// Function creates no aliases of pointer.
92def NoCapture : EnumAttr<"nocapture">;
93
94/// Call cannot be duplicated.
95def NoDuplicate : EnumAttr<"noduplicate">;
96
97/// Function does not deallocate memory.
98def NoFree : EnumAttr<"nofree">;
99
100/// Disable implicit floating point insts.
101def NoImplicitFloat : EnumAttr<"noimplicitfloat">;
102
103/// inline=never.
104def NoInline : EnumAttr<"noinline">;
105
106/// Function is called early and/or often, so lazy binding isn't worthwhile.
107def NonLazyBind : EnumAttr<"nonlazybind">;
108
109/// Disable merging for call sites
110def NoMerge : EnumAttr<"nomerge">;
111
112/// Pointer is known to be not null.
113def NonNull : EnumAttr<"nonnull">;
114
115/// The function does not recurse.
116def NoRecurse : EnumAttr<"norecurse">;
117
118/// Disable redzone.
119def NoRedZone : EnumAttr<"noredzone">;
120
121/// Mark the function as not returning.
122def NoReturn : EnumAttr<"noreturn">;
123
124/// Function does not synchronize.
125def NoSync : EnumAttr<"nosync">;
126
127/// Disable Indirect Branch Tracking.
128def NoCfCheck : EnumAttr<"nocf_check">;
129
130/// Function doesn't unwind stack.
131def NoUnwind : EnumAttr<"nounwind">;
132
133/// Null pointer in address space zero is valid.
134def NullPointerIsValid : EnumAttr<"null_pointer_is_valid">;
135
136/// Select optimizations for best fuzzing signal.
137def OptForFuzzing : EnumAttr<"optforfuzzing">;
138
139/// opt_size.
140def OptimizeForSize : EnumAttr<"optsize">;
141
142/// Function must not be optimized.
143def OptimizeNone : EnumAttr<"optnone">;
144
145/// Similar to byval but without a copy.
146def Preallocated : TypeAttr<"preallocated">;
147
148/// Function does not access memory.
149def ReadNone : EnumAttr<"readnone">;
150
151/// Function only reads from memory.
152def ReadOnly : EnumAttr<"readonly">;
153
154/// Return value is always equal to this argument.
155def Returned : EnumAttr<"returned">;
156
157/// Parameter is required to be a trivial constant.
158def ImmArg : EnumAttr<"immarg">;
159
160/// Function can return twice.
161def ReturnsTwice : EnumAttr<"returns_twice">;
162
163/// Safe Stack protection.
164def SafeStack : EnumAttr<"safestack">;
165
166/// Shadow Call Stack protection.
167def ShadowCallStack : EnumAttr<"shadowcallstack">;
168
169/// Sign extended before/after call.
170def SExt : EnumAttr<"signext">;
171
172/// Alignment of stack for function (3 bits)  stored as log2 of alignment with
173/// +1 bias 0 means unaligned (different from alignstack=(1)).
174def StackAlignment : IntAttr<"alignstack">;
175
176/// Function can be speculated.
177def Speculatable : EnumAttr<"speculatable">;
178
179/// Stack protection.
180def StackProtect : EnumAttr<"ssp">;
181
182/// Stack protection required.
183def StackProtectReq : EnumAttr<"sspreq">;
184
185/// Strong Stack protection.
186def StackProtectStrong : EnumAttr<"sspstrong">;
187
188/// Function was called in a scope requiring strict floating point semantics.
189def StrictFP : EnumAttr<"strictfp">;
190
191/// Hidden pointer to structure to return.
192def StructRet : EnumAttr<"sret">;
193
194/// AddressSanitizer is on.
195def SanitizeAddress : EnumAttr<"sanitize_address">;
196
197/// ThreadSanitizer is on.
198def SanitizeThread : EnumAttr<"sanitize_thread">;
199
200/// MemorySanitizer is on.
201def SanitizeMemory : EnumAttr<"sanitize_memory">;
202
203/// HWAddressSanitizer is on.
204def SanitizeHWAddress : EnumAttr<"sanitize_hwaddress">;
205
206/// MemTagSanitizer is on.
207def SanitizeMemTag : EnumAttr<"sanitize_memtag">;
208
209/// Speculative Load Hardening is enabled.
210///
211/// Note that this uses the default compatibility (always compatible during
212/// inlining) and a conservative merge strategy where inlining an attributed
213/// body will add the attribute to the caller. This ensures that code carrying
214/// this attribute will always be lowered with hardening enabled.
215def SpeculativeLoadHardening : EnumAttr<"speculative_load_hardening">;
216
217/// Argument is swift error.
218def SwiftError : EnumAttr<"swifterror">;
219
220/// Argument is swift self/context.
221def SwiftSelf : EnumAttr<"swiftself">;
222
223/// Function must be in a unwind table.
224def UWTable : EnumAttr<"uwtable">;
225
226/// Function always comes back to callsite.
227def WillReturn : EnumAttr<"willreturn">;
228
229/// Function only writes to memory.
230def WriteOnly : EnumAttr<"writeonly">;
231
232/// Zero extended before/after call.
233def ZExt : EnumAttr<"zeroext">;
234
235/// Target-independent string attributes.
236def LessPreciseFPMAD : StrBoolAttr<"less-precise-fpmad">;
237def NoInfsFPMath : StrBoolAttr<"no-infs-fp-math">;
238def NoNansFPMath : StrBoolAttr<"no-nans-fp-math">;
239def NoSignedZerosFPMath : StrBoolAttr<"no-signed-zeros-fp-math">;
240def UnsafeFPMath : StrBoolAttr<"unsafe-fp-math">;
241def NoJumpTables : StrBoolAttr<"no-jump-tables">;
242def NoInlineLineTables : StrBoolAttr<"no-inline-line-tables">;
243def ProfileSampleAccurate : StrBoolAttr<"profile-sample-accurate">;
244def UseSampleProfile : StrBoolAttr<"use-sample-profile">;
245
246class CompatRule<string F> {
247  // The name of the function called to check the attribute of the caller and
248  // callee and decide whether inlining should be allowed. The function's
249  // signature must match "bool(const Function&, const Function &)", where the
250  // first parameter is the reference to the caller and the second parameter is
251  // the reference to the callee. It must return false if the attributes of the
252  // caller and callee are incompatible, and true otherwise.
253  string CompatFunc = F;
254}
255
256def : CompatRule<"isEqual<SanitizeAddressAttr>">;
257def : CompatRule<"isEqual<SanitizeThreadAttr>">;
258def : CompatRule<"isEqual<SanitizeMemoryAttr>">;
259def : CompatRule<"isEqual<SanitizeHWAddressAttr>">;
260def : CompatRule<"isEqual<SanitizeMemTagAttr>">;
261def : CompatRule<"isEqual<SafeStackAttr>">;
262def : CompatRule<"isEqual<ShadowCallStackAttr>">;
263def : CompatRule<"isEqual<UseSampleProfileAttr>">;
264
265class MergeRule<string F> {
266  // The name of the function called to merge the attributes of the caller and
267  // callee. The function's signature must match
268  // "void(Function&, const Function &)", where the first parameter is the
269  // reference to the caller and the second parameter is the reference to the
270  // callee.
271  string MergeFunc = F;
272}
273
274def : MergeRule<"setAND<LessPreciseFPMADAttr>">;
275def : MergeRule<"setAND<NoInfsFPMathAttr>">;
276def : MergeRule<"setAND<NoNansFPMathAttr>">;
277def : MergeRule<"setAND<NoSignedZerosFPMathAttr>">;
278def : MergeRule<"setAND<UnsafeFPMathAttr>">;
279def : MergeRule<"setOR<NoImplicitFloatAttr>">;
280def : MergeRule<"setOR<NoJumpTablesAttr>">;
281def : MergeRule<"setOR<ProfileSampleAccurateAttr>">;
282def : MergeRule<"setOR<SpeculativeLoadHardeningAttr>">;
283def : MergeRule<"adjustCallerSSPLevel">;
284def : MergeRule<"adjustCallerStackProbes">;
285def : MergeRule<"adjustCallerStackProbeSize">;
286def : MergeRule<"adjustMinLegalVectorWidth">;
287def : MergeRule<"adjustNullPointerValidAttr">;
288