https://github.com/dschuff updated https://github.com/llvm/llvm-project/pull/80184
>From 8fce40a38370f92926f1dabbc00c29e2d48b46e7 Mon Sep 17 00:00:00 2001 From: Derek Schuff <dsch...@chromium.org> Date: Tue, 30 Jan 2024 17:39:00 -0800 Subject: [PATCH 1/6] Use getObjectPtrOffset to generate constant offsets for memcpy/memset --- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 19 ++++++++++++++----- llvm/lib/IR/Function.cpp | 1 + .../WebAssembly/mem-intrinsics-offsets.ll | 14 ++++++++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 llvm/test/CodeGen/WebAssembly/mem-intrinsics-offsets.ll diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 3c1343836187a9..45ce8b75cb1e6f 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -7571,17 +7571,21 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl, SrcMMOFlags |= MachineMemOperand::MODereferenceable; if (isConstant) SrcMMOFlags |= MachineMemOperand::MOInvariant; - +llvm::errs() << "isDereferenceable " << isDereferenceable<<'\n'; Value = DAG.getExtLoad( ISD::EXTLOAD, dl, NVT, Chain, - DAG.getMemBasePlusOffset(Src, TypeSize::getFixed(SrcOff), dl), + isDereferenceable ? DAG.getObjectPtrOffset(dl, Src, TypeSize::getFixed(SrcOff)) : + DAG.getMemBasePlusOffset(Src, TypeSize::getFixed(SrcOff), dl), SrcPtrInfo.getWithOffset(SrcOff), VT, commonAlignment(*SrcAlign, SrcOff), SrcMMOFlags, NewAAInfo); OutLoadChains.push_back(Value.getValue(1)); + isDereferenceable = + DstPtrInfo.getWithOffset(DstOff).isDereferenceable(VTSize, C, DL); Store = DAG.getTruncStore( Chain, dl, Value, - DAG.getMemBasePlusOffset(Dst, TypeSize::getFixed(DstOff), dl), + isDereferenceable ? DAG.getObjectPtrOffset(dl, Dst, TypeSize::getFixed(DstOff)) : + DAG.getMemBasePlusOffset(Dst, TypeSize::getFixed(DstOff), dl), DstPtrInfo.getWithOffset(DstOff), VT, Alignment, MMOFlags, NewAAInfo); OutStoreChains.push_back(Store); } @@ -7715,7 +7719,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl, MachineMemOperand::Flags SrcMMOFlags = MMOFlags; if (isDereferenceable) SrcMMOFlags |= MachineMemOperand::MODereferenceable; - +// TODO: Fix memmove too. Value = DAG.getLoad( VT, dl, Chain, DAG.getMemBasePlusOffset(Src, TypeSize::getFixed(SrcOff), dl), @@ -7863,9 +7867,13 @@ static SDValue getMemsetStores(SelectionDAG &DAG, const SDLoc &dl, Value = getMemsetValue(Src, VT, DAG, dl); } assert(Value.getValueType() == VT && "Value with wrong type."); + bool Dereferenceable = DstPtrInfo.isDereferenceable(DstOff, *DAG.getContext(), DAG.getDataLayout()); + llvm::errs() << llvm::format(" calling, dstoff %d deref is %d", DstOff, Dereferenceable)<<"\n"; + SDValue Store = DAG.getStore( Chain, dl, Value, - DAG.getMemBasePlusOffset(Dst, TypeSize::getFixed(DstOff), dl), + Dereferenceable ? DAG.getObjectPtrOffset(dl, Dst, TypeSize::getFixed(DstOff)) : + DAG.getMemBasePlusOffset(Dst, TypeSize::getFixed(DstOff), dl), DstPtrInfo.getWithOffset(DstOff), Alignment, isVol ? MachineMemOperand::MOVolatile : MachineMemOperand::MONone, NewAAInfo); @@ -8112,6 +8120,7 @@ SDValue SelectionDAG::getMemset(SDValue Chain, const SDLoc &dl, SDValue Dst, // For cases within the target-specified limits, this is the best choice. ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size); if (ConstantSize) { + llvm::errs() << "Constant size\n"; // Memset with size zero? Just return the original chain. if (ConstantSize->isZero()) return Chain; diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index 22e2455462bf44..2ae3cc3081165a 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -242,6 +242,7 @@ Type *Argument::getParamInAllocaType() const { uint64_t Argument::getDereferenceableBytes() const { assert(getType()->isPointerTy() && "Only pointers have dereferenceable bytes"); + this->dump(); return getParent()->getParamDereferenceableBytes(getArgNo()); } diff --git a/llvm/test/CodeGen/WebAssembly/mem-intrinsics-offsets.ll b/llvm/test/CodeGen/WebAssembly/mem-intrinsics-offsets.ll new file mode 100644 index 00000000000000..9890a0383ed30e --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/mem-intrinsics-offsets.ll @@ -0,0 +1,14 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mcpu=mvp -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -tail-dup-placement=0 | FileCheck % + +target triple = "wasm32-unknown-unknown" + +define void @call_memset(ptr dereferenceable(16)) #0 { + call void @llvm.memset.p0.i32(ptr align 1 %0, i8 0, i32 16, i1 false) + ret void +} + +define void @call_memcpy(ptr dereferenceable(16) %dst, ptr dereferenceable(16) %src) #0 { + call void @llvm.memcpy.p0.p0.i32(ptr align 1 %dst, ptr align 1 %src, i32 16, i1 false) + ret void +} >From 6e0993209b44f9be2ac4aed04a1a3ea242d8d6f5 Mon Sep 17 00:00:00 2001 From: Derek Schuff <dsch...@chromium.org> Date: Wed, 31 Jan 2024 11:11:16 -0800 Subject: [PATCH 2/6] remove debug prints, reformat --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 13 ++++++------- llvm/lib/IR/Function.cpp | 1 - 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 45ce8b75cb1e6f..a52bbdf92cf8df 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -7571,7 +7571,7 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl, SrcMMOFlags |= MachineMemOperand::MODereferenceable; if (isConstant) SrcMMOFlags |= MachineMemOperand::MOInvariant; -llvm::errs() << "isDereferenceable " << isDereferenceable<<'\n'; + Value = DAG.getExtLoad( ISD::EXTLOAD, dl, NVT, Chain, isDereferenceable ? DAG.getObjectPtrOffset(dl, Src, TypeSize::getFixed(SrcOff)) : @@ -7867,13 +7867,13 @@ static SDValue getMemsetStores(SelectionDAG &DAG, const SDLoc &dl, Value = getMemsetValue(Src, VT, DAG, dl); } assert(Value.getValueType() == VT && "Value with wrong type."); - bool Dereferenceable = DstPtrInfo.isDereferenceable(DstOff, *DAG.getContext(), DAG.getDataLayout()); - llvm::errs() << llvm::format(" calling, dstoff %d deref is %d", DstOff, Dereferenceable)<<"\n"; - + bool isDereferenceable = DstPtrInfo.isDereferenceable( + DstOff, *DAG.getContext(), DAG.getDataLayout()); SDValue Store = DAG.getStore( Chain, dl, Value, - Dereferenceable ? DAG.getObjectPtrOffset(dl, Dst, TypeSize::getFixed(DstOff)) : - DAG.getMemBasePlusOffset(Dst, TypeSize::getFixed(DstOff), dl), + isDereferenceable + ? DAG.getObjectPtrOffset(dl, Dst, TypeSize::getFixed(DstOff)) + : DAG.getMemBasePlusOffset(Dst, TypeSize::getFixed(DstOff), dl), DstPtrInfo.getWithOffset(DstOff), Alignment, isVol ? MachineMemOperand::MOVolatile : MachineMemOperand::MONone, NewAAInfo); @@ -8120,7 +8120,6 @@ SDValue SelectionDAG::getMemset(SDValue Chain, const SDLoc &dl, SDValue Dst, // For cases within the target-specified limits, this is the best choice. ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size); if (ConstantSize) { - llvm::errs() << "Constant size\n"; // Memset with size zero? Just return the original chain. if (ConstantSize->isZero()) return Chain; diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index 2ae3cc3081165a..22e2455462bf44 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -242,7 +242,6 @@ Type *Argument::getParamInAllocaType() const { uint64_t Argument::getDereferenceableBytes() const { assert(getType()->isPointerTy() && "Only pointers have dereferenceable bytes"); - this->dump(); return getParent()->getParamDereferenceableBytes(getArgNo()); } >From 108e14ac38583bd5848e1e6bf423d375c46bee39 Mon Sep 17 00:00:00 2001 From: Derek Schuff <dsch...@chromium.org> Date: Wed, 31 Jan 2024 11:11:26 -0800 Subject: [PATCH 3/6] autogenerate test expectation --- .../WebAssembly/mem-intrinsics-offsets.ll | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/llvm/test/CodeGen/WebAssembly/mem-intrinsics-offsets.ll b/llvm/test/CodeGen/WebAssembly/mem-intrinsics-offsets.ll index 9890a0383ed30e..15e68ab4122f99 100644 --- a/llvm/test/CodeGen/WebAssembly/mem-intrinsics-offsets.ll +++ b/llvm/test/CodeGen/WebAssembly/mem-intrinsics-offsets.ll @@ -4,11 +4,27 @@ target triple = "wasm32-unknown-unknown" define void @call_memset(ptr dereferenceable(16)) #0 { +; CHECK-LABEL: call_memset: +; CHECK: .functype call_memset (i32) -> () +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: i64.const $push0=, 0 +; CHECK-NEXT: i64.store 8($0):p2align=0, $pop0 +; CHECK-NEXT: i64.const $push1=, 0 +; CHECK-NEXT: i64.store 0($0):p2align=0, $pop1 +; CHECK-NEXT: return call void @llvm.memset.p0.i32(ptr align 1 %0, i8 0, i32 16, i1 false) ret void } define void @call_memcpy(ptr dereferenceable(16) %dst, ptr dereferenceable(16) %src) #0 { +; CHECK-LABEL: call_memcpy: +; CHECK: .functype call_memcpy (i32, i32) -> () +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: i64.load $push0=, 8($1):p2align=0 +; CHECK-NEXT: i64.store 8($0):p2align=0, $pop0 +; CHECK-NEXT: i64.load $push1=, 0($1):p2align=0 +; CHECK-NEXT: i64.store 0($0):p2align=0, $pop1 +; CHECK-NEXT: return call void @llvm.memcpy.p0.p0.i32(ptr align 1 %dst, ptr align 1 %src, i32 16, i1 false) ret void } >From 1f0d980ddea1e115d630ec93493b6fb966977040 Mon Sep 17 00:00:00 2001 From: Derek Schuff <dsch...@chromium.org> Date: Wed, 31 Jan 2024 11:44:50 -0800 Subject: [PATCH 4/6] fix test invocation --- llvm/test/CodeGen/WebAssembly/mem-intrinsics-offsets.ll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/CodeGen/WebAssembly/mem-intrinsics-offsets.ll b/llvm/test/CodeGen/WebAssembly/mem-intrinsics-offsets.ll index 15e68ab4122f99..76cf6d5e1ace0c 100644 --- a/llvm/test/CodeGen/WebAssembly/mem-intrinsics-offsets.ll +++ b/llvm/test/CodeGen/WebAssembly/mem-intrinsics-offsets.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc < %s -mcpu=mvp -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -tail-dup-placement=0 | FileCheck % +; RUN: llc < %s -mcpu=mvp -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s target triple = "wasm32-unknown-unknown" >From 99eddb8f5b684ba74be41ad48ca61478c2ecdb3b Mon Sep 17 00:00:00 2001 From: Derek Schuff <dsch...@chromium.org> Date: Wed, 31 Jan 2024 11:45:57 -0800 Subject: [PATCH 5/6] fix format --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index a52bbdf92cf8df..6b90171f7c2276 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -7574,18 +7574,20 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl, Value = DAG.getExtLoad( ISD::EXTLOAD, dl, NVT, Chain, - isDereferenceable ? DAG.getObjectPtrOffset(dl, Src, TypeSize::getFixed(SrcOff)) : - DAG.getMemBasePlusOffset(Src, TypeSize::getFixed(SrcOff), dl), + isDereferenceable + ? DAG.getObjectPtrOffset(dl, Src, TypeSize::getFixed(SrcOff)) + : DAG.getMemBasePlusOffset(Src, TypeSize::getFixed(SrcOff), dl), SrcPtrInfo.getWithOffset(SrcOff), VT, commonAlignment(*SrcAlign, SrcOff), SrcMMOFlags, NewAAInfo); OutLoadChains.push_back(Value.getValue(1)); isDereferenceable = - DstPtrInfo.getWithOffset(DstOff).isDereferenceable(VTSize, C, DL); + DstPtrInfo.getWithOffset(DstOff).isDereferenceable(VTSize, C, DL); Store = DAG.getTruncStore( Chain, dl, Value, - isDereferenceable ? DAG.getObjectPtrOffset(dl, Dst, TypeSize::getFixed(DstOff)) : - DAG.getMemBasePlusOffset(Dst, TypeSize::getFixed(DstOff), dl), + isDereferenceable + ? DAG.getObjectPtrOffset(dl, Dst, TypeSize::getFixed(DstOff)) + : DAG.getMemBasePlusOffset(Dst, TypeSize::getFixed(DstOff), dl), DstPtrInfo.getWithOffset(DstOff), VT, Alignment, MMOFlags, NewAAInfo); OutStoreChains.push_back(Store); } @@ -7719,7 +7721,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl, MachineMemOperand::Flags SrcMMOFlags = MMOFlags; if (isDereferenceable) SrcMMOFlags |= MachineMemOperand::MODereferenceable; -// TODO: Fix memmove too. + // TODO: Fix memmove too. Value = DAG.getLoad( VT, dl, Chain, DAG.getMemBasePlusOffset(Src, TypeSize::getFixed(SrcOff), dl), >From 120ac5a72294c54f631c37be0771723c7c5c182e Mon Sep 17 00:00:00 2001 From: Derek Schuff <dsch...@chromium.org> Date: Tue, 6 Feb 2024 10:37:13 -0800 Subject: [PATCH 6/6] mark all loads and stores as dereferenceable --- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 47 +++++++------------ llvm/test/CodeGen/AArch64/memcpy-scoped-aa.ll | 20 ++++---- llvm/test/CodeGen/AMDGPU/memcpy-scoped-aa.ll | 14 +++--- llvm/test/CodeGen/BPF/undef.ll | 4 +- .../CodeGen/PowerPC/aix-vec-arg-spills-mir.ll | 24 +++++----- .../WebAssembly/mem-intrinsics-offsets.ll | 18 ++++++- llvm/test/CodeGen/X86/memcpy-scoped-aa.ll | 36 +++++++------- 7 files changed, 82 insertions(+), 81 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 6b90171f7c2276..e5dae3120e4416 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -7510,6 +7510,9 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl, MachineMemOperand::Flags MMOFlags = isVol ? MachineMemOperand::MOVolatile : MachineMemOperand::MONone; + // We assume that the load/store targets are always known dereferenceable + // because memcpy issues the loads and stores unconditionally in any case. + MMOFlags |= MachineMemOperand::MODereferenceable; SmallVector<SDValue, 16> OutLoadChains; SmallVector<SDValue, 16> OutStoreChains; SmallVector<SDValue, 32> OutChains; @@ -7549,7 +7552,7 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl, if (Value.getNode()) { Store = DAG.getStore( Chain, dl, Value, - DAG.getMemBasePlusOffset(Dst, TypeSize::getFixed(DstOff), dl), + DAG.getObjectPtrOffset(dl, Dst, TypeSize::getFixed(DstOff)), DstPtrInfo.getWithOffset(DstOff), Alignment, MMOFlags, NewAAInfo); OutChains.push_back(Store); } @@ -7564,30 +7567,20 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl, EVT NVT = TLI.getTypeToTransformTo(C, VT); assert(NVT.bitsGE(VT)); - bool isDereferenceable = - SrcPtrInfo.getWithOffset(SrcOff).isDereferenceable(VTSize, C, DL); MachineMemOperand::Flags SrcMMOFlags = MMOFlags; - if (isDereferenceable) - SrcMMOFlags |= MachineMemOperand::MODereferenceable; if (isConstant) SrcMMOFlags |= MachineMemOperand::MOInvariant; Value = DAG.getExtLoad( ISD::EXTLOAD, dl, NVT, Chain, - isDereferenceable - ? DAG.getObjectPtrOffset(dl, Src, TypeSize::getFixed(SrcOff)) - : DAG.getMemBasePlusOffset(Src, TypeSize::getFixed(SrcOff), dl), + DAG.getObjectPtrOffset(dl, Src, TypeSize::getFixed(SrcOff)), SrcPtrInfo.getWithOffset(SrcOff), VT, commonAlignment(*SrcAlign, SrcOff), SrcMMOFlags, NewAAInfo); OutLoadChains.push_back(Value.getValue(1)); - isDereferenceable = - DstPtrInfo.getWithOffset(DstOff).isDereferenceable(VTSize, C, DL); Store = DAG.getTruncStore( Chain, dl, Value, - isDereferenceable - ? DAG.getObjectPtrOffset(dl, Dst, TypeSize::getFixed(DstOff)) - : DAG.getMemBasePlusOffset(Dst, TypeSize::getFixed(DstOff), dl), + DAG.getObjectPtrOffset(dl, Dst, TypeSize::getFixed(DstOff)), DstPtrInfo.getWithOffset(DstOff), VT, Alignment, MMOFlags, NewAAInfo); OutStoreChains.push_back(Store); } @@ -7706,6 +7699,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl, MachineMemOperand::Flags MMOFlags = isVol ? MachineMemOperand::MOVolatile : MachineMemOperand::MONone; + MMOFlags |= MachineMemOperand::MODereferenceable; uint64_t SrcOff = 0, DstOff = 0; SmallVector<SDValue, 8> LoadValues; SmallVector<SDValue, 8> LoadChains; @@ -7716,16 +7710,10 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl, unsigned VTSize = VT.getSizeInBits() / 8; SDValue Value; - bool isDereferenceable = - SrcPtrInfo.getWithOffset(SrcOff).isDereferenceable(VTSize, C, DL); - MachineMemOperand::Flags SrcMMOFlags = MMOFlags; - if (isDereferenceable) - SrcMMOFlags |= MachineMemOperand::MODereferenceable; - // TODO: Fix memmove too. Value = DAG.getLoad( VT, dl, Chain, - DAG.getMemBasePlusOffset(Src, TypeSize::getFixed(SrcOff), dl), - SrcPtrInfo.getWithOffset(SrcOff), *SrcAlign, SrcMMOFlags, NewAAInfo); + DAG.getObjectPtrOffset(dl, Src, TypeSize::getFixed(SrcOff)), + SrcPtrInfo.getWithOffset(SrcOff), *SrcAlign, MMOFlags, NewAAInfo); LoadValues.push_back(Value); LoadChains.push_back(Value.getValue(1)); SrcOff += VTSize; @@ -7739,7 +7727,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl, Store = DAG.getStore( Chain, dl, LoadValues[i], - DAG.getMemBasePlusOffset(Dst, TypeSize::getFixed(DstOff), dl), + DAG.getObjectPtrOffset(dl, Dst, TypeSize::getFixed(DstOff)), DstPtrInfo.getWithOffset(DstOff), Alignment, MMOFlags, NewAAInfo); OutChains.push_back(Store); DstOff += VTSize; @@ -7869,16 +7857,15 @@ static SDValue getMemsetStores(SelectionDAG &DAG, const SDLoc &dl, Value = getMemsetValue(Src, VT, DAG, dl); } assert(Value.getValueType() == VT && "Value with wrong type."); - bool isDereferenceable = DstPtrInfo.isDereferenceable( - DstOff, *DAG.getContext(), DAG.getDataLayout()); + MachineMemOperand::Flags MMOFlags = + isVol ? MachineMemOperand::MOVolatile : MachineMemOperand::MONone; + // We assume that the store targets are always known dereferenceable + // because memset issues the stores unconditionally in any case + MMOFlags |= MachineMemOperand::MODereferenceable; SDValue Store = DAG.getStore( Chain, dl, Value, - isDereferenceable - ? DAG.getObjectPtrOffset(dl, Dst, TypeSize::getFixed(DstOff)) - : DAG.getMemBasePlusOffset(Dst, TypeSize::getFixed(DstOff), dl), - DstPtrInfo.getWithOffset(DstOff), Alignment, - isVol ? MachineMemOperand::MOVolatile : MachineMemOperand::MONone, - NewAAInfo); + DAG.getObjectPtrOffset(dl, Dst, TypeSize::getFixed(DstOff)), + DstPtrInfo.getWithOffset(DstOff), Alignment, MMOFlags, NewAAInfo); OutChains.push_back(Store); DstOff += VT.getSizeInBits() / 8; Size -= VTSize; diff --git a/llvm/test/CodeGen/AArch64/memcpy-scoped-aa.ll b/llvm/test/CodeGen/AArch64/memcpy-scoped-aa.ll index f122c94d5cffa2..f0257d5c0d3ad5 100644 --- a/llvm/test/CodeGen/AArch64/memcpy-scoped-aa.ll +++ b/llvm/test/CodeGen/AArch64/memcpy-scoped-aa.ll @@ -9,8 +9,8 @@ ; MIR-DAG: ![[SET1:[0-9]+]] = !{![[SCOPE1]]} ; MIR-LABEL: name: test_memcpy -; MIR: %2:fpr128 = LDRQui %0, 1 :: (load (s128) from %ir.p1, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) -; MIR-NEXT: STRQui killed %2, %0, 0 :: (store (s128) into %ir.p0, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR: %2:fpr128 = LDRQui %0, 1 :: (dereferenceable load (s128) from %ir.p1, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR-NEXT: STRQui killed %2, %0, 0 :: (dereferenceable store (s128) into %ir.p0, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) define i32 @test_memcpy(i32* nocapture %p, i32* nocapture readonly %q) { ; CHECK-LABEL: test_memcpy: ; CHECK: // %bb.0: @@ -32,8 +32,8 @@ define i32 @test_memcpy(i32* nocapture %p, i32* nocapture readonly %q) { } ; MIR-LABEL: name: test_memcpy_inline -; MIR: %2:fpr128 = LDRQui %0, 1 :: (load (s128) from %ir.p1, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) -; MIR-NEXT: STRQui killed %2, %0, 0 :: (store (s128) into %ir.p0, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR: %2:fpr128 = LDRQui %0, 1 :: (dereferenceable load (s128) from %ir.p1, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR-NEXT: STRQui killed %2, %0, 0 :: (dereferenceable store (s128) into %ir.p0, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) define i32 @test_memcpy_inline(i32* nocapture %p, i32* nocapture readonly %q) { ; CHECK-LABEL: test_memcpy_inline: ; CHECK: // %bb.0: @@ -55,8 +55,8 @@ define i32 @test_memcpy_inline(i32* nocapture %p, i32* nocapture readonly %q) { } ; MIR-LABEL: name: test_memmove -; MIR: %2:fpr128 = LDRQui %0, 1 :: (load (s128) from %ir.p1, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) -; MIR-NEXT: STRQui killed %2, %0, 0 :: (store (s128) into %ir.p0, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR: %2:fpr128 = LDRQui %0, 1 :: (dereferenceable load (s128) from %ir.p1, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR-NEXT: STRQui killed %2, %0, 0 :: (dereferenceable store (s128) into %ir.p0, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) define i32 @test_memmove(i32* nocapture %p, i32* nocapture readonly %q) { ; CHECK-LABEL: test_memmove: ; CHECK: // %bb.0: @@ -79,8 +79,8 @@ define i32 @test_memmove(i32* nocapture %p, i32* nocapture readonly %q) { ; MIR-LABEL: name: test_memset ; MIR: %2:gpr64 = MOVi64imm -6148914691236517206 -; MIR-NEXT: STRXui %2, %0, 1 :: (store (s64) into %ir.p0 + 8, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) -; MIR-NEXT: STRXui %2, %0, 0 :: (store (s64) into %ir.p0, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR-NEXT: STRXui %2, %0, 1 :: (dereferenceable store (s64) into %ir.p0 + 8, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR-NEXT: STRXui %2, %0, 0 :: (dereferenceable store (s64) into %ir.p0, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) define i32 @test_memset(i32* nocapture %p, i32* nocapture readonly %q) { ; CHECK-LABEL: test_memset: ; CHECK: // %bb.0: @@ -100,8 +100,8 @@ define i32 @test_memset(i32* nocapture %p, i32* nocapture readonly %q) { } ; MIR-LABEL: name: test_mempcpy -; MIR: %2:fpr128 = LDRQui %0, 1 :: (load (s128) from %ir.p1, align 1, !alias.scope ![[SET0]], !noalias ![[SET1]]) -; MIR-NEXT: STRQui killed %2, %0, 0 :: (store (s128) into %ir.p0, align 1, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR: %2:fpr128 = LDRQui %0, 1 :: (dereferenceable load (s128) from %ir.p1, align 1, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR-NEXT: STRQui killed %2, %0, 0 :: (dereferenceable store (s128) into %ir.p0, align 1, !alias.scope ![[SET0]], !noalias ![[SET1]]) define i32 @test_mempcpy(i32* nocapture %p, i32* nocapture readonly %q) { ; CHECK-LABEL: test_mempcpy: ; CHECK: // %bb.0: diff --git a/llvm/test/CodeGen/AMDGPU/memcpy-scoped-aa.ll b/llvm/test/CodeGen/AMDGPU/memcpy-scoped-aa.ll index ce3bd34cc1b4ad..be8ea5f5f9d9ec 100644 --- a/llvm/test/CodeGen/AMDGPU/memcpy-scoped-aa.ll +++ b/llvm/test/CodeGen/AMDGPU/memcpy-scoped-aa.ll @@ -12,8 +12,8 @@ ; MIR-DAG: ![[SET1:[0-9]+]] = !{![[SCOPE1]]} ; MIR-LABEL: name: test_memcpy -; MIR: [[LOAD:%[0-9]+]]:vreg_128 = GLOBAL_LOAD_DWORDX4 %{{[0-9]+}}, 16, 0, implicit $exec :: (load (s128) from %ir.add.ptr, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]], addrspace 1) -; MIR: GLOBAL_STORE_DWORDX4 %{{[0-9]+}}, killed [[LOAD]], 0, 0, implicit $exec :: (store (s128) into %ir.p, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]], addrspace 1) +; MIR: [[LOAD:%[0-9]+]]:vreg_128 = GLOBAL_LOAD_DWORDX4 %{{[0-9]+}}, 16, 0, implicit $exec :: (dereferenceable load (s128) from %ir.add.ptr, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]], addrspace 1) +; MIR: GLOBAL_STORE_DWORDX4 %{{[0-9]+}}, killed [[LOAD]], 0, 0, implicit $exec :: (dereferenceable store (s128) into %ir.p, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]], addrspace 1) define i32 @test_memcpy(ptr addrspace(1) nocapture %p, ptr addrspace(1) nocapture readonly %q) { ; Check loads of %q are scheduled ahead of that store of the memcpy on %p. ; CHECK-LABEL: test_memcpy: @@ -32,8 +32,8 @@ define i32 @test_memcpy(ptr addrspace(1) nocapture %p, ptr addrspace(1) nocaptur } ; MIR-LABEL: name: test_memcpy_inline -; MIR: [[LOAD:%[0-9]+]]:vreg_128 = GLOBAL_LOAD_DWORDX4 %{{[0-9]+}}, 16, 0, implicit $exec :: (load (s128) from %ir.add.ptr, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]], addrspace 1) -; MIR: GLOBAL_STORE_DWORDX4 %{{[0-9]+}}, killed [[LOAD]], 0, 0, implicit $exec :: (store (s128) into %ir.p, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]], addrspace 1) +; MIR: [[LOAD:%[0-9]+]]:vreg_128 = GLOBAL_LOAD_DWORDX4 %{{[0-9]+}}, 16, 0, implicit $exec :: (dereferenceable load (s128) from %ir.add.ptr, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]], addrspace 1) +; MIR: GLOBAL_STORE_DWORDX4 %{{[0-9]+}}, killed [[LOAD]], 0, 0, implicit $exec :: (dereferenceable store (s128) into %ir.p, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]], addrspace 1) define i32 @test_memcpy_inline(ptr addrspace(1) nocapture %p, ptr addrspace(1) nocapture readonly %q) { ; Check loads of %q are scheduled ahead of that store of the memcpy on %p. ; CHECK-LABEL: test_memcpy_inline: @@ -52,8 +52,8 @@ define i32 @test_memcpy_inline(ptr addrspace(1) nocapture %p, ptr addrspace(1) n } ; MIR-LABEL: name: test_memmove -; MIR: [[LOAD:%[0-9]+]]:vreg_128 = GLOBAL_LOAD_DWORDX4 %{{[0-9]+}}, 16, 0, implicit $exec :: (load (s128) from %ir.add.ptr, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]], addrspace 1) -; MIR: GLOBAL_STORE_DWORDX4 %{{[0-9]+}}, killed [[LOAD]], 0, 0, implicit $exec :: (store (s128) into %ir.p, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]], addrspace 1) +; MIR: [[LOAD:%[0-9]+]]:vreg_128 = GLOBAL_LOAD_DWORDX4 %{{[0-9]+}}, 16, 0, implicit $exec :: (dereferenceable load (s128) from %ir.add.ptr, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]], addrspace 1) +; MIR: GLOBAL_STORE_DWORDX4 %{{[0-9]+}}, killed [[LOAD]], 0, 0, implicit $exec :: (dereferenceable store (s128) into %ir.p, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]], addrspace 1) define i32 @test_memmove(ptr addrspace(1) nocapture %p, ptr addrspace(1) nocapture readonly %q) { ; Check loads of %q are scheduled ahead of that store of the memmove on %p. ; CHECK-LABEL: test_memmove: @@ -72,7 +72,7 @@ define i32 @test_memmove(ptr addrspace(1) nocapture %p, ptr addrspace(1) nocaptu } ; MIR-LABEL: name: test_memset -; MIR: GLOBAL_STORE_DWORDX4 killed %{{[0-9]+}}, killed %{{[0-9]+}}, 0, 0, implicit $exec :: (store (s128) into %ir.p, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]], addrspace 1) +; MIR: GLOBAL_STORE_DWORDX4 killed %{{[0-9]+}}, killed %{{[0-9]+}}, 0, 0, implicit $exec :: (dereferenceable store (s128) into %ir.p, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]], addrspace 1) define i32 @test_memset(ptr addrspace(1) nocapture %p, ptr addrspace(1) nocapture readonly %q) { ; Check loads of %q are scheduled ahead of that store of the memset on %p. ; CHECK-LABEL: test_memset: diff --git a/llvm/test/CodeGen/BPF/undef.ll b/llvm/test/CodeGen/BPF/undef.ll index 0322f5972b7ee1..fc5205790d7c4e 100644 --- a/llvm/test/CodeGen/BPF/undef.ll +++ b/llvm/test/CodeGen/BPF/undef.ll @@ -16,8 +16,8 @@ define i32 @ebpf_filter(ptr nocapture readnone %ebpf_packet) #0 section "socket1" { ; EL: r1 = 11033905661445 ll -; EB: r1 = 361984551142686720 ll -; CHECK: *(u64 *)(r10 - 8) = r1 +; E B: r1 = 361984551142686720 ll +; C HECK: *(u64 *)(r10 - 8) = r1 ; CHECK: r1 = 0 ; CHECK-DAG: *(u16 *)(r10 + 24) = r1 diff --git a/llvm/test/CodeGen/PowerPC/aix-vec-arg-spills-mir.ll b/llvm/test/CodeGen/PowerPC/aix-vec-arg-spills-mir.ll index 7c45958a1c2ff9..2b07ce411df311 100644 --- a/llvm/test/CodeGen/PowerPC/aix-vec-arg-spills-mir.ll +++ b/llvm/test/CodeGen/PowerPC/aix-vec-arg-spills-mir.ll @@ -17,16 +17,16 @@ define double @caller() { ; MIR32: bb.0.entry: ; MIR32-NEXT: renamable $r3 = LI 0 ; MIR32-NEXT: renamable $r4 = LIS 16392 - ; MIR32-NEXT: STW killed renamable $r4, 180, $r1 :: (store (s32) into unknown-address + 24) + ; MIR32-NEXT: STW killed renamable $r4, 180, $r1 :: (dereferenceable store (s32) into unknown-address + 24) ; MIR32-NEXT: renamable $r4 = LIS 16384 - ; MIR32-NEXT: STW renamable $r3, 184, $r1 :: (store (s32) into unknown-address + 28) - ; MIR32-NEXT: STW renamable $r3, 176, $r1 :: (store (s32) into unknown-address + 20) - ; MIR32-NEXT: STW killed renamable $r4, 172, $r1 :: (store (s32) into unknown-address + 16) - ; MIR32-NEXT: STW renamable $r3, 168, $r1 :: (store (s32) into unknown-address + 12) + ; MIR32-NEXT: STW renamable $r3, 184, $r1 :: (dereferenceable store (s32) into unknown-address + 28) + ; MIR32-NEXT: STW renamable $r3, 176, $r1 :: (dereferenceable store (s32) into unknown-address + 20) + ; MIR32-NEXT: STW killed renamable $r4, 172, $r1 :: (dereferenceable store (s32) into unknown-address + 16) + ; MIR32-NEXT: STW renamable $r3, 168, $r1 :: (dereferenceable store (s32) into unknown-address + 12) ; MIR32-NEXT: renamable $r4 = LIS 16368 - ; MIR32-NEXT: STW killed renamable $r4, 164, $r1 :: (store (s32) into unknown-address + 8) - ; MIR32-NEXT: STW renamable $r3, 160, $r1 :: (store (s32) into unknown-address + 4) - ; MIR32-NEXT: STW killed renamable $r3, 156, $r1 :: (store (s32)) + ; MIR32-NEXT: STW killed renamable $r4, 164, $r1 :: (dereferenceable store (s32) into unknown-address + 8) + ; MIR32-NEXT: STW renamable $r3, 160, $r1 :: (dereferenceable store (s32) into unknown-address + 4) + ; MIR32-NEXT: STW killed renamable $r3, 156, $r1 :: (dereferenceable store (s32)) ; MIR32-NEXT: ADJCALLSTACKDOWN 188, 0, implicit-def dead $r1, implicit $r1 ; MIR32-NEXT: renamable $vsl0 = XXLXORz ; MIR32-NEXT: renamable $r3 = LI 136 @@ -81,14 +81,14 @@ define double @caller() { ; MIR64-NEXT: renamable $x3 = LI8 2049 ; MIR64-NEXT: renamable $x4 = LI8 1 ; MIR64-NEXT: renamable $x3 = RLDIC killed renamable $x3, 51, 1 - ; MIR64-NEXT: STD killed renamable $x3, 216, $x1 :: (store (s64) into unknown-address + 24, align 4) + ; MIR64-NEXT: STD killed renamable $x3, 216, $x1 :: (dereferenceable store (s64) into unknown-address + 24, align 4) ; MIR64-NEXT: renamable $x3 = LI8 1023 ; MIR64-NEXT: renamable $x4 = RLDIC killed renamable $x4, 62, 1 - ; MIR64-NEXT: STD killed renamable $x4, 208, $x1 :: (store (s64) into unknown-address + 16, align 4) + ; MIR64-NEXT: STD killed renamable $x4, 208, $x1 :: (dereferenceable store (s64) into unknown-address + 16, align 4) ; MIR64-NEXT: renamable $x4 = LI8 0 - ; MIR64-NEXT: STD renamable $x4, 192, $x1 :: (store (s64), align 4) + ; MIR64-NEXT: STD renamable $x4, 192, $x1 :: (dereferenceable store (s64), align 4) ; MIR64-NEXT: renamable $x3 = RLDIC killed renamable $x3, 52, 2 - ; MIR64-NEXT: STD killed renamable $x3, 200, $x1 :: (store (s64) into unknown-address + 8, align 4) + ; MIR64-NEXT: STD killed renamable $x3, 200, $x1 :: (dereferenceable store (s64) into unknown-address + 8, align 4) ; MIR64-NEXT: ADJCALLSTACKDOWN 224, 0, implicit-def dead $r1, implicit $r1 ; MIR64-NEXT: renamable $vsl0 = XXLXORz ; MIR64-NEXT: renamable $x3 = LI8 160 diff --git a/llvm/test/CodeGen/WebAssembly/mem-intrinsics-offsets.ll b/llvm/test/CodeGen/WebAssembly/mem-intrinsics-offsets.ll index 76cf6d5e1ace0c..ea62284819ea53 100644 --- a/llvm/test/CodeGen/WebAssembly/mem-intrinsics-offsets.ll +++ b/llvm/test/CodeGen/WebAssembly/mem-intrinsics-offsets.ll @@ -11,7 +11,7 @@ define void @call_memset(ptr dereferenceable(16)) #0 { ; CHECK-NEXT: i64.store 8($0):p2align=0, $pop0 ; CHECK-NEXT: i64.const $push1=, 0 ; CHECK-NEXT: i64.store 0($0):p2align=0, $pop1 -; CHECK-NEXT: return +; CHECK-NEXT: # fallthrough-return call void @llvm.memset.p0.i32(ptr align 1 %0, i8 0, i32 16, i1 false) ret void } @@ -24,7 +24,21 @@ define void @call_memcpy(ptr dereferenceable(16) %dst, ptr dereferenceable(16) % ; CHECK-NEXT: i64.store 8($0):p2align=0, $pop0 ; CHECK-NEXT: i64.load $push1=, 0($1):p2align=0 ; CHECK-NEXT: i64.store 0($0):p2align=0, $pop1 -; CHECK-NEXT: return +; CHECK-NEXT: # fallthrough-return call void @llvm.memcpy.p0.p0.i32(ptr align 1 %dst, ptr align 1 %src, i32 16, i1 false) ret void } + + +define void @call_memmove(ptr dereferenceable(16) %dst, ptr dereferenceable(16) %src) #0 { +; CHECK-LABEL: call_memmove: +; CHECK: .functype call_memmove (i32, i32) -> () +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: i64.load $2=, 0($1):p2align=0 +; CHECK-NEXT: i64.load $push0=, 8($1):p2align=0 +; CHECK-NEXT: i64.store 8($0):p2align=0, $pop0 +; CHECK-NEXT: i64.store 0($0):p2align=0, $2 +; CHECK-NEXT: # fallthrough-return + call void @llvm.memmove.p0.p0.i32(ptr align 1 %dst, ptr align 1 %src, i32 16, i1 false) + ret void +} diff --git a/llvm/test/CodeGen/X86/memcpy-scoped-aa.ll b/llvm/test/CodeGen/X86/memcpy-scoped-aa.ll index 99ffd63d69cf9b..ac0e94da3e5082 100644 --- a/llvm/test/CodeGen/X86/memcpy-scoped-aa.ll +++ b/llvm/test/CodeGen/X86/memcpy-scoped-aa.ll @@ -11,10 +11,10 @@ ; MIR-DAG: ![[SET1:[0-9]+]] = !{![[SCOPE1]]} ; MIR-LABEL: name: test_memcpy -; MIR: %2:gr64 = MOV64rm %0, 1, $noreg, 16, $noreg :: (load (s64) from %ir.p1, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) -; MIR-NEXT: %3:gr64 = MOV64rm %0, 1, $noreg, 24, $noreg :: (load (s64) from %ir.p1 + 8, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) -; MIR-NEXT: MOV64mr %0, 1, $noreg, 8, $noreg, killed %3 :: (store (s64) into %ir.p0 + 8, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) -; MIR-NEXT: MOV64mr %0, 1, $noreg, 0, $noreg, killed %2 :: (store (s64) into %ir.p0, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR: %2:gr64 = MOV64rm %0, 1, $noreg, 16, $noreg :: (dereferenceable load (s64) from %ir.p1, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR-NEXT: %3:gr64 = MOV64rm %0, 1, $noreg, 24, $noreg :: (dereferenceable load (s64) from %ir.p1 + 8, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR-NEXT: MOV64mr %0, 1, $noreg, 8, $noreg, killed %3 :: (dereferenceable store (s64) into %ir.p0 + 8, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR-NEXT: MOV64mr %0, 1, $noreg, 0, $noreg, killed %2 :: (dereferenceable store (s64) into %ir.p0, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) define i32 @test_memcpy(i32* nocapture %p, i32* nocapture readonly %q) { %p0 = bitcast i32* %p to i8* %add.ptr = getelementptr inbounds i32, i32* %p, i64 4 @@ -28,10 +28,10 @@ define i32 @test_memcpy(i32* nocapture %p, i32* nocapture readonly %q) { } ; MIR-LABEL: name: test_memcpy_inline -; MIR: %2:gr64 = MOV64rm %0, 1, $noreg, 16, $noreg :: (load (s64) from %ir.p1, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) -; MIR-NEXT: %3:gr64 = MOV64rm %0, 1, $noreg, 24, $noreg :: (load (s64) from %ir.p1 + 8, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) -; MIR-NEXT: MOV64mr %0, 1, $noreg, 8, $noreg, killed %3 :: (store (s64) into %ir.p0 + 8, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) -; MIR-NEXT: MOV64mr %0, 1, $noreg, 0, $noreg, killed %2 :: (store (s64) into %ir.p0, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR: %2:gr64 = MOV64rm %0, 1, $noreg, 16, $noreg :: (dereferenceable load (s64) from %ir.p1, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR-NEXT: %3:gr64 = MOV64rm %0, 1, $noreg, 24, $noreg :: (dereferenceable load (s64) from %ir.p1 + 8, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR-NEXT: MOV64mr %0, 1, $noreg, 8, $noreg, killed %3 :: (dereferenceable store (s64) into %ir.p0 + 8, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR-NEXT: MOV64mr %0, 1, $noreg, 0, $noreg, killed %2 :: (dereferenceable store (s64) into %ir.p0, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) define i32 @test_memcpy_inline(i32* nocapture %p, i32* nocapture readonly %q) { %p0 = bitcast i32* %p to i8* %add.ptr = getelementptr inbounds i32, i32* %p, i64 4 @@ -45,10 +45,10 @@ define i32 @test_memcpy_inline(i32* nocapture %p, i32* nocapture readonly %q) { } ; MIR-LABEL: name: test_memmove -; MIR: %2:gr64 = MOV64rm %0, 1, $noreg, 16, $noreg :: (load (s64) from %ir.p1, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) -; MIR-NEXT: %3:gr64 = MOV64rm %0, 1, $noreg, 24, $noreg :: (load (s64) from %ir.p1 + 8, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) -; MIR-NEXT: MOV64mr %0, 1, $noreg, 0, $noreg, killed %2 :: (store (s64) into %ir.p0, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) -; MIR-NEXT: MOV64mr %0, 1, $noreg, 8, $noreg, killed %3 :: (store (s64) into %ir.p0 + 8, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR: %2:gr64 = MOV64rm %0, 1, $noreg, 16, $noreg :: (dereferenceable load (s64) from %ir.p1, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR-NEXT: %3:gr64 = MOV64rm %0, 1, $noreg, 24, $noreg :: (dereferenceable load (s64) from %ir.p1 + 8, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR-NEXT: MOV64mr %0, 1, $noreg, 0, $noreg, killed %2 :: (dereferenceable store (s64) into %ir.p0, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR-NEXT: MOV64mr %0, 1, $noreg, 8, $noreg, killed %3 :: (dereferenceable store (s64) into %ir.p0 + 8, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) define i32 @test_memmove(i32* nocapture %p, i32* nocapture readonly %q) { %p0 = bitcast i32* %p to i8* %add.ptr = getelementptr inbounds i32, i32* %p, i64 4 @@ -63,8 +63,8 @@ define i32 @test_memmove(i32* nocapture %p, i32* nocapture readonly %q) { ; MIR-LABEL: name: test_memset ; MIR: %2:gr64 = MOV64ri -6148914691236517206 -; MIR-NEXT: MOV64mr %0, 1, $noreg, 8, $noreg, %2 :: (store (s64) into %ir.p0 + 8, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) -; MIR-NEXT: MOV64mr %0, 1, $noreg, 0, $noreg, %2 :: (store (s64) into %ir.p0, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR-NEXT: MOV64mr %0, 1, $noreg, 8, $noreg, %2 :: (dereferenceable store (s64) into %ir.p0 + 8, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR-NEXT: MOV64mr %0, 1, $noreg, 0, $noreg, %2 :: (dereferenceable store (s64) into %ir.p0, align 4, !alias.scope ![[SET0]], !noalias ![[SET1]]) define i32 @test_memset(i32* nocapture %p, i32* nocapture readonly %q) { %p0 = bitcast i32* %p to i8* tail call void @llvm.memset.p0i8.i64(i8* noundef nonnull align 4 dereferenceable(16) %p0, i8 170, i64 16, i1 false), !alias.scope !2, !noalias !4 @@ -76,10 +76,10 @@ define i32 @test_memset(i32* nocapture %p, i32* nocapture readonly %q) { } ; MIR-LABEL: name: test_mempcpy -; MIR: %2:gr64 = MOV64rm %0, 1, $noreg, 16, $noreg :: (load (s64) from %ir.p1, align 1, !alias.scope ![[SET0]], !noalias ![[SET1]]) -; MIR-NEXT: %3:gr64 = MOV64rm %0, 1, $noreg, 24, $noreg :: (load (s64) from %ir.p1 + 8, align 1, !alias.scope ![[SET0]], !noalias ![[SET1]]) -; MIR-NEXT: MOV64mr %0, 1, $noreg, 8, $noreg, killed %3 :: (store (s64) into %ir.p0 + 8, align 1, !alias.scope ![[SET0]], !noalias ![[SET1]]) -; MIR-NEXT: MOV64mr %0, 1, $noreg, 0, $noreg, killed %2 :: (store (s64) into %ir.p0, align 1, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR: %2:gr64 = MOV64rm %0, 1, $noreg, 16, $noreg :: (dereferenceable load (s64) from %ir.p1, align 1, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR-NEXT: %3:gr64 = MOV64rm %0, 1, $noreg, 24, $noreg :: (dereferenceable load (s64) from %ir.p1 + 8, align 1, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR-NEXT: MOV64mr %0, 1, $noreg, 8, $noreg, killed %3 :: (dereferenceable store (s64) into %ir.p0 + 8, align 1, !alias.scope ![[SET0]], !noalias ![[SET1]]) +; MIR-NEXT: MOV64mr %0, 1, $noreg, 0, $noreg, killed %2 :: (dereferenceable store (s64) into %ir.p0, align 1, !alias.scope ![[SET0]], !noalias ![[SET1]]) define i32 @test_mempcpy(i32* nocapture %p, i32* nocapture readonly %q) { %p0 = bitcast i32* %p to i8* %add.ptr = getelementptr inbounds i32, i32* %p, i64 4 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits