Skip to content

Commit ac4b6b6

Browse files
committed
Revert "[Intrinsics][PreISelInstrinsicLowering] llvm.memcpy.inline length no longer needs to be constant (#98281)"
This reverts commit 522fd53 while unexpected mlir failures are investigated and resolved.
1 parent 473ed8e commit ac4b6b6

File tree

7 files changed

+32
-69
lines changed

7 files changed

+32
-69
lines changed

llvm/docs/LangRef.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15026,7 +15026,7 @@ Arguments:
1502615026
""""""""""
1502715027

1502815028
The first argument is a pointer to the destination, the second is a
15029-
pointer to the source. The third argument is an integer argument
15029+
pointer to the source. The third argument is a constant integer argument
1503015030
specifying the number of bytes to copy, and the fourth is a
1503115031
boolean indicating a volatile access.
1503215032

llvm/include/llvm/IR/IntrinsicInst.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,9 @@ class MemMoveInst : public MemTransferInst {
12961296
/// This class wraps the llvm.memcpy.inline intrinsic.
12971297
class MemCpyInlineInst : public MemCpyInst {
12981298
public:
1299+
ConstantInt *getLength() const {
1300+
return cast<ConstantInt>(MemCpyInst::getLength());
1301+
}
12991302
// Methods for support type inquiry through isa, cast, and dyn_cast:
13001303
static bool classof(const IntrinsicInst *I) {
13011304
return I->getIntrinsicID() == Intrinsic::memcpy_inline;

llvm/include/llvm/IR/Intrinsics.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -966,14 +966,15 @@ def int_memcpy : Intrinsic<[],
966966
// Memcpy semantic that is guaranteed to be inlined.
967967
// In particular this means that the generated code is not allowed to call any
968968
// external function.
969+
// The third argument (specifying the size) must be a constant.
969970
def int_memcpy_inline
970971
: Intrinsic<[],
971972
[llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty, llvm_i1_ty],
972973
[IntrArgMemOnly, IntrWillReturn, IntrNoFree, IntrNoCallback,
973974
NoCapture<ArgIndex<0>>, NoCapture<ArgIndex<1>>,
974975
NoAlias<ArgIndex<0>>, NoAlias<ArgIndex<1>>,
975976
WriteOnly<ArgIndex<0>>, ReadOnly<ArgIndex<1>>,
976-
ImmArg<ArgIndex<3>>]>;
977+
ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>]>;
977978

978979
def int_memmove : Intrinsic<[],
979980
[llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,

llvm/lib/Analysis/Lint.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,7 @@ void Lint::visitCallBase(CallBase &I) {
290290

291291
// TODO: Check more intrinsics
292292

293-
case Intrinsic::memcpy:
294-
case Intrinsic::memcpy_inline: {
293+
case Intrinsic::memcpy: {
295294
MemCpyInst *MCI = cast<MemCpyInst>(&I);
296295
visitMemoryReference(I, MemoryLocation::getForDest(MCI),
297296
MCI->getDestAlign(), nullptr, MemRef::Write);
@@ -312,6 +311,23 @@ void Lint::visitCallBase(CallBase &I) {
312311
"Undefined behavior: memcpy source and destination overlap", &I);
313312
break;
314313
}
314+
case Intrinsic::memcpy_inline: {
315+
MemCpyInlineInst *MCII = cast<MemCpyInlineInst>(&I);
316+
const uint64_t Size = MCII->getLength()->getValue().getLimitedValue();
317+
visitMemoryReference(I, MemoryLocation::getForDest(MCII),
318+
MCII->getDestAlign(), nullptr, MemRef::Write);
319+
visitMemoryReference(I, MemoryLocation::getForSource(MCII),
320+
MCII->getSourceAlign(), nullptr, MemRef::Read);
321+
322+
// Check that the memcpy arguments don't overlap. The AliasAnalysis API
323+
// isn't expressive enough for what we really want to do. Known partial
324+
// overlap is not distinguished from the case where nothing is known.
325+
const LocationSize LS = LocationSize::precise(Size);
326+
Check(AA->alias(MCII->getSource(), LS, MCII->getDest(), LS) !=
327+
AliasResult::MustAlias,
328+
"Undefined behavior: memcpy source and destination overlap", &I);
329+
break;
330+
}
315331
case Intrinsic::memmove: {
316332
MemMoveInst *MMI = cast<MemMoveInst>(&I);
317333
visitMemoryReference(I, MemoryLocation::getForDest(MMI),

llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -230,21 +230,6 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(Function &F) const {
230230

231231
break;
232232
}
233-
case Intrinsic::memcpy_inline: {
234-
// Only expand llvm.memcpy.inline with non-constant length in this
235-
// codepath, leaving the current SelectionDAG expansion for constant
236-
// length memcpy intrinsics undisturbed.
237-
auto *Memcpy = cast<MemCpyInlineInst>(Inst);
238-
if (isa<ConstantInt>(Memcpy->getLength()))
239-
break;
240-
241-
Function *ParentFunc = Memcpy->getFunction();
242-
const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
243-
expandMemCpyAsLoop(Memcpy, TTI);
244-
Changed = true;
245-
Memcpy->eraseFromParent();
246-
break;
247-
}
248233
case Intrinsic::memmove: {
249234
auto *Memmove = cast<MemMoveInst>(Inst);
250235
Function *ParentFunc = Memmove->getFunction();
@@ -306,7 +291,6 @@ bool PreISelIntrinsicLowering::lowerIntrinsics(Module &M) const {
306291
default:
307292
break;
308293
case Intrinsic::memcpy:
309-
case Intrinsic::memcpy_inline:
310294
case Intrinsic::memmove:
311295
case Intrinsic::memset:
312296
case Intrinsic::memset_inline:

llvm/test/Transforms/PreISelIntrinsicLowering/X86/memcpy-inline-non-constant-len.ll

Lines changed: 0 additions & 49 deletions
This file was deleted.

llvm/test/Verifier/intrinsic-immarg.ll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ define void @memcpy_inline_is_volatile(ptr %dest, ptr %src, i1 %is.volatile) {
3636
ret void
3737
}
3838

39+
define void @memcpy_inline_variable_size(ptr %dest, ptr %src, i32 %size) {
40+
; CHECK: immarg operand has non-immediate parameter
41+
; CHECK-NEXT: i32 %size
42+
; CHECK-NEXT: call void @llvm.memcpy.inline.p0.p0.i32(ptr %dest, ptr %src, i32 %size, i1 true)
43+
call void @llvm.memcpy.inline.p0.p0.i32(ptr %dest, ptr %src, i32 %size, i1 true)
44+
ret void
45+
}
46+
3947
declare void @llvm.memmove.p0.p0.i32(ptr nocapture, ptr nocapture, i32, i1)
4048
define void @memmove(ptr %dest, ptr %src, i1 %is.volatile) {
4149
; CHECK: immarg operand has non-immediate parameter

0 commit comments

Comments
 (0)