[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / aarch64-checkMergeStoreCandidatesForDependencies.ll
blob15fe66b1a591f290f5347b5a5e4152b5286c2e82
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple aarch64-- -o - %s | FileCheck %s
4 ; This used to fail when legalizing types, due to not detecting that a cycle
5 ; in the DAG was introduced when merging consecutive stores.
7 ; When checking for cycles the DAG looks like this:
9 ;   SelectionDAG has 16 nodes:
10 ;     t0: ch = EntryToken
11 ;       t3: i64 = add nuw GlobalAddress:i64<ptr @g0> 0, Constant:i64<8>
12 ;     t6: ch = store<(store (s64) into %ir.sp1, align 1, !tbaa !1)> t0, Constant:i64<0>, t3, undef:i64
13 ;     t7: i64,ch = load<(load (s64) from `ptr undef`, align 1)> t6, undef:i64, undef:i64
14 ;       t8: i64 = add nuw t7, Constant:i64<8>
15 ;     t9: i64,ch = load<(load (s64) from %ir.lp0, align 1)> t6, t8, undef:i64
16 ;         t21: ch = store<(store (s64) into %ir.sp01, align 1)> t19:1, Constant:i64<0>, GlobalAddress:i64<ptr @g0> 0, undef:i64
17 ;       t24: ch = TokenFactor t7:1, t9:1, t21
18 ;     t14: ch,glue = CopyToReg t24, Register:i64 $x0, t19
19 ;     t19: i64,ch = load<(load (s64) from %ir.lp12, align 1, !tbaa !7)> t0, t9, undef:i64
20 ;     t15: ch = AArch64ISD::RET_GLUE t14, Register:i64 $x0, t14:1
22 ; The t21 store depends on t19 (via a chain dependency),
23 ; t19 load depends on t9 (via address operand),
24 ; t9 load depends on the t6 store (via chain).
26 ; So there is a ordering dependency between the two stores, even if it can't
27 ; be found by only following chain dependencies. Neither can it be found by
28 ; scanning from all merge candidates when only considering the non-chain
29 ; operands as a starting point for the scan (as
30 ; checkMergeStoreCandidatesForDependencies used to do).
32 ; This test case validates that ISel is a success, and that no store merge is
33 ; performed.
35 %str0 = type { i64, i64 }
36 %str1 = type { i64, ptr }
38 @g0 = external global %str0, align 1
40 define i64 @foo() {
41 ; CHECK-LABEL: foo:
42 ; CHECK:       // %bb.0: // %entry
43 ; CHECK-NEXT:    adrp x8, :got:g0
44 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:g0]
45 ; CHECK-NEXT:    ldr x9, [x8]
46 ; CHECK-NEXT:    str xzr, [x8, #8]
47 ; CHECK-NEXT:    ldr x9, [x9, #8]
48 ; CHECK-NEXT:    ldr x0, [x9]
49 ; CHECK-NEXT:    str xzr, [x8]
50 ; CHECK-NEXT:    ret
51 entry:
52   %sp1 = getelementptr inbounds %str0, ptr @g0, i32 0, i32 1
53   store i64 0, ptr %sp1, align 1, !tbaa !1
54   %l0 = load ptr, ptr undef, align 1
55   %lp0 = getelementptr inbounds %str1, ptr %l0, i32 0, i32 1
56   %l1 = load ptr, ptr %lp0, align 1
57   %l2 = load i64, ptr %l1, align 1, !tbaa !7
58   store i64 0, ptr @g0, align 1
59   ret i64 %l2
62 !llvm.ident = !{!0}
64 !0 = !{!"clang version 14.0.0.prerel"}
65 !1 = !{!2, !6, i16 1}
66 !2 = !{!"dinges", !3, i16 0, !6, i16 1}
67 !3 = !{!"int", !4, i16 0}
68 !4 = !{!"omnipotent char", !5, i16 0}
69 !5 = !{!"Simple C/C++ TBAA"}
70 !6 = !{!"any pointer", !4, i16 0}
71 !7 = !{!2, !3, i16 0}