xref: /freebsd/contrib/llvm-project/llvm/include/llvm/IR/GEPNoWrapFlags.h (revision 7ab1a32cd43cbae61ad4dd435d6a482bbf61cb52)
1 //===-- llvm/GEPNoWrapFlags.h - NoWrap flags for GEPs -----------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the nowrap flags for getelementptr operators.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_IR_GEPNOWRAPFLAGS_H
14 #define LLVM_IR_GEPNOWRAPFLAGS_H
15 
16 #include <assert.h>
17 
18 namespace llvm {
19 
20 /// Represents flags for the getelementptr instruction/expression.
21 /// The following flags are supported:
22 ///  * inbounds (implies nusw)
23 ///  * nusw (no unsigned signed wrap)
24 ///  * nuw (no unsigned wrap)
25 /// See LangRef for a description of their semantics.
26 class GEPNoWrapFlags {
27   enum : unsigned {
28     InBoundsFlag = (1 << 0),
29     NUSWFlag = (1 << 1),
30     NUWFlag = (1 << 2),
31   };
32 
33   unsigned Flags;
34   GEPNoWrapFlags(unsigned Flags) : Flags(Flags) {
35     assert((!isInBounds() || hasNoUnsignedSignedWrap()) &&
36            "inbounds implies nusw");
37   }
38 
39 public:
40   GEPNoWrapFlags() : Flags(0) {}
41   // For historical reasons, interpret plain boolean as InBounds.
42   // TODO: Migrate users to pass explicit GEPNoWrapFlags and remove this ctor.
43   GEPNoWrapFlags(bool IsInBounds)
44       : Flags(IsInBounds ? (InBoundsFlag | NUSWFlag) : 0) {}
45 
46   static GEPNoWrapFlags none() { return GEPNoWrapFlags(); }
47   static GEPNoWrapFlags all() {
48     return GEPNoWrapFlags(InBoundsFlag | NUSWFlag | NUWFlag);
49   }
50   static GEPNoWrapFlags inBounds() {
51     return GEPNoWrapFlags(InBoundsFlag | NUSWFlag);
52   }
53   static GEPNoWrapFlags noUnsignedSignedWrap() {
54     return GEPNoWrapFlags(NUSWFlag);
55   }
56   static GEPNoWrapFlags noUnsignedWrap() { return GEPNoWrapFlags(NUWFlag); }
57 
58   static GEPNoWrapFlags fromRaw(unsigned Flags) {
59     return GEPNoWrapFlags(Flags);
60   }
61   unsigned getRaw() const { return Flags; }
62 
63   bool isInBounds() const { return Flags & InBoundsFlag; }
64   bool hasNoUnsignedSignedWrap() const { return Flags & NUSWFlag; }
65   bool hasNoUnsignedWrap() const { return Flags & NUWFlag; }
66 
67   GEPNoWrapFlags withoutInBounds() const {
68     return GEPNoWrapFlags(Flags & ~InBoundsFlag);
69   }
70   GEPNoWrapFlags withoutNoUnsignedSignedWrap() const {
71     return GEPNoWrapFlags(Flags & ~(InBoundsFlag | NUSWFlag));
72   }
73   GEPNoWrapFlags withoutNoUnsignedWrap() const {
74     return GEPNoWrapFlags(Flags & ~NUWFlag);
75   }
76 
77   bool operator==(GEPNoWrapFlags Other) const { return Flags == Other.Flags; }
78   bool operator!=(GEPNoWrapFlags Other) const { return !(*this == Other); }
79 
80   GEPNoWrapFlags operator&(GEPNoWrapFlags Other) const {
81     return GEPNoWrapFlags(Flags & Other.Flags);
82   }
83   GEPNoWrapFlags operator|(GEPNoWrapFlags Other) const {
84     return GEPNoWrapFlags(Flags | Other.Flags);
85   }
86   GEPNoWrapFlags &operator&=(GEPNoWrapFlags Other) {
87     Flags &= Other.Flags;
88     return *this;
89   }
90   GEPNoWrapFlags &operator|=(GEPNoWrapFlags Other) {
91     Flags |= Other.Flags;
92     return *this;
93   }
94 };
95 
96 } // end namespace llvm
97 
98 #endif // LLVM_IR_GEPNOWRAPFLAGS_H
99