LLVM 22.0.0git
GEPNoWrapFlags.h
Go to the documentation of this file.
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
18namespace 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.
26class 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) {
36 "inbounds implies nusw");
37 }
38
39public:
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 /// Given (gep (gep p, x), y), determine the nowrap flags for (gep p, x+y).
78 GEPNoWrapFlags intersectForOffsetAdd(GEPNoWrapFlags Other) const {
79 GEPNoWrapFlags Res = *this & Other;
80 // Without inbounds, we could only preserve nusw if we know that x + y does
81 // not wrap.
82 if (!Res.isInBounds() && Res.hasNoUnsignedSignedWrap())
84 return Res;
85 }
86
87 /// Given (gep (gep p, x), y), determine the nowrap flags for
88 /// (gep (gep, p, y), x).
89 GEPNoWrapFlags intersectForReassociate(GEPNoWrapFlags Other) const {
90 GEPNoWrapFlags Res = *this & Other;
91 // We can only preserve inbounds and nusw if nuw is also set.
92 if (!Res.hasNoUnsignedWrap())
93 return none();
94 return Res;
95 }
96
97 bool operator==(GEPNoWrapFlags Other) const { return Flags == Other.Flags; }
98 bool operator!=(GEPNoWrapFlags Other) const { return !(*this == Other); }
99
100 GEPNoWrapFlags operator&(GEPNoWrapFlags Other) const {
101 return GEPNoWrapFlags(Flags & Other.Flags);
102 }
103 GEPNoWrapFlags operator|(GEPNoWrapFlags Other) const {
104 return GEPNoWrapFlags(Flags | Other.Flags);
105 }
106 GEPNoWrapFlags &operator&=(GEPNoWrapFlags Other) {
107 Flags &= Other.Flags;
108 return *this;
109 }
110 GEPNoWrapFlags &operator|=(GEPNoWrapFlags Other) {
111 Flags |= Other.Flags;
112 return *this;
113 }
114};
115
116} // end namespace llvm
117
118#endif // LLVM_IR_GEPNOWRAPFLAGS_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
GEPNoWrapFlags & operator|=(GEPNoWrapFlags Other)
static GEPNoWrapFlags inBounds()
GEPNoWrapFlags withoutNoUnsignedSignedWrap() const
bool operator==(GEPNoWrapFlags Other) const
GEPNoWrapFlags & operator&=(GEPNoWrapFlags Other)
GEPNoWrapFlags withoutInBounds() const
static GEPNoWrapFlags fromRaw(unsigned Flags)
static GEPNoWrapFlags all()
static GEPNoWrapFlags noUnsignedWrap()
static GEPNoWrapFlags noUnsignedSignedWrap()
GEPNoWrapFlags intersectForReassociate(GEPNoWrapFlags Other) const
Given (gep (gep p, x), y), determine the nowrap flags for (gep (gep, p, y), x).
GEPNoWrapFlags(bool IsInBounds)
bool hasNoUnsignedSignedWrap() const
bool operator!=(GEPNoWrapFlags Other) const
bool hasNoUnsignedWrap() const
bool isInBounds() const
GEPNoWrapFlags operator&(GEPNoWrapFlags Other) const
GEPNoWrapFlags operator|(GEPNoWrapFlags Other) const
GEPNoWrapFlags intersectForOffsetAdd(GEPNoWrapFlags Other) const
Given (gep (gep p, x), y), determine the nowrap flags for (gep p, x+y).
GEPNoWrapFlags withoutNoUnsignedWrap() const
static GEPNoWrapFlags none()
unsigned getRaw() const
This is an optimization pass for GlobalISel generic memory operations.
@ Other
Any other memory.
Definition ModRef.h:68