Skip to content

Commit e57308b

Browse files
committed
[IR] Accept GEPNoWrapFlags in creation APIs
Add overloads of GetElementPtrInst::Create() that accept GEPNoWrapFlags, and switch the bool parameters in IRBuilder to accept it instead as well. As a sample use, switch GEP i8 canonicalization in InstCombine to preserve the original flags.
1 parent 3b020d5 commit e57308b

File tree

10 files changed

+72
-49
lines changed

10 files changed

+72
-49
lines changed

llvm/include/llvm/Analysis/InstSimplifyFolder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ class InstSimplifyFolder final : public IRBuilderFolder {
7777
}
7878

7979
Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
80-
bool IsInBounds = false) const override {
81-
return simplifyGEPInst(Ty, Ptr, IdxList, IsInBounds, SQ);
80+
GEPNoWrapFlags NW) const override {
81+
return simplifyGEPInst(Ty, Ptr, IdxList, NW, SQ);
8282
}
8383

8484
Value *FoldSelect(Value *C, Value *True, Value *False) const override {

llvm/include/llvm/Analysis/TargetFolder.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,18 +115,15 @@ class TargetFolder final : public IRBuilderFolder {
115115
}
116116

117117
Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
118-
bool IsInBounds = false) const override {
118+
GEPNoWrapFlags NW) const override {
119119
if (!ConstantExpr::isSupportedGetElementPtr(Ty))
120120
return nullptr;
121121

122122
if (auto *PC = dyn_cast<Constant>(Ptr)) {
123123
// Every index must be constant.
124124
if (any_of(IdxList, [](Value *V) { return !isa<Constant>(V); }))
125125
return nullptr;
126-
if (IsInBounds)
127-
return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, PC, IdxList));
128-
else
129-
return Fold(ConstantExpr::getGetElementPtr(Ty, PC, IdxList));
126+
return Fold(ConstantExpr::getGetElementPtr(Ty, PC, IdxList, NW));
130127
}
131128
return nullptr;
132129
}

llvm/include/llvm/IR/ConstantFolder.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class ConstantFolder final : public IRBuilderFolder {
104104
}
105105

106106
Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
107-
bool IsInBounds = false) const override {
107+
GEPNoWrapFlags NW) const override {
108108
if (!ConstantExpr::isSupportedGetElementPtr(Ty))
109109
return nullptr;
110110

@@ -113,10 +113,7 @@ class ConstantFolder final : public IRBuilderFolder {
113113
if (any_of(IdxList, [](Value *V) { return !isa<Constant>(V); }))
114114
return nullptr;
115115

116-
if (IsInBounds)
117-
return ConstantExpr::getInBoundsGetElementPtr(Ty, PC, IdxList);
118-
else
119-
return ConstantExpr::getGetElementPtr(Ty, PC, IdxList);
116+
return ConstantExpr::getGetElementPtr(Ty, PC, IdxList, NW);
120117
}
121118
return nullptr;
122119
}

llvm/include/llvm/IR/IRBuilder.h

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,25 +1864,23 @@ class IRBuilderBase {
18641864
}
18651865

18661866
Value *CreateGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
1867-
const Twine &Name = "", bool IsInBounds = false) {
1868-
if (auto *V = Folder.FoldGEP(Ty, Ptr, IdxList, IsInBounds))
1867+
const Twine &Name = "",
1868+
GEPNoWrapFlags NW = GEPNoWrapFlags::none()) {
1869+
if (auto *V = Folder.FoldGEP(Ty, Ptr, IdxList, NW))
18691870
return V;
1870-
return Insert(IsInBounds
1871-
? GetElementPtrInst::CreateInBounds(Ty, Ptr, IdxList)
1872-
: GetElementPtrInst::Create(Ty, Ptr, IdxList),
1873-
Name);
1871+
return Insert(GetElementPtrInst::Create(Ty, Ptr, IdxList, NW), Name);
18741872
}
18751873

18761874
Value *CreateInBoundsGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
18771875
const Twine &Name = "") {
1878-
return CreateGEP(Ty, Ptr, IdxList, Name, /* IsInBounds */ true);
1876+
return CreateGEP(Ty, Ptr, IdxList, Name, GEPNoWrapFlags::inBounds());
18791877
}
18801878

18811879
Value *CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0,
18821880
const Twine &Name = "") {
18831881
Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
18841882

1885-
if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, /*IsInBounds=*/false))
1883+
if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, GEPNoWrapFlags::none()))
18861884
return V;
18871885

18881886
return Insert(GetElementPtrInst::Create(Ty, Ptr, Idx), Name);
@@ -1892,7 +1890,7 @@ class IRBuilderBase {
18921890
const Twine &Name = "") {
18931891
Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
18941892

1895-
if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, /*IsInBounds=*/true))
1893+
if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, GEPNoWrapFlags::inBounds()))
18961894
return V;
18971895

18981896
return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idx), Name);
@@ -1905,7 +1903,7 @@ class IRBuilderBase {
19051903
ConstantInt::get(Type::getInt32Ty(Context), Idx1)
19061904
};
19071905

1908-
if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, /*IsInBounds=*/false))
1906+
if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, GEPNoWrapFlags::none()))
19091907
return V;
19101908

19111909
return Insert(GetElementPtrInst::Create(Ty, Ptr, Idxs), Name);
@@ -1918,7 +1916,7 @@ class IRBuilderBase {
19181916
ConstantInt::get(Type::getInt32Ty(Context), Idx1)
19191917
};
19201918

1921-
if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, /*IsInBounds=*/true))
1919+
if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, GEPNoWrapFlags::inBounds()))
19221920
return V;
19231921

19241922
return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idxs), Name);
@@ -1928,7 +1926,7 @@ class IRBuilderBase {
19281926
const Twine &Name = "") {
19291927
Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
19301928

1931-
if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, /*IsInBounds=*/false))
1929+
if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, GEPNoWrapFlags::none()))
19321930
return V;
19331931

19341932
return Insert(GetElementPtrInst::Create(Ty, Ptr, Idx), Name);
@@ -1938,7 +1936,7 @@ class IRBuilderBase {
19381936
const Twine &Name = "") {
19391937
Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
19401938

1941-
if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, /*IsInBounds=*/true))
1939+
if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, GEPNoWrapFlags::inBounds()))
19421940
return V;
19431941

19441942
return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idx), Name);
@@ -1951,7 +1949,7 @@ class IRBuilderBase {
19511949
ConstantInt::get(Type::getInt64Ty(Context), Idx1)
19521950
};
19531951

1954-
if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, /*IsInBounds=*/false))
1952+
if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, GEPNoWrapFlags::none()))
19551953
return V;
19561954

19571955
return Insert(GetElementPtrInst::Create(Ty, Ptr, Idxs), Name);
@@ -1964,7 +1962,7 @@ class IRBuilderBase {
19641962
ConstantInt::get(Type::getInt64Ty(Context), Idx1)
19651963
};
19661964

1967-
if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, /*IsInBounds=*/true))
1965+
if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, GEPNoWrapFlags::inBounds()))
19681966
return V;
19691967

19701968
return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idxs), Name);
@@ -1976,13 +1974,14 @@ class IRBuilderBase {
19761974
}
19771975

19781976
Value *CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name = "",
1979-
bool IsInBounds = false) {
1980-
return CreateGEP(getInt8Ty(), Ptr, Offset, Name, IsInBounds);
1977+
GEPNoWrapFlags NW = GEPNoWrapFlags::none()) {
1978+
return CreateGEP(getInt8Ty(), Ptr, Offset, Name, NW);
19811979
}
19821980

19831981
Value *CreateInBoundsPtrAdd(Value *Ptr, Value *Offset,
19841982
const Twine &Name = "") {
1985-
return CreateGEP(getInt8Ty(), Ptr, Offset, Name, /*IsInBounds*/ true);
1983+
return CreateGEP(getInt8Ty(), Ptr, Offset, Name,
1984+
GEPNoWrapFlags::inBounds());
19861985
}
19871986

19881987
/// Same as CreateGlobalString, but return a pointer with "i8*" type

llvm/include/llvm/IR/IRBuilderFolder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class IRBuilderFolder {
5252
Value *RHS) const = 0;
5353

5454
virtual Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
55-
bool IsInBounds = false) const = 0;
55+
GEPNoWrapFlags NW) const = 0;
5656

5757
virtual Value *FoldSelect(Value *C, Value *True, Value *False) const = 0;
5858

llvm/include/llvm/IR/Instructions.h

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,36 +1031,60 @@ class GetElementPtrInst : public Instruction {
10311031
NameStr, InsertAtEnd);
10321032
}
10331033

1034+
static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr,
1035+
ArrayRef<Value *> IdxList, GEPNoWrapFlags NW,
1036+
const Twine &NameStr,
1037+
BasicBlock::iterator InsertBefore) {
1038+
GetElementPtrInst *GEP =
1039+
Create(PointeeType, Ptr, IdxList, NameStr, InsertBefore);
1040+
GEP->setNoWrapFlags(NW);
1041+
return GEP;
1042+
}
1043+
1044+
static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr,
1045+
ArrayRef<Value *> IdxList, GEPNoWrapFlags NW,
1046+
const Twine &NameStr = "",
1047+
Instruction *InsertBefore = nullptr) {
1048+
GetElementPtrInst *GEP =
1049+
Create(PointeeType, Ptr, IdxList, NameStr, InsertBefore);
1050+
GEP->setNoWrapFlags(NW);
1051+
return GEP;
1052+
}
1053+
1054+
static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr,
1055+
ArrayRef<Value *> IdxList, GEPNoWrapFlags NW,
1056+
const Twine &NameStr,
1057+
BasicBlock *InsertAtEnd) {
1058+
GetElementPtrInst *GEP =
1059+
Create(PointeeType, Ptr, IdxList, NameStr, InsertAtEnd);
1060+
GEP->setNoWrapFlags(NW);
1061+
return GEP;
1062+
}
1063+
10341064
/// Create an "inbounds" getelementptr. See the documentation for the
10351065
/// "inbounds" flag in LangRef.html for details.
10361066
static GetElementPtrInst *CreateInBounds(Type *PointeeType, Value *Ptr,
10371067
ArrayRef<Value *> IdxList,
10381068
const Twine &NameStr,
10391069
BasicBlock::iterator InsertBefore) {
1040-
GetElementPtrInst *GEP =
1041-
Create(PointeeType, Ptr, IdxList, NameStr, InsertBefore);
1042-
GEP->setIsInBounds(true);
1043-
return GEP;
1070+
return Create(PointeeType, Ptr, IdxList, GEPNoWrapFlags::inBounds(),
1071+
NameStr, InsertBefore);
10441072
}
10451073

10461074
static GetElementPtrInst *
10471075
CreateInBounds(Type *PointeeType, Value *Ptr, ArrayRef<Value *> IdxList,
10481076
const Twine &NameStr = "",
10491077
Instruction *InsertBefore = nullptr) {
1050-
GetElementPtrInst *GEP =
1051-
Create(PointeeType, Ptr, IdxList, NameStr, InsertBefore);
1052-
GEP->setIsInBounds(true);
1053-
return GEP;
1078+
return Create(PointeeType, Ptr, IdxList, GEPNoWrapFlags::inBounds(),
1079+
NameStr, InsertBefore);
10541080
}
10551081

10561082
static GetElementPtrInst *CreateInBounds(Type *PointeeType, Value *Ptr,
10571083
ArrayRef<Value *> IdxList,
10581084
const Twine &NameStr,
10591085
BasicBlock *InsertAtEnd) {
1060-
GetElementPtrInst *GEP =
1061-
Create(PointeeType, Ptr, IdxList, NameStr, InsertAtEnd);
1062-
GEP->setIsInBounds(true);
1063-
return GEP;
1086+
return Create(PointeeType, Ptr, IdxList, GEPNoWrapFlags::inBounds(),
1087+
NameStr, InsertAtEnd);
10641088
}
10651089

10661090
/// Transparently provide more efficient getOperand methods.

llvm/include/llvm/IR/NoFolder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class NoFolder final : public IRBuilderFolder {
7575
}
7676

7777
Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
78-
bool IsInBounds = false) const override {
78+
GEPNoWrapFlags NW) const override {
7979
return nullptr;
8080
}
8181

llvm/lib/IR/Constants.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3361,11 +3361,8 @@ Instruction *ConstantExpr::getAsInstruction() const {
33613361

33623362
case Instruction::GetElementPtr: {
33633363
const auto *GO = cast<GEPOperator>(this);
3364-
if (GO->isInBounds())
3365-
return GetElementPtrInst::CreateInBounds(GO->getSourceElementType(),
3366-
Ops[0], Ops.slice(1), "");
33673364
return GetElementPtrInst::Create(GO->getSourceElementType(), Ops[0],
3368-
Ops.slice(1), "");
3365+
Ops.slice(1), GO->getNoWrapFlags(), "");
33693366
}
33703367
default:
33713368
assert(getNumOperands() == 2 && "Must be binary operator?");

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2782,7 +2782,7 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
27822782
if (GEP.accumulateConstantOffset(DL, Offset))
27832783
return replaceInstUsesWith(
27842784
GEP, Builder.CreatePtrAdd(PtrOp, Builder.getInt(Offset), "",
2785-
GEP.isInBounds()));
2785+
GEP.getNoWrapFlags()));
27862786
}
27872787

27882788
// Canonicalize scalable GEPs to an explicit offset using the llvm.vscale

llvm/test/Transforms/InstCombine/getelementptr.ll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,4 +1724,13 @@ define ptr @constexpr_gep_of_gep_with_narrow_type() {
17241724
ret ptr getelementptr (i8, ptr getelementptr (i8, ptr @g, i8 127), i8 127)
17251725
}
17261726

1727+
define ptr @gep_to_i8_nusw_nuw(ptr %p) {
1728+
; CHECK-LABEL: @gep_to_i8_nusw_nuw(
1729+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr nusw nuw i8, ptr [[P:%.*]], i64 4
1730+
; CHECK-NEXT: ret ptr [[GEP]]
1731+
;
1732+
%gep = getelementptr nusw nuw i32, ptr %p, i64 1
1733+
ret ptr %gep
1734+
}
1735+
17271736
!0 = !{!"branch_weights", i32 2, i32 10}

0 commit comments

Comments
 (0)