Skip to content

Commit e6b4a21

Browse files
authored
[IR] Add utilities for manipulating length of MemIntrinsic [nfc] (#153856)
Goal is simply to reduce direct usage of getLength and setLength so that if we end up moving memset.pattern (whose length is in elements) there are fewer places to audit.
1 parent a4e8ec9 commit e6b4a21

File tree

6 files changed

+24
-17
lines changed

6 files changed

+24
-17
lines changed

llvm/include/llvm/IR/IntrinsicInst.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,13 @@ template <typename Derived> class MemIntrinsicBase : public IntrinsicInst {
987987
const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
988988
Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); }
989989

990+
std::optional<APInt> getLengthInBytes() const {
991+
ConstantInt *C = dyn_cast<ConstantInt>(getLength());
992+
if (!C)
993+
return std::nullopt;
994+
return C->getValue();
995+
}
996+
990997
/// This is just like getRawDest, but it strips off any cast
991998
/// instructions (including addrspacecast) that feed it, giving the
992999
/// original input. The returned value is guaranteed to be a pointer.
@@ -1022,6 +1029,10 @@ template <typename Derived> class MemIntrinsicBase : public IntrinsicInst {
10221029
"setLength called with value of wrong type!");
10231030
setArgOperand(ARG_LENGTH, L);
10241031
}
1032+
1033+
void setLength(uint64_t L) {
1034+
setLength(ConstantInt::get(getLength()->getType(), L));
1035+
}
10251036
};
10261037

10271038
/// Common base class for all memory transfer intrinsics. Simply provides

llvm/lib/CodeGen/SafeStack.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ bool SafeStack::IsMemIntrinsicSafe(const MemIntrinsic *MI, const Use &U,
262262
return true;
263263
}
264264

265-
const auto *Len = dyn_cast<ConstantInt>(MI->getLength());
265+
auto Len = MI->getLengthInBytes();
266266
// Non-constant size => unsafe. FIXME: try SCEV getRange.
267267
if (!Len) return false;
268268
return IsAccessSafe(U, Len->getZExtValue(), AllocaPtr, AllocaSize);

llvm/lib/Transforms/IPO/AttributorAttributes.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2008,9 +2008,8 @@ struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
20082008
// destination) and second (=source) arguments as we know how they are
20092009
// accessed.
20102010
if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) {
2011-
ConstantInt *Length = dyn_cast<ConstantInt>(MI->getLength());
20122011
int64_t LengthVal = AA::RangeTy::Unknown;
2013-
if (Length)
2012+
if (auto Length = MI->getLengthInBytes())
20142013
LengthVal = Length->getSExtValue();
20152014
unsigned ArgNo = getIRPosition().getCallSiteArgNo();
20162015
ChangeStatus Changed = ChangeStatus::UNCHANGED;

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,15 @@ Instruction *InstCombinerImpl::SimplifyAnyMemTransfer(AnyMemTransferInst *MI) {
133133
// wouldn't be constant), and this must be a noop.
134134
if (!isModSet(AA->getModRefInfoMask(MI->getDest()))) {
135135
// Set the size of the copy to 0, it will be deleted on the next iteration.
136-
MI->setLength(Constant::getNullValue(MI->getLength()->getType()));
136+
MI->setLength((uint64_t)0);
137137
return MI;
138138
}
139139

140140
// If the source is provably undef, the memcpy/memmove doesn't do anything
141141
// (unless the transfer is volatile).
142142
if (hasUndefSource(MI) && !MI->isVolatile()) {
143143
// Set the size of the copy to 0, it will be deleted on the next iteration.
144-
MI->setLength(Constant::getNullValue(MI->getLength()->getType()));
144+
MI->setLength((uint64_t)0);
145145
return MI;
146146
}
147147

@@ -211,7 +211,7 @@ Instruction *InstCombinerImpl::SimplifyAnyMemTransfer(AnyMemTransferInst *MI) {
211211
}
212212

213213
// Set the size of the copy to 0, it will be deleted on the next iteration.
214-
MI->setLength(Constant::getNullValue(MemOpLength->getType()));
214+
MI->setLength((uint64_t)0);
215215
return MI;
216216
}
217217

@@ -229,7 +229,7 @@ Instruction *InstCombinerImpl::SimplifyAnyMemSet(AnyMemSetInst *MI) {
229229
// wouldn't be constant), and this must be a noop.
230230
if (!isModSet(AA->getModRefInfoMask(MI->getDest()))) {
231231
// Set the size of the copy to 0, it will be deleted on the next iteration.
232-
MI->setLength(Constant::getNullValue(MI->getLength()->getType()));
232+
MI->setLength((uint64_t)0);
233233
return MI;
234234
}
235235

@@ -238,7 +238,7 @@ Instruction *InstCombinerImpl::SimplifyAnyMemSet(AnyMemSetInst *MI) {
238238
// value. Change to PoisonValue once #52930 is resolved.
239239
if (isa<UndefValue>(MI->getValue())) {
240240
// Set the size of the copy to 0, it will be deleted on the next iteration.
241-
MI->setLength(Constant::getNullValue(MI->getLength()->getType()));
241+
MI->setLength((uint64_t)0);
242242
return MI;
243243
}
244244

@@ -277,7 +277,7 @@ Instruction *InstCombinerImpl::SimplifyAnyMemSet(AnyMemSetInst *MI) {
277277
S->setOrdering(AtomicOrdering::Unordered);
278278

279279
// Set the size of the copy to 0, it will be deleted on the next iteration.
280-
MI->setLength(Constant::getNullValue(LenC->getType()));
280+
MI->setLength((uint64_t)0);
281281
return MI;
282282
}
283283

@@ -1751,9 +1751,9 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
17511751
// Intrinsics cannot occur in an invoke or a callbr, so handle them here
17521752
// instead of in visitCallBase.
17531753
if (auto *MI = dyn_cast<AnyMemIntrinsic>(II)) {
1754-
if (ConstantInt *NumBytes = dyn_cast<ConstantInt>(MI->getLength())) {
1754+
if (auto NumBytes = MI->getLengthInBytes()) {
17551755
// memmove/cpy/set of zero bytes is a noop.
1756-
if (NumBytes->isNullValue())
1756+
if (NumBytes->isZero())
17571757
return eraseInstFromFunction(CI);
17581758

17591759
// For atomic unordered mem intrinsics if len is not a positive or

llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -676,15 +676,13 @@ static bool tryToShorten(Instruction *DeadI, int64_t &DeadStart,
676676
<< "\n KILLER [" << ToRemoveStart << ", "
677677
<< int64_t(ToRemoveStart + ToRemoveSize) << ")\n");
678678

679-
Value *DeadWriteLength = DeadIntrinsic->getLength();
680-
Value *TrimmedLength = ConstantInt::get(DeadWriteLength->getType(), NewSize);
681-
DeadIntrinsic->setLength(TrimmedLength);
679+
DeadIntrinsic->setLength(NewSize);
682680
DeadIntrinsic->setDestAlignment(PrefAlign);
683681

684682
Value *OrigDest = DeadIntrinsic->getRawDest();
685683
if (!IsOverwriteEnd) {
686684
Value *Indices[1] = {
687-
ConstantInt::get(DeadWriteLength->getType(), ToRemoveSize)};
685+
ConstantInt::get(DeadIntrinsic->getLength()->getType(), ToRemoveSize)};
688686
Instruction *NewDestGEP = GetElementPtrInst::CreateInBounds(
689687
Type::getInt8Ty(DeadIntrinsic->getContext()), OrigDest, Indices, "",
690688
DeadI->getIterator());

llvm/lib/Transforms/Scalar/SROA.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3411,8 +3411,7 @@ class AllocaSliceRewriter : public InstVisitor<AllocaSliceRewriter, bool> {
34113411

34123412
// Rewrite the size as needed.
34133413
if (NewEndOffset != EndOffset)
3414-
II.setLength(ConstantInt::get(II.getLength()->getType(),
3415-
NewEndOffset - NewBeginOffset));
3414+
II.setLength(NewEndOffset - NewBeginOffset);
34163415
return false;
34173416
}
34183417
// Record this instruction for deletion.

0 commit comments

Comments
 (0)