if (LegalOperations)
return SDValue();
- // Collect all the stores in the chain.
- SDValue Chain;
- SmallVector<StoreSDNode *, 8> Stores;
- for (StoreSDNode *Store = N; Store; Store = dyn_cast<StoreSDNode>(Chain)) {
- // TODO: Allow unordered atomics when wider type is legal (see D66309)
- EVT MemVT = Store->getMemoryVT();
- if (!(MemVT == MVT::i8 || MemVT == MVT::i16 || MemVT == MVT::i32) ||
- !Store->isSimple() || Store->isIndexed())
+ // We only handle merging simple stores of 1-4 bytes.
+ // TODO: Allow unordered atomics when wider type is legal (see D66309)
+ EVT MemVT = N->getMemoryVT();
+ if (!(MemVT == MVT::i8 || MemVT == MVT::i16 || MemVT == MVT::i32) ||
+ !N->isSimple() || N->isIndexed())
+ return SDValue();
+
+ // Collect all of the stores in the chain.
+ SDValue Chain = N->getChain();
+ SmallVector<StoreSDNode *, 8> Stores = {N};
+ while (auto *Store = dyn_cast<StoreSDNode>(Chain)) {
+ // All stores must be the same size to ensure that we are writing all of the
+ // bytes in the wide value.
+ // TODO: We could allow multiple sizes by tracking each stored byte.
+ if (Store->getMemoryVT() != MemVT || !Store->isSimple() ||
+ Store->isIndexed())
return SDValue();
Stores.push_back(Store);
Chain = Store->getChain();
}
; https://llvm.org/PR50623
-; FIXME:
; It is a miscompile to merge the stores if we are not
; writing all of the bytes from the source value.
define void @merge_hole(i32 %x, i8* %p) {
; CHECK-LABEL: merge_hole:
; CHECK: # %bb.0:
-; CHECK-NEXT: movl %edi, (%rsi)
+; CHECK-NEXT: movb %dil, (%rsi)
+; CHECK-NEXT: shrl $16, %edi
+; CHECK-NEXT: movw %di, 2(%rsi)
; CHECK-NEXT: retq
%pcast = bitcast i8* %p to i16*
%p2 = getelementptr inbounds i16, i16* %pcast, i64 1
}
; Change offset.
-; FIXME:
; It is a miscompile to merge the stores if we are not
; writing all of the bytes from the source value.
define void @merge_hole4(i32 %x, i8* %p) {
; CHECK-LABEL: merge_hole4:
; CHECK: # %bb.0:
-; CHECK-NEXT: rorl $16, %edi
-; CHECK-NEXT: movl %edi, (%rsi)
+; CHECK-NEXT: movb %dil, 2(%rsi)
+; CHECK-NEXT: shrl $16, %edi
+; CHECK-NEXT: movw %di, (%rsi)
; CHECK-NEXT: retq
%pcast = bitcast i8* %p to i16*
%p2 = getelementptr inbounds i8, i8* %p, i64 2