Skip to content

Commit c878399

Browse files
authored
[C API] Add accessors for new no-wrap flags on GEP instructions (#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).
1 parent bf5d5fe commit c878399

File tree

5 files changed

+135
-9
lines changed

5 files changed

+135
-9
lines changed

llvm/docs/ReleaseNotes.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,14 @@ They are described in detail in the `debug info migration guide <https://llvm.or
309309
* ``LLVMGetTargetExtTypeNumTypeParams``/``LLVMGetTargetExtTypeTypeParam``
310310
* ``LLVMGetTargetExtTypeNumIntParams``/``LLVMGetTargetExtTypeIntParam``
311311

312+
* Added the following functions for accessing/setting the no-wrap flags for a
313+
GetElementPtr instruction:
314+
315+
* ``LLVMBuildGEPWithNoWrapFlags``
316+
* ``LLVMConstGEPWithNoWrapFlags``
317+
* ``LLVMGEPGetNoWrapFlags``
318+
* ``LLVMGEPSetNoWrapFlags``
319+
312320
Changes to the CodeGen infrastructure
313321
-------------------------------------
314322

llvm/include/llvm-c/Core.h

Lines changed: 50 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
*/
@@ -2395,6 +2409,17 @@ LLVMValueRef LLVMConstGEP2(LLVMTypeRef Ty, LLVMValueRef ConstantVal,
23952409
LLVMValueRef LLVMConstInBoundsGEP2(LLVMTypeRef Ty, LLVMValueRef ConstantVal,
23962410
LLVMValueRef *ConstantIndices,
23972411
unsigned NumIndices);
2412+
/**
2413+
* Creates a constant GetElementPtr expression. Similar to LLVMConstGEP2, but
2414+
* allows specifying the no-wrap flags.
2415+
*
2416+
* @see llvm::ConstantExpr::getGetElementPtr()
2417+
*/
2418+
LLVMValueRef LLVMConstGEPWithNoWrapFlags(LLVMTypeRef Ty,
2419+
LLVMValueRef ConstantVal,
2420+
LLVMValueRef *ConstantIndices,
2421+
unsigned NumIndices,
2422+
LLVMGEPNoWrapFlags NoWrapFlags);
23982423
LLVMValueRef LLVMConstTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
23992424
LLVMValueRef LLVMConstPtrToInt(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
24002425
LLVMValueRef LLVMConstIntToPtr(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
@@ -3904,6 +3929,20 @@ void LLVMSetIsInBounds(LLVMValueRef GEP, LLVMBool InBounds);
39043929
*/
39053930
LLVMTypeRef LLVMGetGEPSourceElementType(LLVMValueRef GEP);
39063931

3932+
/**
3933+
* Get the no-wrap related flags for the given GEP instruction.
3934+
*
3935+
* @see llvm::GetElementPtrInst::getNoWrapFlags
3936+
*/
3937+
LLVMGEPNoWrapFlags LLVMGEPGetNoWrapFlags(LLVMValueRef GEP);
3938+
3939+
/**
3940+
* Set the no-wrap related flags for the given GEP instruction.
3941+
*
3942+
* @see llvm::GetElementPtrInst::setNoWrapFlags
3943+
*/
3944+
void LLVMGEPSetNoWrapFlags(LLVMValueRef GEP, LLVMGEPNoWrapFlags NoWrapFlags);
3945+
39073946
/**
39083947
* @}
39093948
*/
@@ -4363,6 +4402,17 @@ LLVMValueRef LLVMBuildGEP2(LLVMBuilderRef B, LLVMTypeRef Ty,
43634402
LLVMValueRef LLVMBuildInBoundsGEP2(LLVMBuilderRef B, LLVMTypeRef Ty,
43644403
LLVMValueRef Pointer, LLVMValueRef *Indices,
43654404
unsigned NumIndices, const char *Name);
4405+
/**
4406+
* Creates a GetElementPtr instruction. Similar to LLVMBuildGEP2, but allows
4407+
* specifying the no-wrap flags.
4408+
*
4409+
* @see llvm::IRBuilder::CreateGEP()
4410+
*/
4411+
LLVMValueRef LLVMBuildGEPWithNoWrapFlags(LLVMBuilderRef B, LLVMTypeRef Ty,
4412+
LLVMValueRef Pointer,
4413+
LLVMValueRef *Indices,
4414+
unsigned NumIndices, const char *Name,
4415+
LLVMGEPNoWrapFlags NoWrapFlags);
43664416
LLVMValueRef LLVMBuildStructGEP2(LLVMBuilderRef B, LLVMTypeRef Ty,
43674417
LLVMValueRef Pointer, unsigned Idx,
43684418
const char *Name);

llvm/lib/IR/Core.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1685,6 +1685,32 @@ static int map_from_llvmopcode(LLVMOpcode code)
16851685
llvm_unreachable("Unhandled Opcode.");
16861686
}
16871687

1688+
/*-- GEP wrap flag conversions */
1689+
1690+
static GEPNoWrapFlags mapFromLLVMGEPNoWrapFlags(LLVMGEPNoWrapFlags GEPFlags) {
1691+
GEPNoWrapFlags NewGEPFlags;
1692+
if ((GEPFlags & LLVMGEPFlagInBounds) != 0)
1693+
NewGEPFlags |= GEPNoWrapFlags::inBounds();
1694+
if ((GEPFlags & LLVMGEPFlagNUSW) != 0)
1695+
NewGEPFlags |= GEPNoWrapFlags::noUnsignedSignedWrap();
1696+
if ((GEPFlags & LLVMGEPFlagNUW) != 0)
1697+
NewGEPFlags |= GEPNoWrapFlags::noUnsignedWrap();
1698+
1699+
return NewGEPFlags;
1700+
}
1701+
1702+
static LLVMGEPNoWrapFlags mapToLLVMGEPNoWrapFlags(GEPNoWrapFlags GEPFlags) {
1703+
LLVMGEPNoWrapFlags NewGEPFlags = 0;
1704+
if (GEPFlags.isInBounds())
1705+
NewGEPFlags |= LLVMGEPFlagInBounds;
1706+
if (GEPFlags.hasNoUnsignedSignedWrap())
1707+
NewGEPFlags |= LLVMGEPFlagNUSW;
1708+
if (GEPFlags.hasNoUnsignedWrap())
1709+
NewGEPFlags |= LLVMGEPFlagNUW;
1710+
1711+
return NewGEPFlags;
1712+
}
1713+
16881714
/*--.. Constant expressions ................................................--*/
16891715

16901716
LLVMOpcode LLVMGetConstOpcode(LLVMValueRef ConstantVal) {
@@ -1789,6 +1815,18 @@ LLVMValueRef LLVMConstInBoundsGEP2(LLVMTypeRef Ty, LLVMValueRef ConstantVal,
17891815
return wrap(ConstantExpr::getInBoundsGetElementPtr(unwrap(Ty), Val, IdxList));
17901816
}
17911817

1818+
LLVMValueRef LLVMConstGEPWithNoWrapFlags(LLVMTypeRef Ty,
1819+
LLVMValueRef ConstantVal,
1820+
LLVMValueRef *ConstantIndices,
1821+
unsigned NumIndices,
1822+
LLVMGEPNoWrapFlags NoWrapFlags) {
1823+
ArrayRef<Constant *> IdxList(unwrap<Constant>(ConstantIndices, NumIndices),
1824+
NumIndices);
1825+
Constant *Val = unwrap<Constant>(ConstantVal);
1826+
return wrap(ConstantExpr::getGetElementPtr(
1827+
unwrap(Ty), Val, IdxList, mapFromLLVMGEPNoWrapFlags(NoWrapFlags)));
1828+
}
1829+
17921830
LLVMValueRef LLVMConstTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType) {
17931831
return wrap(ConstantExpr::getTrunc(unwrap<Constant>(ConstantVal),
17941832
unwrap(ToType)));
@@ -3102,6 +3140,16 @@ LLVMTypeRef LLVMGetGEPSourceElementType(LLVMValueRef GEP) {
31023140
return wrap(unwrap<GEPOperator>(GEP)->getSourceElementType());
31033141
}
31043142

3143+
LLVMGEPNoWrapFlags LLVMGEPGetNoWrapFlags(LLVMValueRef GEP) {
3144+
GEPOperator *GEPOp = unwrap<GEPOperator>(GEP);
3145+
return mapToLLVMGEPNoWrapFlags(GEPOp->getNoWrapFlags());
3146+
}
3147+
3148+
void LLVMGEPSetNoWrapFlags(LLVMValueRef GEP, LLVMGEPNoWrapFlags NoWrapFlags) {
3149+
GetElementPtrInst *GEPInst = unwrap<GetElementPtrInst>(GEP);
3150+
GEPInst->setNoWrapFlags(mapFromLLVMGEPNoWrapFlags(NoWrapFlags));
3151+
}
3152+
31053153
/*--.. Operations on phi nodes .............................................--*/
31063154

31073155
void LLVMAddIncoming(LLVMValueRef PhiNode, LLVMValueRef *IncomingValues,
@@ -3902,6 +3950,16 @@ LLVMValueRef LLVMBuildInBoundsGEP2(LLVMBuilderRef B, LLVMTypeRef Ty,
39023950
unwrap(B)->CreateInBoundsGEP(unwrap(Ty), unwrap(Pointer), IdxList, Name));
39033951
}
39043952

3953+
LLVMValueRef LLVMBuildGEPWithNoWrapFlags(LLVMBuilderRef B, LLVMTypeRef Ty,
3954+
LLVMValueRef Pointer,
3955+
LLVMValueRef *Indices,
3956+
unsigned NumIndices, const char *Name,
3957+
LLVMGEPNoWrapFlags NoWrapFlags) {
3958+
ArrayRef<Value *> IdxList(unwrap(Indices), NumIndices);
3959+
return wrap(unwrap(B)->CreateGEP(unwrap(Ty), unwrap(Pointer), IdxList, Name,
3960+
mapFromLLVMGEPNoWrapFlags(NoWrapFlags)));
3961+
}
3962+
39053963
LLVMValueRef LLVMBuildStructGEP2(LLVMBuilderRef B, LLVMTypeRef Ty,
39063964
LLVMValueRef Pointer, unsigned Idx,
39073965
const char *Name) {

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ module asm "classical GAS"
2525

2626
@const_gep = global ptr getelementptr (i32, ptr @var, i64 2)
2727
@const_inbounds_gep = global ptr getelementptr inbounds (i32, ptr @var, i64 1)
28+
@const_gep_nuw = global ptr getelementptr nuw (i32, ptr @var, i64 1)
29+
@const_gep_nusw = global ptr getelementptr nusw (i32, ptr @var, i64 1)
30+
@const_gep_nuw_inbounds = global ptr getelementptr nuw inbounds (i32, ptr @var, i64 1)
2831

2932
@aliased1 = alias i32, ptr @var
3033
@aliased2 = internal alias i32, ptr @var
@@ -391,6 +394,15 @@ bb_03:
391394
ret void
392395
}
393396

397+
define ptr @test_gep_no_wrap_flags(ptr %0) {
398+
%gep.1 = getelementptr i8, ptr %0, i32 4
399+
%gep.inbounds = getelementptr inbounds i8, ptr %0, i32 4
400+
%gep.nuw = getelementptr nuw i8, ptr %0, i32 4
401+
%gep.nuw.inbounds = getelementptr inbounds nuw i8, ptr %0, i32 4
402+
%gep.nusw = getelementptr nusw i8, ptr %0, i32 4
403+
ret ptr %gep.nusw
404+
}
405+
394406
!llvm.dbg.cu = !{!0, !2}
395407
!llvm.module.flags = !{!3}
396408

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

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -412,10 +412,9 @@ static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M) {
412412
SmallVector<LLVMValueRef, 8> Idx;
413413
for (int i = 1; i <= NumIdx; i++)
414414
Idx.push_back(clone_constant(LLVMGetOperand(Cst, i), M));
415-
if (LLVMIsInBounds(Cst))
416-
return LLVMConstInBoundsGEP2(ElemTy, Ptr, Idx.data(), NumIdx);
417-
else
418-
return LLVMConstGEP2(ElemTy, Ptr, Idx.data(), NumIdx);
415+
416+
return LLVMConstGEPWithNoWrapFlags(ElemTy, Ptr, Idx.data(), NumIdx,
417+
LLVMGEPGetNoWrapFlags(Cst));
419418
}
420419
default:
421420
fprintf(stderr, "%d is not a supported opcode for constant expressions\n",
@@ -767,11 +766,10 @@ struct FunCloner {
767766
int NumIdx = LLVMGetNumIndices(Src);
768767
for (int i = 1; i <= NumIdx; i++)
769768
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);
769+
770+
Dst = LLVMBuildGEPWithNoWrapFlags(Builder, ElemTy, Ptr, Idx.data(),
771+
NumIdx, Name,
772+
LLVMGEPGetNoWrapFlags(Src));
775773
break;
776774
}
777775
case LLVMAtomicRMW: {

0 commit comments

Comments
 (0)