• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- llvm/Analysis/AliasAnalysis.h - Alias Analysis Interface -*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the generic AliasAnalysis interface, which is used as the
11 // common interface used by all clients of alias analysis information, and
12 // implemented by all alias analysis implementations.  Mod/Ref information is
13 // also captured by this interface.
14 //
15 // Implementations of this interface must implement the various virtual methods,
16 // which automatically provides functionality for the entire suite of client
17 // APIs.
18 //
19 // This API identifies memory regions with the Location class. The pointer
20 // component specifies the base memory address of the region. The Size specifies
21 // the maximum size (in address units) of the memory region, or UnknownSize if
22 // the size is not known. The TBAA tag identifies the "type" of the memory
23 // reference; see the TypeBasedAliasAnalysis class for details.
24 //
25 // Some non-obvious details include:
26 //  - Pointers that point to two completely different objects in memory never
27 //    alias, regardless of the value of the Size component.
28 //  - NoAlias doesn't imply inequal pointers. The most obvious example of this
29 //    is two pointers to constant memory. Even if they are equal, constant
30 //    memory is never stored to, so there will never be any dependencies.
31 //    In this and other situations, the pointers may be both NoAlias and
32 //    MustAlias at the same time. The current API can only return one result,
33 //    though this is rarely a problem in practice.
34 //
35 //===----------------------------------------------------------------------===//
36 
37 #ifndef LLVM_ANALYSIS_ALIAS_ANALYSIS_H
38 #define LLVM_ANALYSIS_ALIAS_ANALYSIS_H
39 
40 #include "llvm/Support/CallSite.h"
41 #include "llvm/ADT/DenseMap.h"
42 
43 namespace llvm {
44 
45 class LoadInst;
46 class StoreInst;
47 class VAArgInst;
48 class TargetData;
49 class Pass;
50 class AnalysisUsage;
51 class MemTransferInst;
52 class MemIntrinsic;
53 
54 class AliasAnalysis {
55 protected:
56   const TargetData *TD;
57 
58 private:
59   AliasAnalysis *AA;       // Previous Alias Analysis to chain to.
60 
61 protected:
62   /// InitializeAliasAnalysis - Subclasses must call this method to initialize
63   /// the AliasAnalysis interface before any other methods are called.  This is
64   /// typically called by the run* methods of these subclasses.  This may be
65   /// called multiple times.
66   ///
67   void InitializeAliasAnalysis(Pass *P);
68 
69   /// getAnalysisUsage - All alias analysis implementations should invoke this
70   /// directly (using AliasAnalysis::getAnalysisUsage(AU)).
71   virtual void getAnalysisUsage(AnalysisUsage &AU) const;
72 
73 public:
74   static char ID; // Class identification, replacement for typeinfo
AliasAnalysis()75   AliasAnalysis() : TD(0), AA(0) {}
76   virtual ~AliasAnalysis();  // We want to be subclassed
77 
78   /// UnknownSize - This is a special value which can be used with the
79   /// size arguments in alias queries to indicate that the caller does not
80   /// know the sizes of the potential memory references.
81   static uint64_t const UnknownSize = ~UINT64_C(0);
82 
83   /// getTargetData - Return a pointer to the current TargetData object, or
84   /// null if no TargetData object is available.
85   ///
getTargetData()86   const TargetData *getTargetData() const { return TD; }
87 
88   /// getTypeStoreSize - Return the TargetData store size for the given type,
89   /// if known, or a conservative value otherwise.
90   ///
91   uint64_t getTypeStoreSize(Type *Ty);
92 
93   //===--------------------------------------------------------------------===//
94   /// Alias Queries...
95   ///
96 
97   /// Location - A description of a memory location.
98   struct Location {
99     /// Ptr - The address of the start of the location.
100     const Value *Ptr;
101     /// Size - The maximum size of the location, in address-units, or
102     /// UnknownSize if the size is not known.  Note that an unknown size does
103     /// not mean the pointer aliases the entire virtual address space, because
104     /// there are restrictions on stepping out of one object and into another.
105     /// See http://llvm.org/docs/LangRef.html#pointeraliasing
106     uint64_t Size;
107     /// TBAATag - The metadata node which describes the TBAA type of
108     /// the location, or null if there is no known unique tag.
109     const MDNode *TBAATag;
110 
111     explicit Location(const Value *P = 0, uint64_t S = UnknownSize,
112                       const MDNode *N = 0)
PtrLocation113       : Ptr(P), Size(S), TBAATag(N) {}
114 
getWithNewPtrLocation115     Location getWithNewPtr(const Value *NewPtr) const {
116       Location Copy(*this);
117       Copy.Ptr = NewPtr;
118       return Copy;
119     }
120 
getWithNewSizeLocation121     Location getWithNewSize(uint64_t NewSize) const {
122       Location Copy(*this);
123       Copy.Size = NewSize;
124       return Copy;
125     }
126 
getWithoutTBAATagLocation127     Location getWithoutTBAATag() const {
128       Location Copy(*this);
129       Copy.TBAATag = 0;
130       return Copy;
131     }
132   };
133 
134   /// getLocation - Fill in Loc with information about the memory reference by
135   /// the given instruction.
136   Location getLocation(const LoadInst *LI);
137   Location getLocation(const StoreInst *SI);
138   Location getLocation(const VAArgInst *VI);
139   static Location getLocationForSource(const MemTransferInst *MTI);
140   static Location getLocationForDest(const MemIntrinsic *MI);
141 
142   /// Alias analysis result - Either we know for sure that it does not alias, we
143   /// know for sure it must alias, or we don't know anything: The two pointers
144   /// _might_ alias.  This enum is designed so you can do things like:
145   ///     if (AA.alias(P1, P2)) { ... }
146   /// to check to see if two pointers might alias.
147   ///
148   /// See docs/AliasAnalysis.html for more information on the specific meanings
149   /// of these values.
150   ///
151   enum AliasResult {
152     NoAlias = 0,        ///< No dependencies.
153     MayAlias,           ///< Anything goes.
154     PartialAlias,       ///< Pointers differ, but pointees overlap.
155     MustAlias           ///< Pointers are equal.
156   };
157 
158   /// alias - The main low level interface to the alias analysis implementation.
159   /// Returns an AliasResult indicating whether the two pointers are aliased to
160   /// each other.  This is the interface that must be implemented by specific
161   /// alias analysis implementations.
162   virtual AliasResult alias(const Location &LocA, const Location &LocB);
163 
164   /// alias - A convenience wrapper.
alias(const Value * V1,uint64_t V1Size,const Value * V2,uint64_t V2Size)165   AliasResult alias(const Value *V1, uint64_t V1Size,
166                     const Value *V2, uint64_t V2Size) {
167     return alias(Location(V1, V1Size), Location(V2, V2Size));
168   }
169 
170   /// alias - A convenience wrapper.
alias(const Value * V1,const Value * V2)171   AliasResult alias(const Value *V1, const Value *V2) {
172     return alias(V1, UnknownSize, V2, UnknownSize);
173   }
174 
175   /// isNoAlias - A trivial helper function to check to see if the specified
176   /// pointers are no-alias.
isNoAlias(const Location & LocA,const Location & LocB)177   bool isNoAlias(const Location &LocA, const Location &LocB) {
178     return alias(LocA, LocB) == NoAlias;
179   }
180 
181   /// isNoAlias - A convenience wrapper.
isNoAlias(const Value * V1,uint64_t V1Size,const Value * V2,uint64_t V2Size)182   bool isNoAlias(const Value *V1, uint64_t V1Size,
183                  const Value *V2, uint64_t V2Size) {
184     return isNoAlias(Location(V1, V1Size), Location(V2, V2Size));
185   }
186 
187   /// isMustAlias - A convenience wrapper.
isMustAlias(const Location & LocA,const Location & LocB)188   bool isMustAlias(const Location &LocA, const Location &LocB) {
189     return alias(LocA, LocB) == MustAlias;
190   }
191 
192   /// isMustAlias - A convenience wrapper.
isMustAlias(const Value * V1,const Value * V2)193   bool isMustAlias(const Value *V1, const Value *V2) {
194     return alias(V1, 1, V2, 1) == MustAlias;
195   }
196 
197   /// pointsToConstantMemory - If the specified memory location is
198   /// known to be constant, return true. If OrLocal is true and the
199   /// specified memory location is known to be "local" (derived from
200   /// an alloca), return true. Otherwise return false.
201   virtual bool pointsToConstantMemory(const Location &Loc,
202                                       bool OrLocal = false);
203 
204   /// pointsToConstantMemory - A convenient wrapper.
205   bool pointsToConstantMemory(const Value *P, bool OrLocal = false) {
206     return pointsToConstantMemory(Location(P), OrLocal);
207   }
208 
209   //===--------------------------------------------------------------------===//
210   /// Simple mod/ref information...
211   ///
212 
213   /// ModRefResult - Represent the result of a mod/ref query.  Mod and Ref are
214   /// bits which may be or'd together.
215   ///
216   enum ModRefResult { NoModRef = 0, Ref = 1, Mod = 2, ModRef = 3 };
217 
218   /// These values define additional bits used to define the
219   /// ModRefBehavior values.
220   enum { Nowhere = 0, ArgumentPointees = 4, Anywhere = 8 | ArgumentPointees };
221 
222   /// ModRefBehavior - Summary of how a function affects memory in the program.
223   /// Loads from constant globals are not considered memory accesses for this
224   /// interface.  Also, functions may freely modify stack space local to their
225   /// invocation without having to report it through these interfaces.
226   enum ModRefBehavior {
227     /// DoesNotAccessMemory - This function does not perform any non-local loads
228     /// or stores to memory.
229     ///
230     /// This property corresponds to the GCC 'const' attribute.
231     /// This property corresponds to the LLVM IR 'readnone' attribute.
232     /// This property corresponds to the IntrNoMem LLVM intrinsic flag.
233     DoesNotAccessMemory = Nowhere | NoModRef,
234 
235     /// OnlyReadsArgumentPointees - The only memory references in this function
236     /// (if it has any) are non-volatile loads from objects pointed to by its
237     /// pointer-typed arguments, with arbitrary offsets.
238     ///
239     /// This property corresponds to the IntrReadArgMem LLVM intrinsic flag.
240     OnlyReadsArgumentPointees = ArgumentPointees | Ref,
241 
242     /// OnlyAccessesArgumentPointees - The only memory references in this
243     /// function (if it has any) are non-volatile loads and stores from objects
244     /// pointed to by its pointer-typed arguments, with arbitrary offsets.
245     ///
246     /// This property corresponds to the IntrReadWriteArgMem LLVM intrinsic flag.
247     OnlyAccessesArgumentPointees = ArgumentPointees | ModRef,
248 
249     /// OnlyReadsMemory - This function does not perform any non-local stores or
250     /// volatile loads, but may read from any memory location.
251     ///
252     /// This property corresponds to the GCC 'pure' attribute.
253     /// This property corresponds to the LLVM IR 'readonly' attribute.
254     /// This property corresponds to the IntrReadMem LLVM intrinsic flag.
255     OnlyReadsMemory = Anywhere | Ref,
256 
257     /// UnknownModRefBehavior - This indicates that the function could not be
258     /// classified into one of the behaviors above.
259     UnknownModRefBehavior = Anywhere | ModRef
260   };
261 
262   /// getModRefBehavior - Return the behavior when calling the given call site.
263   virtual ModRefBehavior getModRefBehavior(ImmutableCallSite CS);
264 
265   /// getModRefBehavior - Return the behavior when calling the given function.
266   /// For use when the call site is not known.
267   virtual ModRefBehavior getModRefBehavior(const Function *F);
268 
269   /// doesNotAccessMemory - If the specified call is known to never read or
270   /// write memory, return true.  If the call only reads from known-constant
271   /// memory, it is also legal to return true.  Calls that unwind the stack
272   /// are legal for this predicate.
273   ///
274   /// Many optimizations (such as CSE and LICM) can be performed on such calls
275   /// without worrying about aliasing properties, and many calls have this
276   /// property (e.g. calls to 'sin' and 'cos').
277   ///
278   /// This property corresponds to the GCC 'const' attribute.
279   ///
doesNotAccessMemory(ImmutableCallSite CS)280   bool doesNotAccessMemory(ImmutableCallSite CS) {
281     return getModRefBehavior(CS) == DoesNotAccessMemory;
282   }
283 
284   /// doesNotAccessMemory - If the specified function is known to never read or
285   /// write memory, return true.  For use when the call site is not known.
286   ///
doesNotAccessMemory(const Function * F)287   bool doesNotAccessMemory(const Function *F) {
288     return getModRefBehavior(F) == DoesNotAccessMemory;
289   }
290 
291   /// onlyReadsMemory - If the specified call is known to only read from
292   /// non-volatile memory (or not access memory at all), return true.  Calls
293   /// that unwind the stack are legal for this predicate.
294   ///
295   /// This property allows many common optimizations to be performed in the
296   /// absence of interfering store instructions, such as CSE of strlen calls.
297   ///
298   /// This property corresponds to the GCC 'pure' attribute.
299   ///
onlyReadsMemory(ImmutableCallSite CS)300   bool onlyReadsMemory(ImmutableCallSite CS) {
301     return onlyReadsMemory(getModRefBehavior(CS));
302   }
303 
304   /// onlyReadsMemory - If the specified function is known to only read from
305   /// non-volatile memory (or not access memory at all), return true.  For use
306   /// when the call site is not known.
307   ///
onlyReadsMemory(const Function * F)308   bool onlyReadsMemory(const Function *F) {
309     return onlyReadsMemory(getModRefBehavior(F));
310   }
311 
312   /// onlyReadsMemory - Return true if functions with the specified behavior are
313   /// known to only read from non-volatile memory (or not access memory at all).
314   ///
onlyReadsMemory(ModRefBehavior MRB)315   static bool onlyReadsMemory(ModRefBehavior MRB) {
316     return !(MRB & Mod);
317   }
318 
319   /// onlyAccessesArgPointees - Return true if functions with the specified
320   /// behavior are known to read and write at most from objects pointed to by
321   /// their pointer-typed arguments (with arbitrary offsets).
322   ///
onlyAccessesArgPointees(ModRefBehavior MRB)323   static bool onlyAccessesArgPointees(ModRefBehavior MRB) {
324     return !(MRB & Anywhere & ~ArgumentPointees);
325   }
326 
327   /// doesAccessArgPointees - Return true if functions with the specified
328   /// behavior are known to potentially read or write  from objects pointed
329   /// to be their pointer-typed arguments (with arbitrary offsets).
330   ///
doesAccessArgPointees(ModRefBehavior MRB)331   static bool doesAccessArgPointees(ModRefBehavior MRB) {
332     return (MRB & ModRef) && (MRB & ArgumentPointees);
333   }
334 
335   /// getModRefInfo - Return information about whether or not an instruction may
336   /// read or write the specified memory location.  An instruction
337   /// that doesn't read or write memory may be trivially LICM'd for example.
getModRefInfo(const Instruction * I,const Location & Loc)338   ModRefResult getModRefInfo(const Instruction *I,
339                              const Location &Loc) {
340     switch (I->getOpcode()) {
341     case Instruction::VAArg:  return getModRefInfo((const VAArgInst*)I, Loc);
342     case Instruction::Load:   return getModRefInfo((const LoadInst*)I,  Loc);
343     case Instruction::Store:  return getModRefInfo((const StoreInst*)I, Loc);
344     case Instruction::Call:   return getModRefInfo((const CallInst*)I,  Loc);
345     case Instruction::Invoke: return getModRefInfo((const InvokeInst*)I,Loc);
346     default:                  return NoModRef;
347     }
348   }
349 
350   /// getModRefInfo - A convenience wrapper.
getModRefInfo(const Instruction * I,const Value * P,uint64_t Size)351   ModRefResult getModRefInfo(const Instruction *I,
352                              const Value *P, uint64_t Size) {
353     return getModRefInfo(I, Location(P, Size));
354   }
355 
356   /// getModRefInfo (for call sites) - Return whether information about whether
357   /// a particular call site modifies or reads the specified memory location.
358   virtual ModRefResult getModRefInfo(ImmutableCallSite CS,
359                                      const Location &Loc);
360 
361   /// getModRefInfo (for call sites) - A convenience wrapper.
getModRefInfo(ImmutableCallSite CS,const Value * P,uint64_t Size)362   ModRefResult getModRefInfo(ImmutableCallSite CS,
363                              const Value *P, uint64_t Size) {
364     return getModRefInfo(CS, Location(P, Size));
365   }
366 
367   /// getModRefInfo (for calls) - Return whether information about whether
368   /// a particular call modifies or reads the specified memory location.
getModRefInfo(const CallInst * C,const Location & Loc)369   ModRefResult getModRefInfo(const CallInst *C, const Location &Loc) {
370     return getModRefInfo(ImmutableCallSite(C), Loc);
371   }
372 
373   /// getModRefInfo (for calls) - A convenience wrapper.
getModRefInfo(const CallInst * C,const Value * P,uint64_t Size)374   ModRefResult getModRefInfo(const CallInst *C, const Value *P, uint64_t Size) {
375     return getModRefInfo(C, Location(P, Size));
376   }
377 
378   /// getModRefInfo (for invokes) - Return whether information about whether
379   /// a particular invoke modifies or reads the specified memory location.
getModRefInfo(const InvokeInst * I,const Location & Loc)380   ModRefResult getModRefInfo(const InvokeInst *I,
381                              const Location &Loc) {
382     return getModRefInfo(ImmutableCallSite(I), Loc);
383   }
384 
385   /// getModRefInfo (for invokes) - A convenience wrapper.
getModRefInfo(const InvokeInst * I,const Value * P,uint64_t Size)386   ModRefResult getModRefInfo(const InvokeInst *I,
387                              const Value *P, uint64_t Size) {
388     return getModRefInfo(I, Location(P, Size));
389   }
390 
391   /// getModRefInfo (for loads) - Return whether information about whether
392   /// a particular load modifies or reads the specified memory location.
393   ModRefResult getModRefInfo(const LoadInst *L, const Location &Loc);
394 
395   /// getModRefInfo (for loads) - A convenience wrapper.
getModRefInfo(const LoadInst * L,const Value * P,uint64_t Size)396   ModRefResult getModRefInfo(const LoadInst *L, const Value *P, uint64_t Size) {
397     return getModRefInfo(L, Location(P, Size));
398   }
399 
400   /// getModRefInfo (for stores) - Return whether information about whether
401   /// a particular store modifies or reads the specified memory location.
402   ModRefResult getModRefInfo(const StoreInst *S, const Location &Loc);
403 
404   /// getModRefInfo (for stores) - A convenience wrapper.
getModRefInfo(const StoreInst * S,const Value * P,uint64_t Size)405   ModRefResult getModRefInfo(const StoreInst *S, const Value *P, uint64_t Size){
406     return getModRefInfo(S, Location(P, Size));
407   }
408 
409   /// getModRefInfo (for va_args) - Return whether information about whether
410   /// a particular va_arg modifies or reads the specified memory location.
411   ModRefResult getModRefInfo(const VAArgInst* I, const Location &Loc);
412 
413   /// getModRefInfo (for va_args) - A convenience wrapper.
getModRefInfo(const VAArgInst * I,const Value * P,uint64_t Size)414   ModRefResult getModRefInfo(const VAArgInst* I, const Value* P, uint64_t Size){
415     return getModRefInfo(I, Location(P, Size));
416   }
417 
418   /// getModRefInfo - Return information about whether two call sites may refer
419   /// to the same set of memory locations.  See
420   ///   http://llvm.org/docs/AliasAnalysis.html#ModRefInfo
421   /// for details.
422   virtual ModRefResult getModRefInfo(ImmutableCallSite CS1,
423                                      ImmutableCallSite CS2);
424 
425   //===--------------------------------------------------------------------===//
426   /// Higher level methods for querying mod/ref information.
427   ///
428 
429   /// canBasicBlockModify - Return true if it is possible for execution of the
430   /// specified basic block to modify the value pointed to by Ptr.
431   bool canBasicBlockModify(const BasicBlock &BB, const Location &Loc);
432 
433   /// canBasicBlockModify - A convenience wrapper.
canBasicBlockModify(const BasicBlock & BB,const Value * P,uint64_t Size)434   bool canBasicBlockModify(const BasicBlock &BB, const Value *P, uint64_t Size){
435     return canBasicBlockModify(BB, Location(P, Size));
436   }
437 
438   /// canInstructionRangeModify - Return true if it is possible for the
439   /// execution of the specified instructions to modify the value pointed to by
440   /// Ptr.  The instructions to consider are all of the instructions in the
441   /// range of [I1,I2] INCLUSIVE.  I1 and I2 must be in the same basic block.
442   bool canInstructionRangeModify(const Instruction &I1, const Instruction &I2,
443                                  const Location &Loc);
444 
445   /// canInstructionRangeModify - A convenience wrapper.
canInstructionRangeModify(const Instruction & I1,const Instruction & I2,const Value * Ptr,uint64_t Size)446   bool canInstructionRangeModify(const Instruction &I1, const Instruction &I2,
447                                  const Value *Ptr, uint64_t Size) {
448     return canInstructionRangeModify(I1, I2, Location(Ptr, Size));
449   }
450 
451   //===--------------------------------------------------------------------===//
452   /// Methods that clients should call when they transform the program to allow
453   /// alias analyses to update their internal data structures.  Note that these
454   /// methods may be called on any instruction, regardless of whether or not
455   /// they have pointer-analysis implications.
456   ///
457 
458   /// deleteValue - This method should be called whenever an LLVM Value is
459   /// deleted from the program, for example when an instruction is found to be
460   /// redundant and is eliminated.
461   ///
462   virtual void deleteValue(Value *V);
463 
464   /// copyValue - This method should be used whenever a preexisting value in the
465   /// program is copied or cloned, introducing a new value.  Note that analysis
466   /// implementations should tolerate clients that use this method to introduce
467   /// the same value multiple times: if the analysis already knows about a
468   /// value, it should ignore the request.
469   ///
470   virtual void copyValue(Value *From, Value *To);
471 
472   /// addEscapingUse - This method should be used whenever an escaping use is
473   /// added to a pointer value.  Analysis implementations may either return
474   /// conservative responses for that value in the future, or may recompute
475   /// some or all internal state to continue providing precise responses.
476   ///
477   /// Escaping uses are considered by anything _except_ the following:
478   ///  - GEPs or bitcasts of the pointer
479   ///  - Loads through the pointer
480   ///  - Stores through (but not of) the pointer
481   virtual void addEscapingUse(Use &U);
482 
483   /// replaceWithNewValue - This method is the obvious combination of the two
484   /// above, and it provided as a helper to simplify client code.
485   ///
replaceWithNewValue(Value * Old,Value * New)486   void replaceWithNewValue(Value *Old, Value *New) {
487     copyValue(Old, New);
488     deleteValue(Old);
489   }
490 };
491 
492 // Specialize DenseMapInfo for Location.
493 template<>
494 struct DenseMapInfo<AliasAnalysis::Location> {
495   static inline AliasAnalysis::Location getEmptyKey() {
496     return
497       AliasAnalysis::Location(DenseMapInfo<const Value *>::getEmptyKey(),
498                               0, 0);
499   }
500   static inline AliasAnalysis::Location getTombstoneKey() {
501     return
502       AliasAnalysis::Location(DenseMapInfo<const Value *>::getTombstoneKey(),
503                               0, 0);
504   }
505   static unsigned getHashValue(const AliasAnalysis::Location &Val) {
506     return DenseMapInfo<const Value *>::getHashValue(Val.Ptr) ^
507            DenseMapInfo<uint64_t>::getHashValue(Val.Size) ^
508            DenseMapInfo<const MDNode *>::getHashValue(Val.TBAATag);
509   }
510   static bool isEqual(const AliasAnalysis::Location &LHS,
511                       const AliasAnalysis::Location &RHS) {
512     return LHS.Ptr == RHS.Ptr &&
513            LHS.Size == RHS.Size &&
514            LHS.TBAATag == RHS.TBAATag;
515   }
516 };
517 
518 /// isNoAliasCall - Return true if this pointer is returned by a noalias
519 /// function.
520 bool isNoAliasCall(const Value *V);
521 
522 /// isIdentifiedObject - Return true if this pointer refers to a distinct and
523 /// identifiable object.  This returns true for:
524 ///    Global Variables and Functions (but not Global Aliases)
525 ///    Allocas and Mallocs
526 ///    ByVal and NoAlias Arguments
527 ///    NoAlias returns
528 ///
529 bool isIdentifiedObject(const Value *V);
530 
531 } // End llvm namespace
532 
533 #endif
534