[llvm] [C API] Add accessors for new no-wrap flags on GEP instructions (PR #97970)
Benji Smith via llvm-commits
llvm-commits at lists.llvm.org
Sun Jul 7 12:19:08 PDT 2024
https://github.com/Benjins created https://github.com/llvm/llvm-project/pull/97970
Previously, only the inbounds flag was accessible via the C API. This adds support for any no-wrap related flags (currently nuw and nusw)
>From 0171a6b03cb62061d304b1e4929ae861d9b540ed Mon Sep 17 00:00:00 2001
From: Benji Smith <benjsith at gmail.com>
Date: Sun, 7 Jul 2024 14:04:26 -0400
Subject: [PATCH] [C API] Add accessors for new no-wrap flags on GEP
instructions
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/docs/ReleaseNotes.rst | 6 ++++++
llvm/include/llvm-c/Core.h | 28 +++++++++++++++++++++++++
llvm/lib/IR/Core.cpp | 34 +++++++++++++++++++++++++++++++
llvm/test/Bindings/llvm-c/echo.ll | 9 ++++++++
llvm/tools/llvm-c-test/echo.cpp | 8 +++-----
5 files changed, 80 insertions(+), 5 deletions(-)
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: {
More information about the llvm-commits
mailing list