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
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 }
14 name: not_necessarily_equiv_loads
15 tracksRegLiveness: true
16 machineFunctionInfo: {}
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.
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)
43 tracksRegLiveness: true
44 machineFunctionInfo: {}
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)
67 name: both_have_to_be_invariant_1
68 tracksRegLiveness: true
69 machineFunctionInfo: {}
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)
90 name: both_have_to_be_invariant_2
91 tracksRegLiveness: true
92 machineFunctionInfo: {}
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)
113 name: both_have_to_have_same_size
114 tracksRegLiveness: true
115 machineFunctionInfo: {}
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)