[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / GlobalISel / prelegalizercombiner-not-really-equiv-insts.mir
blob71eae18d4144ed05707fe395f8ec38ecc5d975e9
1 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2 # RUN: llc -mtriple aarch64 -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs %s -o - | FileCheck %s
4 --- |
5   @g = external hidden unnamed_addr global i32, align 4
6   define void @not_necessarily_equiv_loads() { ret void }
7   define void @invariant_loads() { ret void }
8   define void @both_have_to_be_invariant_1() { ret void }
9   define void @both_have_to_be_invariant_2() { ret void }
10   define void @both_have_to_have_same_size() { ret void }
12 ...
13 ---
14 name:            not_necessarily_equiv_loads
15 tracksRegLiveness: true
16 machineFunctionInfo: {}
17 body:             |
18   bb.0:
20     ; %load1 || %load2 == %load1 is not necessarily true, even though they
21     ; both load from the same address. Whatever is in that address may be
22     ; changed by another instruction which appears between them.
23     ;
24     ; Check that we don't remove the G_OR.
26     ; CHECK-LABEL: name: not_necessarily_equiv_loads
27     ; CHECK: %ptr:_(p0) = G_GLOBAL_VALUE @g
28     ; CHECK-NEXT: %load1:_(s32) = G_LOAD %ptr(p0) :: (load (s32) from @g)
29     ; CHECK-NEXT: %load2:_(s32) = G_LOAD %ptr(p0) :: (load (s32) from @g)
30     ; CHECK-NEXT: %or:_(s32) = G_OR %load2, %load1
31     ; CHECK-NEXT: G_STORE %or(s32), %ptr(p0) :: (store (s32) into @g)
32     ; CHECK-NEXT: RET_ReallyLR
33     %ptr:_(p0) = G_GLOBAL_VALUE @g
34     %load1:_(s32) = G_LOAD %ptr(p0) :: (load (s32) from @g)
35     %load2:_(s32) = G_LOAD %ptr(p0) :: (load (s32) from @g)
36     %or:_(s32) = G_OR %load2, %load1
37     G_STORE %or(s32), %ptr(p0) :: (store (s32) into @g)
38     RET_ReallyLR
40 ...
41 ---
42 name:            invariant_loads
43 tracksRegLiveness: true
44 machineFunctionInfo: {}
45 body:             |
46   bb.0:
48     ; %load1 || %load2 == %load1 is fine here, because the loads are invariant.
49     ; TODO: Loads need to be CSE'd for this to work.
51     ; CHECK-LABEL: name: invariant_loads
52     ; CHECK: %ptr:_(p0) = G_GLOBAL_VALUE @g
53     ; CHECK-NEXT: %load1:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable invariant load (s32) from @g)
54     ; CHECK-NEXT: %load2:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable invariant load (s32) from @g)
55     ; CHECK-NEXT: %or:_(s32) = G_OR %load2, %load1
56     ; CHECK-NEXT: G_STORE %or(s32), %ptr(p0) :: (store (s32) into @g)
57     ; CHECK-NEXT: RET_ReallyLR
58     %ptr:_(p0) = G_GLOBAL_VALUE @g
59     %load1:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable invariant load (s32) from @g)
60     %load2:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable invariant load (s32) from @g)
61     %or:_(s32) = G_OR %load2, %load1
62     G_STORE %or(s32), %ptr(p0) :: (store (s32) into @g)
63     RET_ReallyLR
65 ...
66 ---
67 name:            both_have_to_be_invariant_1
68 tracksRegLiveness: true
69 machineFunctionInfo: {}
70 body:             |
71   bb.0:
73     ; We shouldn't combine here, because the loads both have to be invariant.
75     ; CHECK-LABEL: name: both_have_to_be_invariant_1
76     ; CHECK: %ptr:_(p0) = G_GLOBAL_VALUE @g
77     ; CHECK-NEXT: %load1:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable invariant load (s32) from @g)
78     ; CHECK-NEXT: %load2:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable load (s32) from @g)
79     ; CHECK-NEXT: %or:_(s32) = G_OR %load2, %load1
80     ; CHECK-NEXT: G_STORE %or(s32), %ptr(p0) :: (store (s32) into @g)
81     ; CHECK-NEXT: RET_ReallyLR
82     %ptr:_(p0) = G_GLOBAL_VALUE @g
83     %load1:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable invariant load (s32) from @g)
84     %load2:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable load (s32) from @g)
85     %or:_(s32) = G_OR %load2, %load1
86     G_STORE %or(s32), %ptr(p0) :: (store (s32) into @g)
87     RET_ReallyLR
88 ...
89 ---
90 name:            both_have_to_be_invariant_2
91 tracksRegLiveness: true
92 machineFunctionInfo: {}
93 body:             |
94   bb.0:
96     ; We shouldn't combine here, because the loads both have to be invariant.
98     ; CHECK-LABEL: name: both_have_to_be_invariant_2
99     ; CHECK: %ptr:_(p0) = G_GLOBAL_VALUE @g
100     ; CHECK-NEXT: %load1:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable load (s32) from @g)
101     ; CHECK-NEXT: %load2:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable invariant load (s32) from @g)
102     ; CHECK-NEXT: %or:_(s32) = G_OR %load2, %load1
103     ; CHECK-NEXT: G_STORE %or(s32), %ptr(p0) :: (store (s32) into @g)
104     ; CHECK-NEXT: RET_ReallyLR
105     %ptr:_(p0) = G_GLOBAL_VALUE @g
106     %load1:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable load (s32) from @g)
107     %load2:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable invariant load (s32) from @g)
108     %or:_(s32) = G_OR %load2, %load1
109     G_STORE %or(s32), %ptr(p0) :: (store (s32) into @g)
110     RET_ReallyLR
113 name:            both_have_to_have_same_size
114 tracksRegLiveness: true
115 machineFunctionInfo: {}
116 body:             |
117   bb.0:
119     ; We shouldn't combine here, because the loads both have to have the same size.
121     ; CHECK-LABEL: name: both_have_to_have_same_size
122     ; CHECK: %ptr:_(p0) = G_GLOBAL_VALUE @g
123     ; CHECK-NEXT: %load1:_(s32) = G_ZEXTLOAD %ptr(p0) :: (dereferenceable invariant load (s8) from @g)
124     ; CHECK-NEXT: %load2:_(s32) = G_ZEXTLOAD %ptr(p0) :: (dereferenceable invariant load (s16) from @g)
125     ; CHECK-NEXT: %or:_(s32) = G_OR %load2, %load1
126     ; CHECK-NEXT: G_STORE %or(s32), %ptr(p0) :: (store (s32) into @g)
127     ; CHECK-NEXT: RET_ReallyLR
128     %ptr:_(p0) = G_GLOBAL_VALUE @g
129     %load1:_(s32) = G_ZEXTLOAD %ptr(p0) :: (dereferenceable invariant load (s8) from @g)
130     %load2:_(s32) = G_ZEXTLOAD %ptr(p0) :: (dereferenceable invariant load (s16) from @g)
131     %or:_(s32) = G_OR %load2, %load1
132     G_STORE %or(s32), %ptr(p0) :: (store (s32) into @g)
133     RET_ReallyLR