[AArch64] Use an unknown size for memcpy ops with non-constant sizes. (#187445)
The previous value of 0 was allowing loads to move past the mops operations where it is not valid. Use a LocationSize::afterPointer() size instead. The GISel lowering currently loses the MMO, which is fine as it should be conservatively treated as a load/store to any location.
This commit is contained in:
parent
421bf13e4b
commit
441790b31f
@ -127,9 +127,9 @@ SDValue AArch64SelectionDAGInfo::EmitMOPS(unsigned Opcode, SelectionDAG &DAG,
|
||||
MachinePointerInfo SrcPtrInfo) const {
|
||||
|
||||
// Get the constant size of the copy/set.
|
||||
uint64_t ConstSize = 0;
|
||||
LocationSize MemSize = LocationSize::afterPointer();
|
||||
if (auto *C = dyn_cast<ConstantSDNode>(Size))
|
||||
ConstSize = C->getZExtValue();
|
||||
MemSize = LocationSize::precise(C->getZExtValue());
|
||||
|
||||
const bool IsSet = Opcode == AArch64::MOPSMemorySetPseudo ||
|
||||
Opcode == AArch64::MOPSMemorySetTaggingPseudo;
|
||||
@ -140,7 +140,7 @@ SDValue AArch64SelectionDAGInfo::EmitMOPS(unsigned Opcode, SelectionDAG &DAG,
|
||||
isVolatile ? MachineMemOperand::MOVolatile : MachineMemOperand::MONone;
|
||||
auto DstFlags = MachineMemOperand::MOStore | Vol;
|
||||
auto *DstOp =
|
||||
MF.getMachineMemOperand(DstPtrInfo, DstFlags, ConstSize, Alignment);
|
||||
MF.getMachineMemOperand(DstPtrInfo, DstFlags, MemSize, Alignment);
|
||||
|
||||
if (IsSet) {
|
||||
// Extend value to i64, if required.
|
||||
@ -158,7 +158,7 @@ SDValue AArch64SelectionDAGInfo::EmitMOPS(unsigned Opcode, SelectionDAG &DAG,
|
||||
|
||||
auto SrcFlags = MachineMemOperand::MOLoad | Vol;
|
||||
auto *SrcOp =
|
||||
MF.getMachineMemOperand(SrcPtrInfo, SrcFlags, ConstSize, Alignment);
|
||||
MF.getMachineMemOperand(SrcPtrInfo, SrcFlags, MemSize, Alignment);
|
||||
DAG.setNodeMemRefs(Node, {DstOp, SrcOp});
|
||||
return SDValue(Node, 3);
|
||||
}
|
||||
|
||||
28
llvm/test/CodeGen/AArch64/mops-mmo-size.ll
Normal file
28
llvm/test/CodeGen/AArch64/mops-mmo-size.ll
Normal file
@ -0,0 +1,28 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
|
||||
; RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=+mops -stop-after=aarch64-isel -o - %s | FileCheck %s --check-prefix=CHECK-SD
|
||||
; RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=+mops -global-isel -stop-after=finalize-isel -o - %s | FileCheck %s --check-prefix=CHECK-GI
|
||||
|
||||
define void @test(ptr %out, ptr %in, i64 %a) {
|
||||
; CHECK-SD-LABEL: name: test
|
||||
; CHECK-SD: bb.0.entry:
|
||||
; CHECK-SD-NEXT: liveins: $x0, $x1, $x2
|
||||
; CHECK-SD-NEXT: {{ $}}
|
||||
; CHECK-SD-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x2
|
||||
; CHECK-SD-NEXT: [[COPY1:%[0-9]+]]:gpr64common = COPY $x1
|
||||
; CHECK-SD-NEXT: [[COPY2:%[0-9]+]]:gpr64common = COPY $x0
|
||||
; CHECK-SD-NEXT: [[MOPSMemoryMovePseudo:%[0-9]+]]:gpr64common, [[MOPSMemoryMovePseudo1:%[0-9]+]]:gpr64common, [[MOPSMemoryMovePseudo2:%[0-9]+]]:gpr64 = MOPSMemoryMovePseudo [[COPY2]], [[COPY1]], [[COPY]], implicit-def dead $nzcv :: (store unknown-size into %ir.out, align 1), (load unknown-size from %ir.in, align 1)
|
||||
; CHECK-SD-NEXT: RET_ReallyLR
|
||||
;
|
||||
; CHECK-GI-LABEL: name: test
|
||||
; CHECK-GI: bb.1.entry:
|
||||
; CHECK-GI-NEXT: liveins: $x0, $x1, $x2
|
||||
; CHECK-GI-NEXT: {{ $}}
|
||||
; CHECK-GI-NEXT: [[COPY:%[0-9]+]]:gpr64common = COPY $x0
|
||||
; CHECK-GI-NEXT: [[COPY1:%[0-9]+]]:gpr64common = COPY $x1
|
||||
; CHECK-GI-NEXT: [[COPY2:%[0-9]+]]:gpr64 = COPY $x2
|
||||
; CHECK-GI-NEXT: [[MOPSMemoryMovePseudo:%[0-9]+]]:gpr64common, [[MOPSMemoryMovePseudo1:%[0-9]+]]:gpr64common, [[MOPSMemoryMovePseudo2:%[0-9]+]]:gpr64 = MOPSMemoryMovePseudo [[COPY]], [[COPY1]], [[COPY2]], implicit-def dead $nzcv
|
||||
; CHECK-GI-NEXT: RET_ReallyLR
|
||||
entry:
|
||||
call void @llvm.memmove.p0.p0.i64(ptr %out, ptr %in, i64 %a, i1 false)
|
||||
ret void
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user