Skip to content

Commit 6737dda

Browse files
committed
[SelectionDAG] Widen <n x T> vector types for atomic load
`load atomic <n x T>` is not valid. This change widens vector types of atomic load in SelectionDAG so that it can translate aligned vectors of >1 size. commit-id:2894ccd1
1 parent 464bb05 commit 6737dda

File tree

3 files changed

+70
-5
lines changed

3 files changed

+70
-5
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
10461046
SDValue WidenVecRes_EXTRACT_SUBVECTOR(SDNode* N);
10471047
SDValue WidenVecRes_INSERT_SUBVECTOR(SDNode *N);
10481048
SDValue WidenVecRes_INSERT_VECTOR_ELT(SDNode* N);
1049+
SDValue WidenVecRes_ATOMIC_LOAD(AtomicSDNode *N);
10491050
SDValue WidenVecRes_LOAD(SDNode* N);
10501051
SDValue WidenVecRes_VP_LOAD(VPLoadSDNode *N);
10511052
SDValue WidenVecRes_VP_STRIDED_LOAD(VPStridedLoadSDNode *N);
@@ -1129,8 +1130,9 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
11291130
/// resulting wider type. It takes:
11301131
/// LdChain: list of chains for the load to be generated.
11311132
/// Ld: load to widen
1132-
SDValue GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain,
1133-
LoadSDNode *LD);
1133+
template <typename T>
1134+
SDValue GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain, T *LD,
1135+
bool IsAtomic = false);
11341136

11351137
/// Helper function to generate a set of extension loads to load a vector with
11361138
/// a resulting wider type. It takes:

llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp

+36-3
Original file line numberDiff line numberDiff line change
@@ -4515,6 +4515,9 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
45154515
break;
45164516
case ISD::EXTRACT_SUBVECTOR: Res = WidenVecRes_EXTRACT_SUBVECTOR(N); break;
45174517
case ISD::INSERT_VECTOR_ELT: Res = WidenVecRes_INSERT_VECTOR_ELT(N); break;
4518+
case ISD::ATOMIC_LOAD:
4519+
Res = WidenVecRes_ATOMIC_LOAD(cast<AtomicSDNode>(N));
4520+
break;
45184521
case ISD::LOAD: Res = WidenVecRes_LOAD(N); break;
45194522
case ISD::STEP_VECTOR:
45204523
case ISD::SPLAT_VECTOR:
@@ -5901,6 +5904,30 @@ SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) {
59015904
N->getOperand(1), N->getOperand(2));
59025905
}
59035906

5907+
SDValue DAGTypeLegalizer::WidenVecRes_ATOMIC_LOAD(AtomicSDNode *N) {
5908+
SmallVector<SDValue, 16> LdChain; // Chain for the series of load
5909+
SDValue Result = GenWidenVectorLoads(LdChain, N, true /*IsAtomic*/);
5910+
5911+
if (Result) {
5912+
// If we generate a single load, we can use that for the chain. Otherwise,
5913+
// build a factor node to remember the multiple loads are independent and
5914+
// chain to that.
5915+
SDValue NewChain;
5916+
if (LdChain.size() == 1)
5917+
NewChain = LdChain[0];
5918+
else
5919+
NewChain = DAG.getNode(ISD::TokenFactor, SDLoc(N), MVT::Other, LdChain);
5920+
5921+
// Modified the chain - switch anything that used the old chain to use
5922+
// the new one.
5923+
ReplaceValueWith(SDValue(N, 1), NewChain);
5924+
5925+
return Result;
5926+
}
5927+
5928+
report_fatal_error("Unable to widen atomic vector load");
5929+
}
5930+
59045931
SDValue DAGTypeLegalizer::WidenVecRes_LOAD(SDNode *N) {
59055932
LoadSDNode *LD = cast<LoadSDNode>(N);
59065933
ISD::LoadExtType ExtType = LD->getExtensionType();
@@ -7699,8 +7726,9 @@ static SDValue BuildVectorFromScalar(SelectionDAG& DAG, EVT VecTy,
76997726
return DAG.getNode(ISD::BITCAST, dl, VecTy, VecOp);
77007727
}
77017728

7729+
template <typename T>
77027730
SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain,
7703-
LoadSDNode *LD) {
7731+
T *LD, bool IsAtomic) {
77047732
// The strategy assumes that we can efficiently load power-of-two widths.
77057733
// The routine chops the vector into the largest vector loads with the same
77067734
// element type or scalar loads and then recombines it to the widen vector
@@ -7757,8 +7785,13 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain,
77577785
} while (TypeSize::isKnownGT(RemainingWidth, NewVTWidth));
77587786
}
77597787

7760-
SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr, LD->getPointerInfo(),
7761-
LD->getOriginalAlign(), MMOFlags, AAInfo);
7788+
SDValue LdOp;
7789+
if (IsAtomic)
7790+
LdOp = DAG.getAtomic(ISD::ATOMIC_LOAD, dl, *FirstVT, *FirstVT, Chain,
7791+
BasePtr, LD->getMemOperand());
7792+
else
7793+
LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr, LD->getPointerInfo(),
7794+
LD->getOriginalAlign(), MMOFlags, AAInfo);
77627795
LdChain.push_back(LdOp.getValue(1));
77637796

77647797
// Check if we can load the element with one instruction.

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

+30
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,36 @@ define <1 x i64> @atomic_vec1_i64_align(ptr %x) nounwind {
146146
ret <1 x i64> %ret
147147
}
148148

149+
define <2 x i16> @atomic_vec2_i16(ptr %x) {
150+
; CHECK-LABEL: atomic_vec2_i16:
151+
; CHECK: ## %bb.0:
152+
; CHECK-NEXT: movl (%rdi), %eax
153+
; CHECK-NEXT: movd %eax, %xmm0
154+
; CHECK-NEXT: retq
155+
%ret = load atomic <2 x i16>, ptr %x acquire, align 4
156+
ret <2 x i16> %ret
157+
}
158+
159+
define <2 x i32> @atomic_vec2_i32_align(ptr %x) {
160+
; CHECK-LABEL: atomic_vec2_i32_align:
161+
; CHECK: ## %bb.0:
162+
; CHECK-NEXT: movq (%rdi), %rax
163+
; CHECK-NEXT: movq %rax, %xmm0
164+
; CHECK-NEXT: retq
165+
%ret = load atomic <2 x i32>, ptr %x acquire, align 8
166+
ret <2 x i32> %ret
167+
}
168+
169+
define <2 x float> @atomic_vec2_float_align(ptr %x) {
170+
; CHECK-LABEL: atomic_vec2_float_align:
171+
; CHECK: ## %bb.0:
172+
; CHECK-NEXT: movq (%rdi), %rax
173+
; CHECK-NEXT: movq %rax, %xmm0
174+
; CHECK-NEXT: retq
175+
%ret = load atomic <2 x float>, ptr %x acquire, align 8
176+
ret <2 x float> %ret
177+
}
178+
149179
define <1 x ptr> @atomic_vec1_ptr(ptr %x) nounwind {
150180
; CHECK3-LABEL: atomic_vec1_ptr:
151181
; CHECK3: ## %bb.0:

0 commit comments

Comments
 (0)