Skip to content

Commit 62d0c01

Browse files
authored
[SelectionDAG] Remove pointer from MMO for VP strided load/store. (#82667)
MachineIR alias analysis assumes that only bytes after the pointer will be accessed. This is incorrect if the stride is negative. This is causing miscompiles in our downstream after SLP started making strided loads. Fixes #82657
1 parent 56d5829 commit 62d0c01

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8030,8 +8030,9 @@ void SelectionDAGBuilder::visitVPStridedLoad(
80308030
MemoryLocation ML = MemoryLocation::getAfter(PtrOperand, AAInfo);
80318031
bool AddToChain = !AA || !AA->pointsToConstantMemory(ML);
80328032
SDValue InChain = AddToChain ? DAG.getRoot() : DAG.getEntryNode();
8033+
unsigned AS = PtrOperand->getType()->getPointerAddressSpace();
80338034
MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
8034-
MachinePointerInfo(PtrOperand), MachineMemOperand::MOLoad,
8035+
MachinePointerInfo(AS), MachineMemOperand::MOLoad,
80358036
MemoryLocation::UnknownSize, *Alignment, AAInfo, Ranges);
80368037

80378038
SDValue LD = DAG.getStridedLoadVP(VT, DL, InChain, OpValues[0], OpValues[1],
@@ -8052,8 +8053,9 @@ void SelectionDAGBuilder::visitVPStridedStore(
80528053
if (!Alignment)
80538054
Alignment = DAG.getEVTAlign(VT.getScalarType());
80548055
AAMDNodes AAInfo = VPIntrin.getAAMetadata();
8056+
unsigned AS = PtrOperand->getType()->getPointerAddressSpace();
80558057
MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
8056-
MachinePointerInfo(PtrOperand), MachineMemOperand::MOStore,
8058+
MachinePointerInfo(AS), MachineMemOperand::MOStore,
80578059
MemoryLocation::UnknownSize, *Alignment, AAInfo);
80588060

80598061
SDValue ST = DAG.getStridedStoreVP(
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
2+
; RUN: llc -mtriple=riscv64 -mattr=+v -stop-after=finalize-isel %s -o - | FileCheck %s
3+
4+
; Test makes sure we don't store a pointer in the MachineMemOperand created for
5+
; these instructions. MachineMemOperand handling can't currently deal with a
6+
; negative stride that would allow memory before the pointer to be read.
7+
8+
declare <vscale x 1 x i8> @llvm.experimental.vp.strided.load.nxv1i8.p0.i8(ptr, i8, <vscale x 1 x i1>, i32)
9+
10+
define <vscale x 1 x i8> @strided_vpload_nxv1i8_i8(ptr %ptr, i8 signext %stride, <vscale x 1 x i1> %m, i32 zeroext %evl) {
11+
; CHECK-LABEL: name: strided_vpload_nxv1i8_i8
12+
; CHECK: bb.0 (%ir-block.0):
13+
; CHECK-NEXT: liveins: $x10, $x11, $v0, $x12
14+
; CHECK-NEXT: {{ $}}
15+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x12
16+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0
17+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x11
18+
; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x10
19+
; CHECK-NEXT: $v0 = COPY [[COPY1]]
20+
; CHECK-NEXT: [[PseudoVLSE8_V_MF8_MASK:%[0-9]+]]:vrnov0 = PseudoVLSE8_V_MF8_MASK $noreg, [[COPY3]], [[COPY2]], $v0, [[COPY]], 3 /* e8 */, 1 /* ta, mu */ :: (load unknown-size, align 1)
21+
; CHECK-NEXT: $v8 = COPY [[PseudoVLSE8_V_MF8_MASK]]
22+
; CHECK-NEXT: PseudoRET implicit $v8
23+
%load = call <vscale x 1 x i8> @llvm.experimental.vp.strided.load.nxv1i8.p0.i8(ptr %ptr, i8 %stride, <vscale x 1 x i1> %m, i32 %evl)
24+
ret <vscale x 1 x i8> %load
25+
}
26+
27+
declare void @llvm.experimental.vp.strided.store.nxv1i8.p0.i8(<vscale x 1 x i8>, ptr, i8, <vscale x 1 x i1>, i32)
28+
29+
define void @strided_vpstore_nxv1i8_i8(<vscale x 1 x i8> %val, ptr %ptr, i8 signext %stride, <vscale x 1 x i1> %m, i32 zeroext %evl) {
30+
; CHECK-LABEL: name: strided_vpstore_nxv1i8_i8
31+
; CHECK: bb.0 (%ir-block.0):
32+
; CHECK-NEXT: liveins: $v8, $x10, $x11, $v0, $x12
33+
; CHECK-NEXT: {{ $}}
34+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x12
35+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0
36+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x11
37+
; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x10
38+
; CHECK-NEXT: [[COPY4:%[0-9]+]]:vr = COPY $v8
39+
; CHECK-NEXT: $v0 = COPY [[COPY1]]
40+
; CHECK-NEXT: PseudoVSSE8_V_MF8_MASK [[COPY4]], [[COPY3]], [[COPY2]], $v0, [[COPY]], 3 /* e8 */ :: (store unknown-size, align 1)
41+
; CHECK-NEXT: PseudoRET
42+
call void @llvm.experimental.vp.strided.store.nxv1i8.p0.i8(<vscale x 1 x i8> %val, ptr %ptr, i8 %stride, <vscale x 1 x i1> %m, i32 %evl)
43+
ret void
44+
}
45+
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
46+
; CHECK: {{.*}}

0 commit comments

Comments
 (0)