[llvm] e57308b - [IR] Accept GEPNoWrapFlags in creation APIs
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 4 05:08:41 PDT 2024
Author: Nikita Popov
Date: 2024-06-04T14:08:33+02:00
New Revision: e57308b063bb2399b9524222d757609797d331fc
URL: https://github.com/llvm/llvm-project/commit/e57308b063bb2399b9524222d757609797d331fc
DIFF: https://github.com/llvm/llvm-project/commit/e57308b063bb2399b9524222d757609797d331fc.diff
LOG: [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.
Added:
Modified:
llvm/include/llvm/Analysis/InstSimplifyFolder.h
llvm/include/llvm/Analysis/TargetFolder.h
llvm/include/llvm/IR/ConstantFolder.h
llvm/include/llvm/IR/IRBuilder.h
llvm/include/llvm/IR/IRBuilderFolder.h
llvm/include/llvm/IR/Instructions.h
llvm/include/llvm/IR/NoFolder.h
llvm/lib/IR/Constants.cpp
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
llvm/test/Transforms/InstCombine/getelementptr.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/InstSimplifyFolder.h b/llvm/include/llvm/Analysis/InstSimplifyFolder.h
index 98c7c291fea1f..6b3da534631a8 100644
--- a/llvm/include/llvm/Analysis/InstSimplifyFolder.h
+++ b/llvm/include/llvm/Analysis/InstSimplifyFolder.h
@@ -77,8 +77,8 @@ class InstSimplifyFolder final : public IRBuilderFolder {
}
Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
- bool IsInBounds = false) const override {
- return simplifyGEPInst(Ty, Ptr, IdxList, IsInBounds, SQ);
+ GEPNoWrapFlags NW) const override {
+ return simplifyGEPInst(Ty, Ptr, IdxList, NW, SQ);
}
Value *FoldSelect(Value *C, Value *True, Value *False) const override {
diff --git a/llvm/include/llvm/Analysis/TargetFolder.h b/llvm/include/llvm/Analysis/TargetFolder.h
index 26ec4dcef6df4..4c78211b5c935 100644
--- a/llvm/include/llvm/Analysis/TargetFolder.h
+++ b/llvm/include/llvm/Analysis/TargetFolder.h
@@ -115,7 +115,7 @@ class TargetFolder final : public IRBuilderFolder {
}
Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
- bool IsInBounds = false) const override {
+ GEPNoWrapFlags NW) const override {
if (!ConstantExpr::isSupportedGetElementPtr(Ty))
return nullptr;
@@ -123,10 +123,7 @@ class TargetFolder final : public IRBuilderFolder {
// Every index must be constant.
if (any_of(IdxList, [](Value *V) { return !isa<Constant>(V); }))
return nullptr;
- if (IsInBounds)
- return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, PC, IdxList));
- else
- return Fold(ConstantExpr::getGetElementPtr(Ty, PC, IdxList));
+ return Fold(ConstantExpr::getGetElementPtr(Ty, PC, IdxList, NW));
}
return nullptr;
}
diff --git a/llvm/include/llvm/IR/ConstantFolder.h b/llvm/include/llvm/IR/ConstantFolder.h
index 65467bdbb3038..a75cdf97f6ed3 100644
--- a/llvm/include/llvm/IR/ConstantFolder.h
+++ b/llvm/include/llvm/IR/ConstantFolder.h
@@ -104,7 +104,7 @@ class ConstantFolder final : public IRBuilderFolder {
}
Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
- bool IsInBounds = false) const override {
+ GEPNoWrapFlags NW) const override {
if (!ConstantExpr::isSupportedGetElementPtr(Ty))
return nullptr;
@@ -113,10 +113,7 @@ class ConstantFolder final : public IRBuilderFolder {
if (any_of(IdxList, [](Value *V) { return !isa<Constant>(V); }))
return nullptr;
- if (IsInBounds)
- return ConstantExpr::getInBoundsGetElementPtr(Ty, PC, IdxList);
- else
- return ConstantExpr::getGetElementPtr(Ty, PC, IdxList);
+ return ConstantExpr::getGetElementPtr(Ty, PC, IdxList, NW);
}
return nullptr;
}
diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h
index 40a9cf507248a..4d785eb6ae832 100644
--- a/llvm/include/llvm/IR/IRBuilder.h
+++ b/llvm/include/llvm/IR/IRBuilder.h
@@ -1864,25 +1864,23 @@ class IRBuilderBase {
}
Value *CreateGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
- const Twine &Name = "", bool IsInBounds = false) {
- if (auto *V = Folder.FoldGEP(Ty, Ptr, IdxList, IsInBounds))
+ const Twine &Name = "",
+ GEPNoWrapFlags NW = GEPNoWrapFlags::none()) {
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, IdxList, NW))
return V;
- return Insert(IsInBounds
- ? GetElementPtrInst::CreateInBounds(Ty, Ptr, IdxList)
- : GetElementPtrInst::Create(Ty, Ptr, IdxList),
- Name);
+ return Insert(GetElementPtrInst::Create(Ty, Ptr, IdxList, NW), Name);
}
Value *CreateInBoundsGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
const Twine &Name = "") {
- return CreateGEP(Ty, Ptr, IdxList, Name, /* IsInBounds */ true);
+ return CreateGEP(Ty, Ptr, IdxList, Name, GEPNoWrapFlags::inBounds());
}
Value *CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0,
const Twine &Name = "") {
Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
- if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, /*IsInBounds=*/false))
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, GEPNoWrapFlags::none()))
return V;
return Insert(GetElementPtrInst::Create(Ty, Ptr, Idx), Name);
@@ -1892,7 +1890,7 @@ class IRBuilderBase {
const Twine &Name = "") {
Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
- if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, /*IsInBounds=*/true))
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, GEPNoWrapFlags::inBounds()))
return V;
return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idx), Name);
@@ -1905,7 +1903,7 @@ class IRBuilderBase {
ConstantInt::get(Type::getInt32Ty(Context), Idx1)
};
- if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, /*IsInBounds=*/false))
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, GEPNoWrapFlags::none()))
return V;
return Insert(GetElementPtrInst::Create(Ty, Ptr, Idxs), Name);
@@ -1918,7 +1916,7 @@ class IRBuilderBase {
ConstantInt::get(Type::getInt32Ty(Context), Idx1)
};
- if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, /*IsInBounds=*/true))
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, GEPNoWrapFlags::inBounds()))
return V;
return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idxs), Name);
@@ -1928,7 +1926,7 @@ class IRBuilderBase {
const Twine &Name = "") {
Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
- if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, /*IsInBounds=*/false))
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, GEPNoWrapFlags::none()))
return V;
return Insert(GetElementPtrInst::Create(Ty, Ptr, Idx), Name);
@@ -1938,7 +1936,7 @@ class IRBuilderBase {
const Twine &Name = "") {
Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
- if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, /*IsInBounds=*/true))
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, GEPNoWrapFlags::inBounds()))
return V;
return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idx), Name);
@@ -1951,7 +1949,7 @@ class IRBuilderBase {
ConstantInt::get(Type::getInt64Ty(Context), Idx1)
};
- if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, /*IsInBounds=*/false))
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, GEPNoWrapFlags::none()))
return V;
return Insert(GetElementPtrInst::Create(Ty, Ptr, Idxs), Name);
@@ -1964,7 +1962,7 @@ class IRBuilderBase {
ConstantInt::get(Type::getInt64Ty(Context), Idx1)
};
- if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, /*IsInBounds=*/true))
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, GEPNoWrapFlags::inBounds()))
return V;
return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idxs), Name);
@@ -1976,13 +1974,14 @@ class IRBuilderBase {
}
Value *CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name = "",
- bool IsInBounds = false) {
- return CreateGEP(getInt8Ty(), Ptr, Offset, Name, IsInBounds);
+ GEPNoWrapFlags NW = GEPNoWrapFlags::none()) {
+ return CreateGEP(getInt8Ty(), Ptr, Offset, Name, NW);
}
Value *CreateInBoundsPtrAdd(Value *Ptr, Value *Offset,
const Twine &Name = "") {
- return CreateGEP(getInt8Ty(), Ptr, Offset, Name, /*IsInBounds*/ true);
+ return CreateGEP(getInt8Ty(), Ptr, Offset, Name,
+ GEPNoWrapFlags::inBounds());
}
/// Same as CreateGlobalString, but return a pointer with "i8*" type
diff --git a/llvm/include/llvm/IR/IRBuilderFolder.h b/llvm/include/llvm/IR/IRBuilderFolder.h
index f474c3a0206b1..3c42eb2cf2a5a 100644
--- a/llvm/include/llvm/IR/IRBuilderFolder.h
+++ b/llvm/include/llvm/IR/IRBuilderFolder.h
@@ -52,7 +52,7 @@ class IRBuilderFolder {
Value *RHS) const = 0;
virtual Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
- bool IsInBounds = false) const = 0;
+ GEPNoWrapFlags NW) const = 0;
virtual Value *FoldSelect(Value *C, Value *True, Value *False) const = 0;
diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h
index 8d7c2b0c957dd..d0a051560fc9a 100644
--- a/llvm/include/llvm/IR/Instructions.h
+++ b/llvm/include/llvm/IR/Instructions.h
@@ -1031,36 +1031,60 @@ class GetElementPtrInst : public Instruction {
NameStr, InsertAtEnd);
}
+ static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList, GEPNoWrapFlags NW,
+ const Twine &NameStr,
+ BasicBlock::iterator InsertBefore) {
+ GetElementPtrInst *GEP =
+ Create(PointeeType, Ptr, IdxList, NameStr, InsertBefore);
+ GEP->setNoWrapFlags(NW);
+ return GEP;
+ }
+
+ static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList, GEPNoWrapFlags NW,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = nullptr) {
+ GetElementPtrInst *GEP =
+ Create(PointeeType, Ptr, IdxList, NameStr, InsertBefore);
+ GEP->setNoWrapFlags(NW);
+ return GEP;
+ }
+
+ static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList, GEPNoWrapFlags NW,
+ const Twine &NameStr,
+ BasicBlock *InsertAtEnd) {
+ GetElementPtrInst *GEP =
+ Create(PointeeType, Ptr, IdxList, NameStr, InsertAtEnd);
+ GEP->setNoWrapFlags(NW);
+ return GEP;
+ }
+
/// Create an "inbounds" getelementptr. See the documentation for the
/// "inbounds" flag in LangRef.html for details.
static GetElementPtrInst *CreateInBounds(Type *PointeeType, Value *Ptr,
ArrayRef<Value *> IdxList,
const Twine &NameStr,
BasicBlock::iterator InsertBefore) {
- GetElementPtrInst *GEP =
- Create(PointeeType, Ptr, IdxList, NameStr, InsertBefore);
- GEP->setIsInBounds(true);
- return GEP;
+ return Create(PointeeType, Ptr, IdxList, GEPNoWrapFlags::inBounds(),
+ NameStr, InsertBefore);
}
static GetElementPtrInst *
CreateInBounds(Type *PointeeType, Value *Ptr, ArrayRef<Value *> IdxList,
const Twine &NameStr = "",
Instruction *InsertBefore = nullptr) {
- GetElementPtrInst *GEP =
- Create(PointeeType, Ptr, IdxList, NameStr, InsertBefore);
- GEP->setIsInBounds(true);
- return GEP;
+ return Create(PointeeType, Ptr, IdxList, GEPNoWrapFlags::inBounds(),
+ NameStr, InsertBefore);
}
static GetElementPtrInst *CreateInBounds(Type *PointeeType, Value *Ptr,
ArrayRef<Value *> IdxList,
const Twine &NameStr,
BasicBlock *InsertAtEnd) {
- GetElementPtrInst *GEP =
- Create(PointeeType, Ptr, IdxList, NameStr, InsertAtEnd);
- GEP->setIsInBounds(true);
- return GEP;
+ return Create(PointeeType, Ptr, IdxList, GEPNoWrapFlags::inBounds(),
+ NameStr, InsertAtEnd);
}
/// Transparently provide more efficient getOperand methods.
diff --git a/llvm/include/llvm/IR/NoFolder.h b/llvm/include/llvm/IR/NoFolder.h
index 72ab22c0d2949..c4631a9ba1cbf 100644
--- a/llvm/include/llvm/IR/NoFolder.h
+++ b/llvm/include/llvm/IR/NoFolder.h
@@ -75,7 +75,7 @@ class NoFolder final : public IRBuilderFolder {
}
Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
- bool IsInBounds = false) const override {
+ GEPNoWrapFlags NW) const override {
return nullptr;
}
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index ecc15f097f14d..a76be441875a1 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -3361,11 +3361,8 @@ Instruction *ConstantExpr::getAsInstruction() const {
case Instruction::GetElementPtr: {
const auto *GO = cast<GEPOperator>(this);
- if (GO->isInBounds())
- return GetElementPtrInst::CreateInBounds(GO->getSourceElementType(),
- Ops[0], Ops.slice(1), "");
return GetElementPtrInst::Create(GO->getSourceElementType(), Ops[0],
- Ops.slice(1), "");
+ Ops.slice(1), GO->getNoWrapFlags(), "");
}
default:
assert(getNumOperands() == 2 && "Must be binary operator?");
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 39a87e267e00e..0d96d461941c6 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2782,7 +2782,7 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
if (GEP.accumulateConstantOffset(DL, Offset))
return replaceInstUsesWith(
GEP, Builder.CreatePtrAdd(PtrOp, Builder.getInt(Offset), "",
- GEP.isInBounds()));
+ GEP.getNoWrapFlags()));
}
// Canonicalize scalable GEPs to an explicit offset using the llvm.vscale
diff --git a/llvm/test/Transforms/InstCombine/getelementptr.ll b/llvm/test/Transforms/InstCombine/getelementptr.ll
index dc7ecd1f52638..d5cfb74a44430 100644
--- a/llvm/test/Transforms/InstCombine/getelementptr.ll
+++ b/llvm/test/Transforms/InstCombine/getelementptr.ll
@@ -1724,4 +1724,13 @@ define ptr @constexpr_gep_of_gep_with_narrow_type() {
ret ptr getelementptr (i8, ptr getelementptr (i8, ptr @g, i8 127), i8 127)
}
+define ptr @gep_to_i8_nusw_nuw(ptr %p) {
+; CHECK-LABEL: @gep_to_i8_nusw_nuw(
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr nusw nuw i8, ptr [[P:%.*]], i64 4
+; CHECK-NEXT: ret ptr [[GEP]]
+;
+ %gep = getelementptr nusw nuw i32, ptr %p, i64 1
+ ret ptr %gep
+}
+
!0 = !{!"branch_weights", i32 2, i32 10}
More information about the llvm-commits
mailing list