1# RUN: llc -o /dev/null %s -mtriple=aarch64-apple-ios -run-pass=aarch64-collect-loh -debug-only=aarch64-collect-loh 2>&1 | FileCheck %s 2# RUN: llc -debugify-and-strip-all-safe -o /dev/null %s -mtriple=aarch64-apple-ios -run-pass=aarch64-collect-loh -debug-only=aarch64-collect-loh 2>&1 | FileCheck %s 3# REQUIRES: asserts 4--- | 5 define void @func0() { ret void } 6 7 declare void @extfunc() 8 9 @g0 = external global i32 10 @g1 = external global i32 11 @g2 = external global i32 12 @g3 = external global i32 13 @g4 = external global i32 14 @g5 = external global i32 15... 16--- 17# Check various LOH variants. Remember that the algorithms walks the basic 18# blocks backwards. 19# CHECK-LABEL: ********** AArch64 Collect LOH ********** 20# CHECK-LABEL: Looking in function func0 21name: func0 22tracksRegLiveness: true 23body: | 24 bb.0: 25 ; CHECK: Adding MCLOH_AdrpAdrp: 26 ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page) @g3 27 ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page) @g4 28 ; CHECK-NEXT: Adding MCLOH_AdrpAdrp: 29 ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page) @g2 30 ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page) @g3 31 ; CHECK-NEXT: Adding MCLOH_AdrpAdrp: 32 ; CHECK-NEXT: $x0 = ADRP target-flags(aarch64-page) @g0 33 ; CHECK-NEXT: $x0 = ADRP target-flags(aarch64-page) @g1 34 $x0 = ADRP target-flags(aarch64-page) @g0 35 $x0 = ADRP target-flags(aarch64-page) @g1 36 $x1 = ADRP target-flags(aarch64-page) @g2 37 $x1 = ADRP target-flags(aarch64-page) @g3 38 $x1 = ADRP target-flags(aarch64-page) @g4 39 40 bb.1: 41 ; CHECK-NEXT: Adding MCLOH_AdrpAdd: 42 ; CHECK-NEXT: $x20 = ADRP target-flags(aarch64-page) @g0 43 ; CHECK-NEXT: $x3 = ADDXri $x20, target-flags(aarch64-pageoff) @g0 44 ; CHECK-NEXT: Adding MCLOH_AdrpAdd: 45 ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page) @g0 46 ; CHECK-NEXT: $x1 = ADDXri $x1, target-flags(aarch64-pageoff) @g0 47 $x1 = ADRP target-flags(aarch64-page) @g0 48 $x9 = SUBXri undef $x11, 5, 0 ; should not affect MCLOH formation 49 $x1 = ADDXri $x1, target-flags(aarch64-pageoff) @g0, 0 50 $x20 = ADRP target-flags(aarch64-page) @g0 51 BL @extfunc, csr_aarch64_aapcs ; should not clobber X20 52 $x3 = ADDXri $x20, target-flags(aarch64-pageoff) @g0, 0 53 54 bb.2: 55 ; CHECK-NOT: MCLOH_AdrpAdd 56 $x9 = ADRP target-flags(aarch64-page) @g0 57 BL @extfunc, csr_aarch64_aapcs ; clobbers x9 58 ; Verification requires the use of 'undef' in front of the clobbered $x9 59 $x9 = ADDXri undef $x9, target-flags(aarch64-pageoff) @g0, 0 60 61 bb.3: 62 ; CHECK-NOT: MCLOH_AdrpAdd 63 $x10 = ADRP target-flags(aarch64-page) @g0 64 HINT 0, implicit def $x10 ; clobbers x10 65 $x10 = ADDXri $x10, target-flags(aarch64-pageoff) @g0, 0 66 67 bb.4: 68 ; Cannot produce a LOH for multiple users 69 ; CHECK-NOT: MCLOH_AdrpAdd 70 $x10 = ADRP target-flags(aarch64-page) @g0 71 HINT 0, implicit def $x10 ; clobbers x10 72 $x11 = ADDXri $x10, target-flags(aarch64-pageoff) @g0, 0 73 $x12 = ADDXri $x10, target-flags(aarch64-pageoff) @g0, 0 74 75 bb.5: 76 ; CHECK-NEXT: Adding MCLOH_AdrpLdr: 77 ; CHECK-NEXT: $x5 = ADRP target-flags(aarch64-page) @g2 78 ; CHECK-NEXT: $s6 = LDRSui $x5, target-flags(aarch64-pageoff) @g2 79 ; CHECK-NEXT: Adding MCLOH_AdrpLdr: 80 ; CHECK-NEXT: $x4 = ADRP target-flags(aarch64-page) @g2 81 ; CHECK-NEXT: $x4 = LDRXui $x4, target-flags(aarch64-pageoff) @g2 82 $x4 = ADRP target-flags(aarch64-page) @g2 83 $x4 = LDRXui $x4, target-flags(aarch64-pageoff) @g2 84 $x5 = ADRP target-flags(aarch64-page) @g2 85 $s6 = LDRSui $x5, target-flags(aarch64-pageoff) @g2 86 87 bb.6: 88 ; CHECK-NEXT: Adding MCLOH_AdrpLdrGot: 89 ; CHECK-NEXT: $x5 = ADRP target-flags(aarch64-page, aarch64-got) @g2 90 ; CHECK-NEXT: $x6 = LDRXui $x5, target-flags(aarch64-pageoff, aarch64-got) @g2 91 ; CHECK-NEXT: Adding MCLOH_AdrpLdrGot: 92 ; CHECK-NEXT: $x4 = ADRP target-flags(aarch64-page, aarch64-got) @g2 93 ; CHECK-NEXT: $x4 = LDRXui $x4, target-flags(aarch64-pageoff, aarch64-got) @g2 94 $x4 = ADRP target-flags(aarch64-page, aarch64-got) @g2 95 $x4 = LDRXui $x4, target-flags(aarch64-pageoff, aarch64-got) @g2 96 $x5 = ADRP target-flags(aarch64-page, aarch64-got) @g2 97 $x6 = LDRXui $x5, target-flags(aarch64-pageoff, aarch64-got) @g2 98 99 bb.7: 100 ; CHECK-NOT: Adding MCLOH_AdrpLdrGot: 101 ; Loading a float value from a GOT table makes no sense so this should not 102 ; produce an LOH. 103 $x11 = ADRP target-flags(aarch64-page, aarch64-got) @g5 104 $s11 = LDRSui $x11, target-flags(aarch64-pageoff, aarch64-got) @g5 105 106 bb.8: 107 ; CHECK-NEXT: Adding MCLOH_AdrpAddLdr: 108 ; CHECK-NEXT: $x7 = ADRP target-flags(aarch64-page) @g3 109 ; CHECK-NEXT: $x8 = ADDXri $x7, target-flags(aarch64-pageoff) @g3 110 ; CHECK-NEXT: $d1 = LDRDui $x8, 8 111 $x7 = ADRP target-flags(aarch64-page) @g3 112 $x8 = ADDXri $x7, target-flags(aarch64-pageoff) @g3, 0 113 $d1 = LDRDui $x8, 8 114 115 bb.9: 116 ; CHECK-NEXT: Adding MCLOH_AdrpAdd: 117 ; CHECK-NEXT: $x3 = ADRP target-flags(aarch64-page) @g3 118 ; CHECK-NEXT: $x3 = ADDXri $x3, target-flags(aarch64-pageoff) @g3 119 ; CHECK-NEXT: Adding MCLOH_AdrpAdd: 120 ; CHECK-NEXT: $x5 = ADRP target-flags(aarch64-page) @g3 121 ; CHECK-NEXT: $x2 = ADDXri $x5, target-flags(aarch64-pageoff) @g3 122 ; CHECK-NEXT: Adding MCLOH_AdrpAddStr: 123 ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page) @g3 124 ; CHECK-NEXT: $x1 = ADDXri $x1, target-flags(aarch64-pageoff) @g3 125 ; CHECK-NEXT: STRXui $xzr, $x1, 16 126 $x1 = ADRP target-flags(aarch64-page) @g3 127 $x1 = ADDXri $x1, target-flags(aarch64-pageoff) @g3, 0 128 STRXui $xzr, $x1, 16 129 130 ; This sequence should just produce an AdrpAdd (not AdrpAddStr) 131 $x5 = ADRP target-flags(aarch64-page) @g3 132 $x2 = ADDXri $x5, target-flags(aarch64-pageoff) @g3, 0 133 STRXui $x2, undef $x11, 16 134 135 ; This sequence should just produce an AdrpAdd (not AdrpAddStr) 136 $x3 = ADRP target-flags(aarch64-page) @g3 137 $x3 = ADDXri $x3, target-flags(aarch64-pageoff) @g3, 0 138 STRXui $x3, $x3, 16 139 140 bb.10: 141 ; CHECK-NEXT: Adding MCLOH_AdrpLdr: 142 ; CHECK-NEXT: $x2 = ADRP target-flags(aarch64-page) @g3 143 ; CHECK-NEXT: $x2 = LDRXui $x2, target-flags(aarch64-pageoff) @g3 144 ; CHECK-NEXT: Adding MCLOH_AdrpLdrGotLdr: 145 ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page, aarch64-got) @g4 146 ; CHECK-NEXT: $x1 = LDRXui $x1, target-flags(aarch64-pageoff, aarch64-got) @g4 147 ; CHECK-NEXT: $x1 = LDRXui $x1, 24 148 $x1 = ADRP target-flags(aarch64-page, aarch64-got) @g4 149 $x1 = LDRXui $x1, target-flags(aarch64-pageoff, aarch64-got) @g4 150 $x1 = LDRXui $x1, 24 151 ; Should just produce a MCLOH_AdrpLdr (not MCLOH_AdrpLdrGotLdr) 152 $x2 = ADRP target-flags(aarch64-page) @g3 153 $x2 = LDRXui $x2, target-flags(aarch64-pageoff) @g3 154 $x2 = LDRXui $x2, 24 155 156 bb.11: 157 ; CHECK-NEXT: Adding MCLOH_AdrpLdr 158 ; CHECK-NEXT: $x5 = ADRP target-flags(aarch64-page) @g1 159 ; CHECK-NEXT: $x5 = LDRXui $x5, target-flags(aarch64-pageoff) @g1 160 ; CHECK-NEXT: Adding MCLOH_AdrpLdrGotStr: 161 ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page, aarch64-got) @g4 162 ; CHECK-NEXT: $x1 = LDRXui $x1, target-flags(aarch64-pageoff, aarch64-got) @g4 163 ; CHECK-NEXT: STRXui $xzr, $x1, 32 164 $x1 = ADRP target-flags(aarch64-page, aarch64-got) @g4 165 $x1 = LDRXui $x1, target-flags(aarch64-pageoff, aarch64-got) @g4 166 STRXui $xzr, $x1, 32 167 ; Should just produce a MCLOH_AdrpLdr (not MCLOH_AdrpLdrGotStr) 168 $x5 = ADRP target-flags(aarch64-page) @g1 169 $x5 = LDRXui $x5, target-flags(aarch64-pageoff) @g1 170 STRXui undef $x11, $x5, 32 171 172 bb.12: 173 ; CHECK-NOT: MCLOH_AdrpAdrp 174 ; CHECK: Adding MCLOH_AdrpAddLdr 175 ; $x9 = ADRP @g4 176 ; $x9 = ADDXri $x9, @g4 177 ; $x5 = LDRXui $x9, 0 178 $x9 = ADRP target-flags(aarch64-page, aarch64-got) @g4 179 $x9 = ADDXri $x9, target-flags(aarch64-pageoff, aarch64-got) @g4, 0 180 $x5 = LDRXui $x9, 0 181 $x9 = ADRP target-flags(aarch64-page, aarch64-got) @g5 182 183 bb.13: 184 ; Cannot produce a LOH for multiple users 185 ; CHECK-NOT: MCLOH_AdrpAdd 186 $x10 = ADRP target-flags(aarch64-page) @g0 187 $x11 = ADDXri $x10, target-flags(aarch64-pageoff) @g0, 0 188 B %bb.14 189 190 bb.14: 191 liveins: $x10 192 $x12 = ADDXri $x10, target-flags(aarch64-pageoff) @g0, 0 193... 194