================
@@ -8061,6 +8064,59 @@ SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) {
report_fatal_error("Unable to widen vector store");
}
+/// Inverse of coerceLoadedValue: pull a FirstVT-sized scalar/vector out of the
+/// widened value so it can be issued in a single atomic store.
+static SDValue coerceStoredValue(SDValue StVal, EVT FirstVT, EVT WidenVT,
+ TypeSize FirstVTWidth, SDLoc dl,
+ SelectionDAG &DAG) {
+ TypeSize WidenWidth = WidenVT.getSizeInBits();
+ if (!FirstVT.isVector()) {
+ unsigned NumElts =
+ WidenWidth.getFixedValue() / FirstVTWidth.getFixedValue();
+ EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), FirstVT, NumElts);
+ SDValue VecOp = DAG.getNode(ISD::BITCAST, dl, NewVecVT, StVal);
+ return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, FirstVT, VecOp,
+ DAG.getVectorIdxConstant(0, dl));
+ }
+ assert(FirstVT == WidenVT && "First value type must equal widen value type");
+ return StVal;
+}
+
+SDValue DAGTypeLegalizer::WidenVecOp_ATOMIC_STORE(AtomicSDNode *ST) {
+ EVT StVT = ST->getMemoryVT();
+ SDLoc dl(ST);
+ assert(StVT.isVector() && "Expected vector");
+
+ SDValue StVal = GetWidenedVector(ST->getVal());
+ EVT WidenVT = StVal.getValueType();
+ assert(WidenVT.isVector() && "Expected vector");
+ assert(StVT.isScalableVector() == WidenVT.isScalableVector() &&
+ "Must be scalable");
+ assert(StVT.getVectorElementType() == WidenVT.getVectorElementType() &&
+ "Expected equivalent element types");
+
+ TypeSize StWidth = StVT.getSizeInBits();
+ TypeSize WidenWidth = WidenVT.getSizeInBits();
+ TypeSize WidthDiff = WidenWidth - StWidth;
+
+ // Find the vector type that can store the original memory width in one
+ // atomic operation.
+ std::optional<EVT> FirstVT =
+ findMemType(DAG, TLI, StWidth.getKnownMinValue(), WidenVT, /*StAlign=*/0,
+ WidthDiff.getKnownMinValue());
+
----------------
jofrn wrote:
Like atomic loads, for atomic stores, this causes a widen beyond the value's
width: e.g. `<2 x i8>` writes beyond object (e.g. `%v` of `<2 x i8> %v`). That
is, if we pass align, then we get `movl %eax, (%rdi)`, which writes to
unrelated / undefined bytes relative to `%v`.
https://github.com/llvm/llvm-project/pull/197618
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits