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