Skip to content

Commit 6506acb

Browse files
committed
[SelectionDAG] Split <n x T> vector types for atomic load
`load atomic <n x T>` is not valid. This change splits vector types of atomic load in SelectionDAG so that it can translate vectors of >1 size with type bfloat,half. commit-id:3a045357
1 parent a8cc74f commit 6506acb

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
946946
void SplitVecRes_FPOp_MultiType(SDNode *N, SDValue &Lo, SDValue &Hi);
947947
void SplitVecRes_IS_FPCLASS(SDNode *N, SDValue &Lo, SDValue &Hi);
948948
void SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo, SDValue &Hi);
949+
void SplitVecRes_ATOMIC_LOAD(AtomicSDNode *LD, SDValue &Lo, SDValue &Hi);
949950
void SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo, SDValue &Hi);
950951
void SplitVecRes_VP_LOAD(VPLoadSDNode *LD, SDValue &Lo, SDValue &Hi);
951952
void SplitVecRes_VP_STRIDED_LOAD(VPStridedLoadSDNode *SLD, SDValue &Lo,

llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,6 +1146,9 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
11461146
SplitVecRes_STEP_VECTOR(N, Lo, Hi);
11471147
break;
11481148
case ISD::SIGN_EXTEND_INREG: SplitVecRes_InregOp(N, Lo, Hi); break;
1149+
case ISD::ATOMIC_LOAD:
1150+
SplitVecRes_ATOMIC_LOAD(cast<AtomicSDNode>(N), Lo, Hi);
1151+
break;
11491152
case ISD::LOAD:
11501153
SplitVecRes_LOAD(cast<LoadSDNode>(N), Lo, Hi);
11511154
break;
@@ -2079,6 +2082,38 @@ void DAGTypeLegalizer::SplitVecRes_VP_SPLAT(SDNode *N, SDValue &Lo,
20792082
Hi = DAG.getNode(N->getOpcode(), dl, HiVT, N->getOperand(0), MaskHi, EVLHi);
20802083
}
20812084

2085+
void DAGTypeLegalizer::SplitVecRes_ATOMIC_LOAD(AtomicSDNode *LD, SDValue &Lo,
2086+
SDValue &Hi) {
2087+
EVT LoVT, HiVT;
2088+
SDLoc dl(LD);
2089+
std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(LD->getValueType(0));
2090+
2091+
SDValue Ch = LD->getChain();
2092+
SDValue Ptr = LD->getBasePtr();
2093+
EVT MemoryVT = LD->getMemoryVT();
2094+
2095+
EVT LoMemVT, HiMemVT;
2096+
std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2097+
2098+
Lo = DAG.getAtomic(ISD::ATOMIC_LOAD, dl, LoMemVT, LoMemVT, Ch, Ptr,
2099+
LD->getMemOperand());
2100+
2101+
MachinePointerInfo MPI;
2102+
IncrementPointer(LD, LoMemVT, MPI, Ptr);
2103+
2104+
Hi = DAG.getAtomic(ISD::ATOMIC_LOAD, dl, HiMemVT, HiMemVT, Ch, Ptr,
2105+
LD->getMemOperand());
2106+
2107+
// Build a factor node to remember that this load is independent of the
2108+
// other one.
2109+
Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
2110+
Hi.getValue(1));
2111+
2112+
// Legalize the chain result - switch anything that used the old chain to
2113+
// use the new one.
2114+
ReplaceValueWith(SDValue(LD, 1), Ch);
2115+
}
2116+
20822117
void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo,
20832118
SDValue &Hi) {
20842119
assert(ISD::isUNINDEXEDLoad(LD) && "Indexed load during type legalization!");

llvm/test/CodeGen/X86/atomic-load-store.ll

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,62 @@ define <2 x float> @atomic_vec2_float_align(ptr %x) {
194194
ret <2 x float> %ret
195195
}
196196

197+
define <2 x half> @atomic_vec2_half(ptr %x) {
198+
; CHECK3-LABEL: atomic_vec2_half:
199+
; CHECK3: ## %bb.0:
200+
; CHECK3-NEXT: movzwl (%rdi), %eax
201+
; CHECK3-NEXT: movzwl 2(%rdi), %ecx
202+
; CHECK3-NEXT: pinsrw $0, %eax, %xmm0
203+
; CHECK3-NEXT: pinsrw $0, %ecx, %xmm1
204+
; CHECK3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
205+
; CHECK3-NEXT: retq
206+
;
207+
; CHECK0-LABEL: atomic_vec2_half:
208+
; CHECK0: ## %bb.0:
209+
; CHECK0-NEXT: movw (%rdi), %dx
210+
; CHECK0-NEXT: movw 2(%rdi), %cx
211+
; CHECK0-NEXT: ## implicit-def: $eax
212+
; CHECK0-NEXT: movw %dx, %ax
213+
; CHECK0-NEXT: ## implicit-def: $xmm0
214+
; CHECK0-NEXT: pinsrw $0, %eax, %xmm0
215+
; CHECK0-NEXT: ## implicit-def: $eax
216+
; CHECK0-NEXT: movw %cx, %ax
217+
; CHECK0-NEXT: ## implicit-def: $xmm1
218+
; CHECK0-NEXT: pinsrw $0, %eax, %xmm1
219+
; CHECK0-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
220+
; CHECK0-NEXT: retq
221+
%ret = load atomic <2 x half>, ptr %x acquire, align 4
222+
ret <2 x half> %ret
223+
}
224+
225+
define <2 x bfloat> @atomic_vec2_bfloat(ptr %x) {
226+
; CHECK3-LABEL: atomic_vec2_bfloat:
227+
; CHECK3: ## %bb.0:
228+
; CHECK3-NEXT: movzwl (%rdi), %eax
229+
; CHECK3-NEXT: movzwl 2(%rdi), %ecx
230+
; CHECK3-NEXT: pinsrw $0, %ecx, %xmm1
231+
; CHECK3-NEXT: pinsrw $0, %eax, %xmm0
232+
; CHECK3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
233+
; CHECK3-NEXT: retq
234+
;
235+
; CHECK0-LABEL: atomic_vec2_bfloat:
236+
; CHECK0: ## %bb.0:
237+
; CHECK0-NEXT: movw (%rdi), %cx
238+
; CHECK0-NEXT: movw 2(%rdi), %dx
239+
; CHECK0-NEXT: ## implicit-def: $eax
240+
; CHECK0-NEXT: movw %dx, %ax
241+
; CHECK0-NEXT: ## implicit-def: $xmm1
242+
; CHECK0-NEXT: pinsrw $0, %eax, %xmm1
243+
; CHECK0-NEXT: ## implicit-def: $eax
244+
; CHECK0-NEXT: movw %cx, %ax
245+
; CHECK0-NEXT: ## implicit-def: $xmm0
246+
; CHECK0-NEXT: pinsrw $0, %eax, %xmm0
247+
; CHECK0-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
248+
; CHECK0-NEXT: retq
249+
%ret = load atomic <2 x bfloat>, ptr %x acquire, align 4
250+
ret <2 x bfloat> %ret
251+
}
252+
197253
define <1 x ptr> @atomic_vec1_ptr(ptr %x) nounwind {
198254
; CHECK3-LABEL: atomic_vec1_ptr:
199255
; CHECK3: ## %bb.0:

0 commit comments

Comments
 (0)