-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[C API] Add accessors for new no-wrap flags on GEP instructions #97970
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Previously, only the inbounds flag was accessible via the C API. This adds support for any no-wrap related flags (currently nuw and nusw)
@llvm/pr-subscribers-llvm-ir Author: Benji Smith (Benjins) ChangesPreviously, only the inbounds flag was accessible via the C API. This adds support for any no-wrap related flags (currently nuw and nusw) Full diff: https://github.com/llvm/llvm-project/pull/97970.diff 5 Files Affected:
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index a6bfd55119398..a0b76a8cb1526 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -293,6 +293,12 @@ They are described in detail in the `debug info migration guide <https://llvm.or
* ``LLVMGetTargetExtTypeNumTypeParams``/``LLVMGetTargetExtTypeTypeParam``
* ``LLVMGetTargetExtTypeNumIntParams``/``LLVMGetTargetExtTypeIntParam``
+* Added the following functions for accessing/changing the no-wrap flags for a
+ GetElementPtr instruction
+
+ * ``LLVMGEPGetNoWrapFlags``
+ * ``LLVMGEPSetNoWrapFlags``
+
Changes to the CodeGen infrastructure
-------------------------------------
diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index 9867db4839fe1..db7cebadf20f8 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -510,6 +510,20 @@ enum {
*/
typedef unsigned LLVMFastMathFlags;
+enum {
+ LLVMGEPFlagInBounds = (1 << 0),
+ LLVMGEPFlagNUSW = (1 << 1),
+ LLVMGEPFlagNUW = (1 << 2),
+};
+
+/**
+ * Flags that constrain the allowed wrap semantics of a getelementptr
+ * instruction.
+ *
+ * See https://llvm.org/docs/LangRef.html#getelementptr-instruction
+ */
+typedef unsigned LLVMGEPNoWrapFlags;
+
/**
* @}
*/
@@ -3904,6 +3918,20 @@ void LLVMSetIsInBounds(LLVMValueRef GEP, LLVMBool InBounds);
*/
LLVMTypeRef LLVMGetGEPSourceElementType(LLVMValueRef GEP);
+/**
+ * Get the no-wrap related flags for the given GEP instruction.
+ *
+ * @see llvm::GetElementPtrInst::getNoWrapFlags
+ */
+LLVMGEPNoWrapFlags LLVMGEPGetNoWrapFlags(LLVMValueRef GEP);
+
+/**
+ * Get the no-wrap related flags for the given GEP instruction.
+ *
+ * @see llvm::GetElementPtrInst::setNoWrapFlags
+ */
+void LLVMGEPSetNoWrapFlags(LLVMValueRef GEP, LLVMGEPNoWrapFlags WrapFlags);
+
/**
* @}
*/
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index 9ba7873106043..a9da24e816b2a 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -3090,6 +3090,30 @@ LLVMTypeRef LLVMGetAllocatedType(LLVMValueRef Alloca) {
/*--.. Operations on gep instructions (only) ...............................--*/
+static GEPNoWrapFlags mapFromLLVMGEPNoWrapFlags(LLVMGEPNoWrapFlags GEPFlags) {
+ GEPNoWrapFlags NewGEPFlags;
+ if ((GEPFlags & LLVMGEPFlagInBounds) != 0)
+ NewGEPFlags |= GEPNoWrapFlags::inBounds();
+ if ((GEPFlags & LLVMGEPFlagNUSW) != 0)
+ NewGEPFlags |= GEPNoWrapFlags::noUnsignedSignedWrap();
+ if ((GEPFlags & LLVMGEPFlagNUW) != 0)
+ NewGEPFlags |= GEPNoWrapFlags::noUnsignedWrap();
+
+ return NewGEPFlags;
+}
+
+static LLVMGEPNoWrapFlags mapToLLVMGEPNoWrapFlags(GEPNoWrapFlags GEPFlags) {
+ LLVMGEPNoWrapFlags NewGEPFlags = 0;
+ if (GEPFlags.isInBounds())
+ NewGEPFlags |= LLVMGEPFlagInBounds;
+ if (GEPFlags.hasNoUnsignedSignedWrap())
+ NewGEPFlags |= LLVMGEPFlagNUSW;
+ if (GEPFlags.hasNoUnsignedWrap())
+ NewGEPFlags |= LLVMGEPFlagNUW;
+
+ return NewGEPFlags;
+}
+
LLVMBool LLVMIsInBounds(LLVMValueRef GEP) {
return unwrap<GEPOperator>(GEP)->isInBounds();
}
@@ -3102,6 +3126,16 @@ LLVMTypeRef LLVMGetGEPSourceElementType(LLVMValueRef GEP) {
return wrap(unwrap<GEPOperator>(GEP)->getSourceElementType());
}
+LLVMGEPNoWrapFlags LLVMGEPGetNoWrapFlags(LLVMValueRef GEP) {
+ GEPOperator *GEPOp = unwrap<GEPOperator>(GEP);
+ return mapToLLVMGEPNoWrapFlags(GEPOp->getNoWrapFlags());
+}
+
+void LLVMGEPSetNoWrapFlags(LLVMValueRef GEP, LLVMGEPNoWrapFlags WrapFlags) {
+ GetElementPtrInst *GEPInst = unwrap<GetElementPtrInst>(GEP);
+ GEPInst->setNoWrapFlags(mapFromLLVMGEPNoWrapFlags(WrapFlags));
+}
+
/*--.. Operations on phi nodes .............................................--*/
void LLVMAddIncoming(LLVMValueRef PhiNode, LLVMValueRef *IncomingValues,
diff --git a/llvm/test/Bindings/llvm-c/echo.ll b/llvm/test/Bindings/llvm-c/echo.ll
index dc6f2a9e7d206..5dcaa04f4f72c 100644
--- a/llvm/test/Bindings/llvm-c/echo.ll
+++ b/llvm/test/Bindings/llvm-c/echo.ll
@@ -391,6 +391,15 @@ bb_03:
ret void
}
+define ptr @test_gep_no_wrap_flags(ptr %0) {
+ %gep.1 = getelementptr i8, ptr %0, i32 4
+ %gep.inbounds = getelementptr inbounds i8, ptr %0, i32 4
+ %gep.nuw = getelementptr nuw i8, ptr %0, i32 4
+ %gep.nuw.inbounds = getelementptr inbounds nuw i8, ptr %0, i32 4
+ %gep.nusw = getelementptr nusw i8, ptr %0, i32 4
+ ret ptr %gep.nusw
+}
+
!llvm.dbg.cu = !{!0, !2}
!llvm.module.flags = !{!3}
diff --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp
index 6fa36421810f0..3c7169efde412 100644
--- a/llvm/tools/llvm-c-test/echo.cpp
+++ b/llvm/tools/llvm-c-test/echo.cpp
@@ -767,11 +767,9 @@ struct FunCloner {
int NumIdx = LLVMGetNumIndices(Src);
for (int i = 1; i <= NumIdx; i++)
Idx.push_back(CloneValue(LLVMGetOperand(Src, i)));
- if (LLVMIsInBounds(Src))
- Dst = LLVMBuildInBoundsGEP2(Builder, ElemTy, Ptr, Idx.data(), NumIdx,
- Name);
- else
- Dst = LLVMBuildGEP2(Builder, ElemTy, Ptr, Idx.data(), NumIdx, Name);
+
+ Dst = LLVMBuildGEP2(Builder, ElemTy, Ptr, Idx.data(), NumIdx, Name);
+ LLVMGEPSetNoWrapFlags(Dst, LLVMGEPGetNoWrapFlags(Src));
break;
}
case LLVMAtomicRMW: {
|
…take an explicit set of GEPNoWrapFlags. Also, actually clone the no-wrap flags for constant GEP expressions, and add a test to verify this
ad42b7e
to
26a7ccf
Compare
Bumping this: I added docs for the new GEP builder functions, other feedback should be addressed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
llvm/docs/ReleaseNotes.rst
Outdated
@@ -293,6 +293,14 @@ They are described in detail in the `debug info migration guide <https://llvm.or | |||
* ``LLVMGetTargetExtTypeNumTypeParams``/``LLVMGetTargetExtTypeTypeParam`` | |||
* ``LLVMGetTargetExtTypeNumIntParams``/``LLVMGetTargetExtTypeIntParam`` | |||
|
|||
* Added the following functions for accessing/setting the no-wrap flags for a | |||
GetElementPtr instruction |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GetElementPtr instruction | |
GetElementPtr instruction: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed these
llvm/include/llvm-c/Core.h
Outdated
LLVMGEPNoWrapFlags LLVMGEPGetNoWrapFlags(LLVMValueRef GEP); | ||
|
||
/** | ||
* Get the no-wrap related flags for the given GEP instruction. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Get the no-wrap related flags for the given GEP instruction. | |
* Set the no-wrap related flags for the given GEP instruction. |
llvm/lib/IR/Core.cpp
Outdated
@@ -1685,6 +1685,32 @@ static int map_from_llvmopcode(LLVMOpcode code) | |||
llvm_unreachable("Unhandled Opcode."); | |||
} | |||
|
|||
/*-- GEP wrap flag conversions*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/*-- GEP wrap flag conversions*/ | |
/*-- GEP wrap flag conversions */ |
Summary: Previously, only the inbounds flag was accessible via the C API. This adds support for any no-wrap related flags (currently nuw and nusw). Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60251605
Previously, only the inbounds flag was accessible via the C API. This adds support for any no-wrap related flags (currently nuw and nusw)