Skip to content

Commit 94a71a3

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 6737dda commit 94a71a3

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
@@ -176,6 +176,62 @@ define <2 x float> @atomic_vec2_float_align(ptr %x) {
176176
ret <2 x float> %ret
177177
}
178178

179+
define <2 x half> @atomic_vec2_half(ptr %x) {
180+
; CHECK3-LABEL: atomic_vec2_half:
181+
; CHECK3: ## %bb.0:
182+
; CHECK3-NEXT: movzwl (%rdi), %eax
183+
; CHECK3-NEXT: movzwl 2(%rdi), %ecx
184+
; CHECK3-NEXT: pinsrw $0, %eax, %xmm0
185+
; CHECK3-NEXT: pinsrw $0, %ecx, %xmm1
186+
; CHECK3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
187+
; CHECK3-NEXT: retq
188+
;
189+
; CHECK0-LABEL: atomic_vec2_half:
190+
; CHECK0: ## %bb.0:
191+
; CHECK0-NEXT: movw (%rdi), %dx
192+
; CHECK0-NEXT: movw 2(%rdi), %cx
193+
; CHECK0-NEXT: ## implicit-def: $eax
194+
; CHECK0-NEXT: movw %dx, %ax
195+
; CHECK0-NEXT: ## implicit-def: $xmm0
196+
; CHECK0-NEXT: pinsrw $0, %eax, %xmm0
197+
; CHECK0-NEXT: ## implicit-def: $eax
198+
; CHECK0-NEXT: movw %cx, %ax
199+
; CHECK0-NEXT: ## implicit-def: $xmm1
200+
; CHECK0-NEXT: pinsrw $0, %eax, %xmm1
201+
; CHECK0-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
202+
; CHECK0-NEXT: retq
203+
%ret = load atomic <2 x half>, ptr %x acquire, align 4
204+
ret <2 x half> %ret
205+
}
206+
207+
define <2 x bfloat> @atomic_vec2_bfloat(ptr %x) {
208+
; CHECK3-LABEL: atomic_vec2_bfloat:
209+
; CHECK3: ## %bb.0:
210+
; CHECK3-NEXT: movzwl (%rdi), %eax
211+
; CHECK3-NEXT: movzwl 2(%rdi), %ecx
212+
; CHECK3-NEXT: pinsrw $0, %ecx, %xmm1
213+
; CHECK3-NEXT: pinsrw $0, %eax, %xmm0
214+
; CHECK3-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
215+
; CHECK3-NEXT: retq
216+
;
217+
; CHECK0-LABEL: atomic_vec2_bfloat:
218+
; CHECK0: ## %bb.0:
219+
; CHECK0-NEXT: movw (%rdi), %cx
220+
; CHECK0-NEXT: movw 2(%rdi), %dx
221+
; CHECK0-NEXT: ## implicit-def: $eax
222+
; CHECK0-NEXT: movw %dx, %ax
223+
; CHECK0-NEXT: ## implicit-def: $xmm1
224+
; CHECK0-NEXT: pinsrw $0, %eax, %xmm1
225+
; CHECK0-NEXT: ## implicit-def: $eax
226+
; CHECK0-NEXT: movw %cx, %ax
227+
; CHECK0-NEXT: ## implicit-def: $xmm0
228+
; CHECK0-NEXT: pinsrw $0, %eax, %xmm0
229+
; CHECK0-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
230+
; CHECK0-NEXT: retq
231+
%ret = load atomic <2 x bfloat>, ptr %x acquire, align 4
232+
ret <2 x bfloat> %ret
233+
}
234+
179235
define <1 x ptr> @atomic_vec1_ptr(ptr %x) nounwind {
180236
; CHECK3-LABEL: atomic_vec1_ptr:
181237
; CHECK3: ## %bb.0:

0 commit comments

Comments
 (0)