Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:00

0001 //===-- llvm/GEPNoWrapFlags.h - NoWrap flags for GEPs -----------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines the nowrap flags for getelementptr operators.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_IR_GEPNOWRAPFLAGS_H
0014 #define LLVM_IR_GEPNOWRAPFLAGS_H
0015 
0016 #include <assert.h>
0017 
0018 namespace llvm {
0019 
0020 /// Represents flags for the getelementptr instruction/expression.
0021 /// The following flags are supported:
0022 ///  * inbounds (implies nusw)
0023 ///  * nusw (no unsigned signed wrap)
0024 ///  * nuw (no unsigned wrap)
0025 /// See LangRef for a description of their semantics.
0026 class GEPNoWrapFlags {
0027   enum : unsigned {
0028     InBoundsFlag = (1 << 0),
0029     NUSWFlag = (1 << 1),
0030     NUWFlag = (1 << 2),
0031   };
0032 
0033   unsigned Flags;
0034   GEPNoWrapFlags(unsigned Flags) : Flags(Flags) {
0035     assert((!isInBounds() || hasNoUnsignedSignedWrap()) &&
0036            "inbounds implies nusw");
0037   }
0038 
0039 public:
0040   GEPNoWrapFlags() : Flags(0) {}
0041   // For historical reasons, interpret plain boolean as InBounds.
0042   // TODO: Migrate users to pass explicit GEPNoWrapFlags and remove this ctor.
0043   GEPNoWrapFlags(bool IsInBounds)
0044       : Flags(IsInBounds ? (InBoundsFlag | NUSWFlag) : 0) {}
0045 
0046   static GEPNoWrapFlags none() { return GEPNoWrapFlags(); }
0047   static GEPNoWrapFlags all() {
0048     return GEPNoWrapFlags(InBoundsFlag | NUSWFlag | NUWFlag);
0049   }
0050   static GEPNoWrapFlags inBounds() {
0051     return GEPNoWrapFlags(InBoundsFlag | NUSWFlag);
0052   }
0053   static GEPNoWrapFlags noUnsignedSignedWrap() {
0054     return GEPNoWrapFlags(NUSWFlag);
0055   }
0056   static GEPNoWrapFlags noUnsignedWrap() { return GEPNoWrapFlags(NUWFlag); }
0057 
0058   static GEPNoWrapFlags fromRaw(unsigned Flags) {
0059     return GEPNoWrapFlags(Flags);
0060   }
0061   unsigned getRaw() const { return Flags; }
0062 
0063   bool isInBounds() const { return Flags & InBoundsFlag; }
0064   bool hasNoUnsignedSignedWrap() const { return Flags & NUSWFlag; }
0065   bool hasNoUnsignedWrap() const { return Flags & NUWFlag; }
0066 
0067   GEPNoWrapFlags withoutInBounds() const {
0068     return GEPNoWrapFlags(Flags & ~InBoundsFlag);
0069   }
0070   GEPNoWrapFlags withoutNoUnsignedSignedWrap() const {
0071     return GEPNoWrapFlags(Flags & ~(InBoundsFlag | NUSWFlag));
0072   }
0073   GEPNoWrapFlags withoutNoUnsignedWrap() const {
0074     return GEPNoWrapFlags(Flags & ~NUWFlag);
0075   }
0076 
0077   /// Given (gep (gep p, x), y), determine the nowrap flags for (gep p, x+y).
0078   GEPNoWrapFlags intersectForOffsetAdd(GEPNoWrapFlags Other) const {
0079     GEPNoWrapFlags Res = *this & Other;
0080     // Without inbounds, we could only preserve nusw if we know that x + y does
0081     // not wrap.
0082     if (!Res.isInBounds() && Res.hasNoUnsignedSignedWrap())
0083       Res = Res.withoutNoUnsignedSignedWrap();
0084     return Res;
0085   }
0086 
0087   bool operator==(GEPNoWrapFlags Other) const { return Flags == Other.Flags; }
0088   bool operator!=(GEPNoWrapFlags Other) const { return !(*this == Other); }
0089 
0090   GEPNoWrapFlags operator&(GEPNoWrapFlags Other) const {
0091     return GEPNoWrapFlags(Flags & Other.Flags);
0092   }
0093   GEPNoWrapFlags operator|(GEPNoWrapFlags Other) const {
0094     return GEPNoWrapFlags(Flags | Other.Flags);
0095   }
0096   GEPNoWrapFlags &operator&=(GEPNoWrapFlags Other) {
0097     Flags &= Other.Flags;
0098     return *this;
0099   }
0100   GEPNoWrapFlags &operator|=(GEPNoWrapFlags Other) {
0101     Flags |= Other.Flags;
0102     return *this;
0103   }
0104 };
0105 
0106 } // end namespace llvm
0107 
0108 #endif // LLVM_IR_GEPNOWRAPFLAGS_H