@@ -14,7 +14,7 @@ define dso_local void @redundant_stores_merging() {
1414; CHECK-LABEL: redundant_stores_merging:
1515; CHECK: # %bb.0:
1616; CHECK-NEXT: movabsq $1958505086977, %rax # imm = 0x1C800000001
17- ; CHECK-NEXT: movq %rax, e+{{.*}} (%rip)
17+ ; CHECK-NEXT: movq %rax, e+4 (%rip)
1818; CHECK-NEXT: retq
1919 store i32 1 , i32* getelementptr inbounds (%structTy , %structTy* @e , i64 0 , i32 1 ), align 4
2020 store i32 123 , i32* getelementptr inbounds (%structTy , %structTy* @e , i64 0 , i32 2 ), align 4
@@ -27,8 +27,8 @@ define dso_local void @redundant_stores_merging_reverse() {
2727; CHECK-LABEL: redundant_stores_merging_reverse:
2828; CHECK: # %bb.0:
2929; CHECK-NEXT: movabsq $528280977409, %rax # imm = 0x7B00000001
30- ; CHECK-NEXT: movq %rax, e+{{.*}} (%rip)
31- ; CHECK-NEXT: movl $456, e+{{.*}} (%rip) # imm = 0x1C8
30+ ; CHECK-NEXT: movq %rax, e+4 (%rip)
31+ ; CHECK-NEXT: movl $456, e+8 (%rip) # imm = 0x1C8
3232; CHECK-NEXT: retq
3333 store i32 123 , i32* getelementptr inbounds (%structTy , %structTy* @e , i64 0 , i32 2 ), align 4
3434 store i32 456 , i32* getelementptr inbounds (%structTy , %structTy* @e , i64 0 , i32 2 ), align 4
@@ -46,8 +46,8 @@ define dso_local void @redundant_stores_merging_reverse() {
4646define dso_local void @overlapping_stores_merging () {
4747; CHECK-LABEL: overlapping_stores_merging:
4848; CHECK: # %bb.0:
49- ; CHECK-NEXT: movl $1, {{.*}} (%rip)
50- ; CHECK-NEXT: movw $2, b+{{.*}} (%rip)
49+ ; CHECK-NEXT: movl $1, b (%rip)
50+ ; CHECK-NEXT: movw $2, b+3 (%rip)
5151; CHECK-NEXT: retq
5252 store i16 0 , i16* bitcast (i8* getelementptr inbounds ([8 x i8 ], [8 x i8 ]* @b , i64 0 , i64 2 ) to i16* ), align 2
5353 store i16 2 , i16* bitcast (i8* getelementptr inbounds ([8 x i8 ], [8 x i8 ]* @b , i64 0 , i64 3 ) to i16* ), align 1
@@ -612,3 +612,88 @@ define dso_local void @be_i64_to_i32_order(i64 %x, i32* %p0) {
612612 store i32 %t0 , i32* %p1 , align 4
613613 ret void
614614}
615+
616+ ; https://llvm.org/PR50623
617+ ; FIXME:
618+ ; It is a miscompile to merge the stores if we are not
619+ ; writing all of the bytes from the source value.
620+
621+ define void @merge_hole (i32 %x , i8* %p ) {
622+ ; CHECK-LABEL: merge_hole:
623+ ; CHECK: # %bb.0:
624+ ; CHECK-NEXT: movl %edi, (%rsi)
625+ ; CHECK-NEXT: retq
626+ %pcast = bitcast i8* %p to i16*
627+ %p2 = getelementptr inbounds i16 , i16* %pcast , i64 1
628+ %x3 = trunc i32 %x to i8
629+ store i8 %x3 , i8* %p , align 1
630+ %sh = lshr i32 %x , 16
631+ %x01 = trunc i32 %sh to i16
632+ store i16 %x01 , i16* %p2 , align 1
633+ ret void
634+ }
635+
636+ ; Change the order of the stores.
637+ ; It is a miscompile to merge the stores if we are not
638+ ; writing all of the bytes from the source value.
639+
640+ define void @merge_hole2 (i32 %x , i8* %p ) {
641+ ; CHECK-LABEL: merge_hole2:
642+ ; CHECK: # %bb.0:
643+ ; CHECK-NEXT: movl %edi, %eax
644+ ; CHECK-NEXT: shrl $16, %eax
645+ ; CHECK-NEXT: movw %ax, 2(%rsi)
646+ ; CHECK-NEXT: movb %dil, (%rsi)
647+ ; CHECK-NEXT: retq
648+ %pcast = bitcast i8* %p to i16*
649+ %p2 = getelementptr inbounds i16 , i16* %pcast , i64 1
650+ %sh = lshr i32 %x , 16
651+ %x01 = trunc i32 %sh to i16
652+ store i16 %x01 , i16* %p2 , align 1
653+ %x3 = trunc i32 %x to i8
654+ store i8 %x3 , i8* %p , align 1
655+ ret void
656+ }
657+
658+ ; Change offset.
659+ ; It is a miscompile to merge the stores if we are not
660+ ; writing all of the bytes from the source value.
661+
662+ define void @merge_hole3 (i32 %x , i8* %p ) {
663+ ; CHECK-LABEL: merge_hole3:
664+ ; CHECK: # %bb.0:
665+ ; CHECK-NEXT: movb %dil, 1(%rsi)
666+ ; CHECK-NEXT: shrl $16, %edi
667+ ; CHECK-NEXT: movw %di, 2(%rsi)
668+ ; CHECK-NEXT: retq
669+ %p1 = getelementptr inbounds i8 , i8* %p , i64 1
670+ %pcast = bitcast i8* %p to i16*
671+ %p2 = getelementptr inbounds i16 , i16* %pcast , i64 1
672+ %x3 = trunc i32 %x to i8
673+ store i8 %x3 , i8* %p1 , align 1
674+ %sh = lshr i32 %x , 16
675+ %x01 = trunc i32 %sh to i16
676+ store i16 %x01 , i16* %p2 , align 1
677+ ret void
678+ }
679+
680+ ; Change offset.
681+ ; FIXME:
682+ ; It is a miscompile to merge the stores if we are not
683+ ; writing all of the bytes from the source value.
684+
685+ define void @merge_hole4 (i32 %x , i8* %p ) {
686+ ; CHECK-LABEL: merge_hole4:
687+ ; CHECK: # %bb.0:
688+ ; CHECK-NEXT: rorl $16, %edi
689+ ; CHECK-NEXT: movl %edi, (%rsi)
690+ ; CHECK-NEXT: retq
691+ %pcast = bitcast i8* %p to i16*
692+ %p2 = getelementptr inbounds i8 , i8* %p , i64 2
693+ %x3 = trunc i32 %x to i8
694+ store i8 %x3 , i8* %p2 , align 1
695+ %sh = lshr i32 %x , 16
696+ %x01 = trunc i32 %sh to i16
697+ store i16 %x01 , i16* %pcast , align 1
698+ ret void
699+ }
0 commit comments