Skip to content

Commit 271c620

Browse files
committed
[LLVM-C] Allow LLVM{Get,Set}Volatile to work on memory intrinsics
1 parent 0dff52b commit 271c620

File tree

3 files changed

+112
-0
lines changed

3 files changed

+112
-0
lines changed

llvm/docs/ReleaseNotes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ Changes to the C API
147147
--------------------
148148

149149
* Add `LLVMGetOrInsertFunction` to get or insert a function, replacing the combination of `LLVMGetNamedFunction` and `LLVMAddFunction`.
150+
* Allow `LLVMGetVolatile` and `LLVMSetVolatile` to work on memory intrinsics like `memset`, `memcpy`, and `memmove`.
150151

151152
Changes to the CodeGen infrastructure
152153
-------------------------------------

llvm/lib/IR/Core.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4106,6 +4106,8 @@ LLVMBool LLVMGetVolatile(LLVMValueRef MemAccessInst) {
41064106
return SI->isVolatile();
41074107
if (AtomicRMWInst *AI = dyn_cast<AtomicRMWInst>(P))
41084108
return AI->isVolatile();
4109+
if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(P))
4110+
return MI->isVolatile();
41094111
return cast<AtomicCmpXchgInst>(P)->isVolatile();
41104112
}
41114113

@@ -4117,6 +4119,8 @@ void LLVMSetVolatile(LLVMValueRef MemAccessInst, LLVMBool isVolatile) {
41174119
return SI->setVolatile(isVolatile);
41184120
if (AtomicRMWInst *AI = dyn_cast<AtomicRMWInst>(P))
41194121
return AI->setVolatile(isVolatile);
4122+
if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(P))
4123+
return MI->setVolatile(ConstantInt::getBool(P->getContext(), isVolatile));
41204124
return cast<AtomicCmpXchgInst>(P)->setVolatile(isVolatile);
41214125
}
41224126

llvm/unittests/IR/InstructionsTest.cpp

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1933,5 +1933,112 @@ TEST(InstructionsTest, StripAndAccumulateConstantOffset) {
19331933
EXPECT_TRUE(Offset.isZero());
19341934
}
19351935

1936+
TEST(InstructionsTest, LLVMGetSetVolatile) {
1937+
LLVMContext Ctx;
1938+
Module M("M", Ctx);
1939+
FunctionType *FT = FunctionType::get(Type::getVoidTy(Ctx), {}, false);
1940+
Function *F = Function::Create(FT, Function::ExternalLinkage, "F", M);
1941+
BasicBlock *BB = BasicBlock::Create(Ctx, "entry", F);
1942+
IRBuilder<> B(BB);
1943+
1944+
Type *Int32Ty = Type::getInt32Ty(Ctx);
1945+
Value *Val = B.getInt32(1);
1946+
Value* Ptr = B.CreateAlloca(Int32Ty);
1947+
1948+
// LoadInst
1949+
{
1950+
LoadInst *Load = B.CreateLoad(Int32Ty, Ptr, "");
1951+
1952+
EXPECT_FALSE(LLVMGetVolatile(wrap(Load)));
1953+
LLVMSetVolatile(wrap(Load), true);
1954+
EXPECT_TRUE(LLVMGetVolatile(wrap(Load)));
1955+
LLVMSetVolatile(wrap(Load), false);
1956+
EXPECT_FALSE(LLVMGetVolatile(wrap(Load)));
1957+
}
1958+
1959+
// StoreInst
1960+
{
1961+
StoreInst *Store = B.CreateStore(Val, Ptr);
1962+
1963+
EXPECT_FALSE(LLVMGetVolatile(wrap(Store)));
1964+
LLVMSetVolatile(wrap(Store), true);
1965+
EXPECT_TRUE(LLVMGetVolatile(wrap(Store)));
1966+
LLVMSetVolatile(wrap(Store), false);
1967+
EXPECT_FALSE(LLVMGetVolatile(wrap(Store)));
1968+
}
1969+
1970+
// AtomicRMWInst
1971+
{
1972+
AtomicRMWInst *RMW =
1973+
B.CreateAtomicRMW(AtomicRMWInst::Add, Ptr, Val,
1974+
MaybeAlign(), AtomicOrdering::Monotonic);
1975+
1976+
EXPECT_FALSE(LLVMGetVolatile(wrap(RMW)));
1977+
LLVMSetVolatile(wrap(RMW), true);
1978+
EXPECT_TRUE(LLVMGetVolatile(wrap(RMW)));
1979+
LLVMSetVolatile(wrap(RMW), false);
1980+
EXPECT_FALSE(LLVMGetVolatile(wrap(RMW)));
1981+
}
1982+
1983+
// MemCpy
1984+
{
1985+
CallInst *MemCpy =
1986+
B.CreateMemCpy(Ptr, MaybeAlign(), Ptr, MaybeAlign(), 4);
1987+
1988+
EXPECT_FALSE(LLVMGetVolatile(wrap(MemCpy)));
1989+
LLVMSetVolatile(wrap(MemCpy), true);
1990+
EXPECT_TRUE(LLVMGetVolatile(wrap(MemCpy)));
1991+
LLVMSetVolatile(wrap(MemCpy), false);
1992+
EXPECT_FALSE(LLVMGetVolatile(wrap(MemCpy)));
1993+
}
1994+
1995+
// MemMove
1996+
{
1997+
CallInst *MemMove =
1998+
B.CreateMemMove(Ptr, MaybeAlign(), Ptr, MaybeAlign(), 4);
1999+
2000+
EXPECT_FALSE(LLVMGetVolatile(wrap(MemMove)));
2001+
LLVMSetVolatile(wrap(MemMove), true);
2002+
EXPECT_TRUE(LLVMGetVolatile(wrap(MemMove)));
2003+
LLVMSetVolatile(wrap(MemMove), false);
2004+
EXPECT_FALSE(LLVMGetVolatile(wrap(MemMove)));
2005+
}
2006+
2007+
// MemSet
2008+
{
2009+
CallInst *MemSet = B.CreateMemSet(Ptr, B.getInt8(0), 1, Align(1));
2010+
2011+
EXPECT_FALSE(LLVMGetVolatile(wrap(MemSet)));
2012+
LLVMSetVolatile(wrap(MemSet), true);
2013+
EXPECT_TRUE(LLVMGetVolatile(wrap(MemSet)));
2014+
LLVMSetVolatile(wrap(MemSet), false);
2015+
EXPECT_FALSE(LLVMGetVolatile(wrap(MemSet)));
2016+
}
2017+
2018+
// MemSetInline
2019+
{
2020+
CallInst *MemSetInline =
2021+
B.CreateMemSetInline(Ptr, Align(1), B.getInt8(0), Val);
2022+
2023+
EXPECT_FALSE(LLVMGetVolatile(wrap(MemSetInline)));
2024+
LLVMSetVolatile(wrap(MemSetInline), true);
2025+
EXPECT_TRUE(LLVMGetVolatile(wrap(MemSetInline)));
2026+
LLVMSetVolatile(wrap(MemSetInline), false);
2027+
EXPECT_FALSE(LLVMGetVolatile(wrap(MemSetInline)));
2028+
}
2029+
2030+
// MemCpyInline
2031+
{
2032+
CallInst *MemCpyInline = B.CreateMemCpyInline(
2033+
Ptr, MaybeAlign(), Val, MaybeAlign(), Val);
2034+
2035+
EXPECT_FALSE(LLVMGetVolatile(wrap(MemCpyInline)));
2036+
LLVMSetVolatile(wrap(MemCpyInline), true);
2037+
EXPECT_TRUE(LLVMGetVolatile(wrap(MemCpyInline)));
2038+
LLVMSetVolatile(wrap(MemCpyInline), false);
2039+
EXPECT_FALSE(LLVMGetVolatile(wrap(MemCpyInline)));
2040+
}
2041+
}
2042+
19362043
} // end anonymous namespace
19372044
} // end namespace llvm

0 commit comments

Comments
 (0)