This fixes the miscompile in issue #58883. The test demonstrates that we gave up on store merging in that example. This change should be strictly safe (just adds another clause to avoid the transform), and it does not prohibit any existing valid optimizations based on regression tests. I want to believe that it's also a sufficient fix (possibly overkill), but I'm not sure how to prove that. Differential Revision: https://reviews.llvm.org/D137791
42 lines
1.4 KiB
LLVM
42 lines
1.4 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc < %s -mtriple=s390x-linux-gnu -pre-RA-sched=list-ilp -disable-sched-live-uses=false | FileCheck %s
|
|
|
|
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
|
|
|
|
%struct.a = type { i16, i32 }
|
|
|
|
@e = dso_local global %struct.a { i16 9, i32 0 }, align 8
|
|
@f = dso_local local_unnamed_addr global ptr @e, align 8
|
|
@d = dso_local local_unnamed_addr global i32 0, align 4
|
|
|
|
; This shows a miscompile caused by merging truncated
|
|
; stores if the store of 0 (sthrl) to 'e' happens before
|
|
; a 64-bit store (stg) of r0. The store of r0 can follow
|
|
; the store to 'e' only if it is a 32-bit store (st).
|
|
|
|
define signext i32 @main() {
|
|
; CHECK-LABEL: main:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: lgrl %r0, e
|
|
; CHECK-NEXT: lgrl %r1, f
|
|
; CHECK-NEXT: srlg %r2, %r0, 32
|
|
; CHECK-NEXT: st %r2, 0(%r1)
|
|
; CHECK-NEXT: lhi %r2, 0
|
|
; CHECK-NEXT: sthrl %r2, e
|
|
; CHECK-NEXT: st %r0, 4(%r1)
|
|
; CHECK-NEXT: lghi %r2, 0
|
|
; CHECK-NEXT: strl %r0, d
|
|
; CHECK-NEXT: br %r14
|
|
%e = load i64, ptr @e, align 8
|
|
%esh = lshr i64 %e, 32
|
|
%ehi = trunc i64 %esh to i32
|
|
%elo = trunc i64 %e to i32
|
|
%t1 = load ptr, ptr @f, align 8
|
|
store i32 %ehi, ptr %t1, align 4
|
|
%f4 = getelementptr inbounds i8, ptr %t1, i64 4
|
|
store i32 %elo, ptr %f4, align 4
|
|
store i16 0, ptr @e, align 8
|
|
store i32 %elo, ptr @d, align 4
|
|
ret i32 0
|
|
}
|