Skip to content

Commit 0171a6b

Browse files
committed
[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)
1 parent d043e4c commit 0171a6b

File tree

5 files changed

+80
-5
lines changed

5 files changed

+80
-5
lines changed

llvm/docs/ReleaseNotes.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,12 @@ They are described in detail in the `debug info migration guide <https://llvm.or
293293
* ``LLVMGetTargetExtTypeNumTypeParams``/``LLVMGetTargetExtTypeTypeParam``
294294
* ``LLVMGetTargetExtTypeNumIntParams``/``LLVMGetTargetExtTypeIntParam``
295295

296+
* Added the following functions for accessing/changing the no-wrap flags for a
297+
GetElementPtr instruction
298+
299+
* ``LLVMGEPGetNoWrapFlags``
300+
* ``LLVMGEPSetNoWrapFlags``
301+
296302
Changes to the CodeGen infrastructure
297303
-------------------------------------
298304

llvm/include/llvm-c/Core.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,20 @@ enum {
510510
*/
511511
typedef unsigned LLVMFastMathFlags;
512512

513+
enum {
514+
LLVMGEPFlagInBounds = (1 << 0),
515+
LLVMGEPFlagNUSW = (1 << 1),
516+
LLVMGEPFlagNUW = (1 << 2),
517+
};
518+
519+
/**
520+
* Flags that constrain the allowed wrap semantics of a getelementptr
521+
* instruction.
522+
*
523+
* See https://llvm.org/docs/LangRef.html#getelementptr-instruction
524+
*/
525+
typedef unsigned LLVMGEPNoWrapFlags;
526+
513527
/**
514528
* @}
515529
*/
@@ -3904,6 +3918,20 @@ void LLVMSetIsInBounds(LLVMValueRef GEP, LLVMBool InBounds);
39043918
*/
39053919
LLVMTypeRef LLVMGetGEPSourceElementType(LLVMValueRef GEP);
39063920

3921+
/**
3922+
* Get the no-wrap related flags for the given GEP instruction.
3923+
*
3924+
* @see llvm::GetElementPtrInst::getNoWrapFlags
3925+
*/
3926+
LLVMGEPNoWrapFlags LLVMGEPGetNoWrapFlags(LLVMValueRef GEP);
3927+
3928+
/**
3929+
* Get the no-wrap related flags for the given GEP instruction.
3930+
*
3931+
* @see llvm::GetElementPtrInst::setNoWrapFlags
3932+
*/
3933+
void LLVMGEPSetNoWrapFlags(LLVMValueRef GEP, LLVMGEPNoWrapFlags WrapFlags);
3934+
39073935
/**
39083936
* @}
39093937
*/

llvm/lib/IR/Core.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3090,6 +3090,30 @@ LLVMTypeRef LLVMGetAllocatedType(LLVMValueRef Alloca) {
30903090

30913091
/*--.. Operations on gep instructions (only) ...............................--*/
30923092

3093+
static GEPNoWrapFlags mapFromLLVMGEPNoWrapFlags(LLVMGEPNoWrapFlags GEPFlags) {
3094+
GEPNoWrapFlags NewGEPFlags;
3095+
if ((GEPFlags & LLVMGEPFlagInBounds) != 0)
3096+
NewGEPFlags |= GEPNoWrapFlags::inBounds();
3097+
if ((GEPFlags & LLVMGEPFlagNUSW) != 0)
3098+
NewGEPFlags |= GEPNoWrapFlags::noUnsignedSignedWrap();
3099+
if ((GEPFlags & LLVMGEPFlagNUW) != 0)
3100+
NewGEPFlags |= GEPNoWrapFlags::noUnsignedWrap();
3101+
3102+
return NewGEPFlags;
3103+
}
3104+
3105+
static LLVMGEPNoWrapFlags mapToLLVMGEPNoWrapFlags(GEPNoWrapFlags GEPFlags) {
3106+
LLVMGEPNoWrapFlags NewGEPFlags = 0;
3107+
if (GEPFlags.isInBounds())
3108+
NewGEPFlags |= LLVMGEPFlagInBounds;
3109+
if (GEPFlags.hasNoUnsignedSignedWrap())
3110+
NewGEPFlags |= LLVMGEPFlagNUSW;
3111+
if (GEPFlags.hasNoUnsignedWrap())
3112+
NewGEPFlags |= LLVMGEPFlagNUW;
3113+
3114+
return NewGEPFlags;
3115+
}
3116+
30933117
LLVMBool LLVMIsInBounds(LLVMValueRef GEP) {
30943118
return unwrap<GEPOperator>(GEP)->isInBounds();
30953119
}
@@ -3102,6 +3126,16 @@ LLVMTypeRef LLVMGetGEPSourceElementType(LLVMValueRef GEP) {
31023126
return wrap(unwrap<GEPOperator>(GEP)->getSourceElementType());
31033127
}
31043128

3129+
LLVMGEPNoWrapFlags LLVMGEPGetNoWrapFlags(LLVMValueRef GEP) {
3130+
GEPOperator *GEPOp = unwrap<GEPOperator>(GEP);
3131+
return mapToLLVMGEPNoWrapFlags(GEPOp->getNoWrapFlags());
3132+
}
3133+
3134+
void LLVMGEPSetNoWrapFlags(LLVMValueRef GEP, LLVMGEPNoWrapFlags WrapFlags) {
3135+
GetElementPtrInst *GEPInst = unwrap<GetElementPtrInst>(GEP);
3136+
GEPInst->setNoWrapFlags(mapFromLLVMGEPNoWrapFlags(WrapFlags));
3137+
}
3138+
31053139
/*--.. Operations on phi nodes .............................................--*/
31063140

31073141
void LLVMAddIncoming(LLVMValueRef PhiNode, LLVMValueRef *IncomingValues,

llvm/test/Bindings/llvm-c/echo.ll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,15 @@ bb_03:
391391
ret void
392392
}
393393

394+
define ptr @test_gep_no_wrap_flags(ptr %0) {
395+
%gep.1 = getelementptr i8, ptr %0, i32 4
396+
%gep.inbounds = getelementptr inbounds i8, ptr %0, i32 4
397+
%gep.nuw = getelementptr nuw i8, ptr %0, i32 4
398+
%gep.nuw.inbounds = getelementptr inbounds nuw i8, ptr %0, i32 4
399+
%gep.nusw = getelementptr nusw i8, ptr %0, i32 4
400+
ret ptr %gep.nusw
401+
}
402+
394403
!llvm.dbg.cu = !{!0, !2}
395404
!llvm.module.flags = !{!3}
396405

llvm/tools/llvm-c-test/echo.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -767,11 +767,9 @@ struct FunCloner {
767767
int NumIdx = LLVMGetNumIndices(Src);
768768
for (int i = 1; i <= NumIdx; i++)
769769
Idx.push_back(CloneValue(LLVMGetOperand(Src, i)));
770-
if (LLVMIsInBounds(Src))
771-
Dst = LLVMBuildInBoundsGEP2(Builder, ElemTy, Ptr, Idx.data(), NumIdx,
772-
Name);
773-
else
774-
Dst = LLVMBuildGEP2(Builder, ElemTy, Ptr, Idx.data(), NumIdx, Name);
770+
771+
Dst = LLVMBuildGEP2(Builder, ElemTy, Ptr, Idx.data(), NumIdx, Name);
772+
LLVMGEPSetNoWrapFlags(Dst, LLVMGEPGetNoWrapFlags(Src));
775773
break;
776774
}
777775
case LLVMAtomicRMW: {

0 commit comments

Comments
 (0)