| # RUN: llc -o /dev/null %s -mtriple=aarch64-apple-ios -run-pass=aarch64-collect-loh -debug-only=aarch64-collect-loh 2>&1 | FileCheck %s | 
 | # 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 | 
 | # REQUIRES: asserts | 
 | --- | | 
 |   define void @func0() { ret void } | 
 |  | 
 |   declare void @extfunc() | 
 |  | 
 |   @g0 = external global i32 | 
 |   @g1 = external global i32 | 
 |   @g2 = external global i32 | 
 |   @g3 = external global i32 | 
 |   @g4 = external global i32 | 
 |   @g5 = external global i32 | 
 | ... | 
 | --- | 
 | # Check various LOH variants. Remember that the algorithms walks the basic | 
 | # blocks backwards. | 
 | # CHECK-LABEL: ********** AArch64 Collect LOH ********** | 
 | # CHECK-LABEL: Looking in function func0 | 
 | name: func0 | 
 | tracksRegLiveness: true | 
 | body: | | 
 |   bb.0: | 
 |     ; CHECK: Adding MCLOH_AdrpAdrp: | 
 |     ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page) @g3 | 
 |     ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page) @g4 | 
 |     ; CHECK-NEXT: Adding MCLOH_AdrpAdrp: | 
 |     ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page) @g2 | 
 |     ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page) @g3 | 
 |     ; CHECK-NEXT: Adding MCLOH_AdrpAdrp: | 
 |     ; CHECK-NEXT: $x0 = ADRP target-flags(aarch64-page) @g0 | 
 |     ; CHECK-NEXT: $x0 = ADRP target-flags(aarch64-page) @g1 | 
 |     $x0 = ADRP target-flags(aarch64-page) @g0 | 
 |     $x0 = ADRP target-flags(aarch64-page) @g1 | 
 |     $x1 = ADRP target-flags(aarch64-page) @g2 | 
 |     $x1 = ADRP target-flags(aarch64-page) @g3 | 
 |     $x1 = ADRP target-flags(aarch64-page) @g4 | 
 |  | 
 |   bb.1: | 
 |     ; CHECK-NEXT: Adding MCLOH_AdrpAdd: | 
 |     ; CHECK-NEXT: $x20 = ADRP target-flags(aarch64-page) @g0 | 
 |     ; CHECK-NEXT: $x3 = ADDXri $x20, target-flags(aarch64-pageoff) @g0 | 
 |     ; CHECK-NEXT: Adding MCLOH_AdrpAdd: | 
 |     ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page) @g0 | 
 |     ; CHECK-NEXT: $x1 = ADDXri $x1, target-flags(aarch64-pageoff) @g0 | 
 |     $x1 = ADRP target-flags(aarch64-page) @g0 | 
 |     $x9 = SUBXri undef $x11, 5, 0 ; should not affect MCLOH formation | 
 |     $x1 = ADDXri $x1, target-flags(aarch64-pageoff) @g0, 0 | 
 |     $x20 = ADRP target-flags(aarch64-page) @g0 | 
 |     BL @extfunc, csr_aarch64_aapcs ; should not clobber X20 | 
 |     $x3 = ADDXri $x20, target-flags(aarch64-pageoff) @g0, 0 | 
 |  | 
 |   bb.2: | 
 |     ; CHECK-NOT: MCLOH_AdrpAdd | 
 |     $x9 = ADRP target-flags(aarch64-page) @g0 | 
 |     BL @extfunc, csr_aarch64_aapcs ; clobbers x9 | 
 |     ; Verification requires the use of 'undef' in front of the clobbered $x9 | 
 |     $x9 = ADDXri undef $x9, target-flags(aarch64-pageoff) @g0, 0 | 
 |  | 
 |   bb.3: | 
 |     ; CHECK-NOT: MCLOH_AdrpAdd | 
 |     $x10 = ADRP target-flags(aarch64-page) @g0 | 
 |     HINT 0, implicit def $x10 ; clobbers x10 | 
 |     $x10 = ADDXri $x10, target-flags(aarch64-pageoff) @g0, 0 | 
 |  | 
 |   bb.4: | 
 |     ; Cannot produce a LOH for multiple users | 
 |     ; CHECK-NOT: MCLOH_AdrpAdd | 
 |     $x10 = ADRP target-flags(aarch64-page) @g0 | 
 |     HINT 0, implicit def $x10 ; clobbers x10 | 
 |     $x11 = ADDXri $x10, target-flags(aarch64-pageoff) @g0, 0 | 
 |     $x12 = ADDXri $x10, target-flags(aarch64-pageoff) @g0, 0 | 
 |  | 
 |   bb.5: | 
 |     ; CHECK-NEXT: Adding MCLOH_AdrpLdr: | 
 |     ; CHECK-NEXT: $x5 = ADRP target-flags(aarch64-page) @g2 | 
 |     ; CHECK-NEXT: $s6 = LDRSui $x5, target-flags(aarch64-pageoff) @g2 | 
 |     ; CHECK-NEXT: Adding MCLOH_AdrpLdr: | 
 |     ; CHECK-NEXT: $x4 = ADRP target-flags(aarch64-page) @g2 | 
 |     ; CHECK-NEXT: $x4 = LDRXui $x4, target-flags(aarch64-pageoff) @g2 | 
 |     $x4 = ADRP target-flags(aarch64-page) @g2 | 
 |     $x4 = LDRXui $x4, target-flags(aarch64-pageoff) @g2 | 
 |     $x5 = ADRP target-flags(aarch64-page) @g2 | 
 |     $s6 = LDRSui $x5, target-flags(aarch64-pageoff) @g2 | 
 |  | 
 |   bb.6: | 
 |     ; CHECK-NEXT: Adding MCLOH_AdrpLdrGot: | 
 |     ; CHECK-NEXT: $x5 = ADRP target-flags(aarch64-page, aarch64-got) @g2 | 
 |     ; CHECK-NEXT: $x6 = LDRXui $x5, target-flags(aarch64-pageoff, aarch64-got) @g2 | 
 |     ; CHECK-NEXT: Adding MCLOH_AdrpLdrGot: | 
 |     ; CHECK-NEXT: $x4 = ADRP target-flags(aarch64-page, aarch64-got) @g2 | 
 |     ; CHECK-NEXT: $x4 = LDRXui $x4, target-flags(aarch64-pageoff, aarch64-got) @g2 | 
 |     $x4 = ADRP target-flags(aarch64-page, aarch64-got) @g2 | 
 |     $x4 = LDRXui $x4, target-flags(aarch64-pageoff, aarch64-got) @g2 | 
 |     $x5 = ADRP target-flags(aarch64-page, aarch64-got) @g2 | 
 |     $x6 = LDRXui $x5, target-flags(aarch64-pageoff, aarch64-got) @g2 | 
 |  | 
 |   bb.7: | 
 |     ; CHECK-NOT: Adding MCLOH_AdrpLdrGot: | 
 |     ; Loading a float value from a GOT table makes no sense so this should not | 
 |     ; produce an LOH. | 
 |     $x11 = ADRP target-flags(aarch64-page, aarch64-got) @g5 | 
 |     $s11 = LDRSui $x11, target-flags(aarch64-pageoff, aarch64-got) @g5 | 
 |  | 
 |   bb.8: | 
 |     ; CHECK-NEXT: Adding MCLOH_AdrpAddLdr: | 
 |     ; CHECK-NEXT: $x7 = ADRP target-flags(aarch64-page) @g3 | 
 |     ; CHECK-NEXT: $x8 = ADDXri $x7, target-flags(aarch64-pageoff) @g3 | 
 |     ; CHECK-NEXT: $d1 = LDRDui $x8, 8 | 
 |     $x7 = ADRP target-flags(aarch64-page) @g3 | 
 |     $x8 = ADDXri $x7, target-flags(aarch64-pageoff) @g3, 0 | 
 |     $d1 = LDRDui $x8, 8 | 
 |  | 
 |   bb.9: | 
 |     ; CHECK-NEXT: Adding MCLOH_AdrpAdd: | 
 |     ; CHECK-NEXT: $x3 = ADRP target-flags(aarch64-page) @g3 | 
 |     ; CHECK-NEXT: $x3 = ADDXri $x3, target-flags(aarch64-pageoff) @g3 | 
 |     ; CHECK-NEXT: Adding MCLOH_AdrpAdd: | 
 |     ; CHECK-NEXT: $x5 = ADRP target-flags(aarch64-page) @g3 | 
 |     ; CHECK-NEXT: $x2 = ADDXri $x5, target-flags(aarch64-pageoff) @g3 | 
 |     ; CHECK-NEXT: Adding MCLOH_AdrpAddStr: | 
 |     ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page) @g3 | 
 |     ; CHECK-NEXT: $x1 = ADDXri $x1, target-flags(aarch64-pageoff) @g3 | 
 |     ; CHECK-NEXT: STRXui $xzr, $x1, 16 | 
 |     $x1 = ADRP target-flags(aarch64-page) @g3 | 
 |     $x1 = ADDXri $x1, target-flags(aarch64-pageoff) @g3, 0 | 
 |     STRXui $xzr, $x1, 16 | 
 |  | 
 |     ; This sequence should just produce an AdrpAdd (not AdrpAddStr) | 
 |     $x5 = ADRP target-flags(aarch64-page) @g3 | 
 |     $x2 = ADDXri $x5, target-flags(aarch64-pageoff) @g3, 0 | 
 |     STRXui $x2, undef $x11, 16 | 
 |  | 
 |     ; This sequence should just produce an AdrpAdd (not AdrpAddStr) | 
 |     $x3 = ADRP target-flags(aarch64-page) @g3 | 
 |     $x3 = ADDXri $x3, target-flags(aarch64-pageoff) @g3, 0 | 
 |     STRXui $x3, $x3, 16 | 
 |  | 
 |   bb.10: | 
 |     ; CHECK-NEXT: Adding MCLOH_AdrpLdr: | 
 |     ; CHECK-NEXT: $x2 = ADRP target-flags(aarch64-page) @g3 | 
 |     ; CHECK-NEXT: $x2 = LDRXui $x2, target-flags(aarch64-pageoff) @g3 | 
 |     ; CHECK-NEXT: Adding MCLOH_AdrpLdrGotLdr: | 
 |     ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page, aarch64-got) @g4 | 
 |     ; CHECK-NEXT: $x1 = LDRXui $x1, target-flags(aarch64-pageoff, aarch64-got) @g4 | 
 |     ; CHECK-NEXT: $x1 = LDRXui $x1, 24 | 
 |     $x1 = ADRP target-flags(aarch64-page, aarch64-got) @g4 | 
 |     $x1 = LDRXui $x1, target-flags(aarch64-pageoff, aarch64-got) @g4 | 
 |     $x1 = LDRXui $x1, 24 | 
 |     ; Should just produce a MCLOH_AdrpLdr (not MCLOH_AdrpLdrGotLdr) | 
 |     $x2 = ADRP target-flags(aarch64-page) @g3 | 
 |     $x2 = LDRXui $x2, target-flags(aarch64-pageoff) @g3 | 
 |     $x2 = LDRXui $x2, 24 | 
 |  | 
 |   bb.11: | 
 |     ; CHECK-NEXT: Adding MCLOH_AdrpLdr | 
 |     ; CHECK-NEXT: $x5 = ADRP target-flags(aarch64-page) @g1 | 
 |     ; CHECK-NEXT: $x5 = LDRXui $x5, target-flags(aarch64-pageoff) @g1 | 
 |     ; CHECK-NEXT: Adding MCLOH_AdrpLdrGotStr: | 
 |     ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page, aarch64-got) @g4 | 
 |     ; CHECK-NEXT: $x1 = LDRXui $x1, target-flags(aarch64-pageoff, aarch64-got) @g4 | 
 |     ; CHECK-NEXT: STRXui $xzr, $x1, 32 | 
 |     $x1 = ADRP target-flags(aarch64-page, aarch64-got) @g4 | 
 |     $x1 = LDRXui $x1, target-flags(aarch64-pageoff, aarch64-got) @g4 | 
 |     STRXui $xzr, $x1, 32 | 
 |     ; Should just produce a MCLOH_AdrpLdr (not MCLOH_AdrpLdrGotStr) | 
 |     $x5 = ADRP target-flags(aarch64-page) @g1 | 
 |     $x5 = LDRXui $x5, target-flags(aarch64-pageoff) @g1 | 
 |     STRXui undef $x11, $x5, 32 | 
 |  | 
 |   bb.12: | 
 |     ; CHECK-NOT: MCLOH_AdrpAdrp | 
 |     ; CHECK: Adding MCLOH_AdrpAddLdr | 
 |     ; $x9 = ADRP @g4 | 
 |     ; $x9 = ADDXri $x9, @g4 | 
 |     ; $x5 = LDRXui $x9, 0 | 
 |     $x9 = ADRP target-flags(aarch64-page, aarch64-got) @g4 | 
 |     $x9 = ADDXri $x9, target-flags(aarch64-pageoff, aarch64-got) @g4, 0 | 
 |     $x5 = LDRXui $x9, 0 | 
 |     $x9 = ADRP target-flags(aarch64-page, aarch64-got) @g5 | 
 |  | 
 |   bb.13: | 
 |     ; Cannot produce a LOH for multiple users | 
 |     ; CHECK-NOT: MCLOH_AdrpAdd | 
 |     $x10 = ADRP target-flags(aarch64-page) @g0 | 
 |     $x11 = ADDXri $x10, target-flags(aarch64-pageoff) @g0, 0 | 
 |     B %bb.14 | 
 |  | 
 |   bb.14: | 
 |     liveins: $x10 | 
 |     $x12 = ADDXri $x10, target-flags(aarch64-pageoff) @g0, 0 | 
 |  | 
 |   bb.15: | 
 |     ; Should not produce a LOH when reg is clobbered by bundled regmask | 
 |     ; CHECK-NOT: MCLOH_AdrpAdrp | 
 |     $x8 = ADRP target-flags(aarch64-page) @g0 | 
 |     BUNDLE { | 
 |       BL @extfunc, csr_aarch64_aapcs | 
 |     } | 
 |     $x8 = ADRP target-flags(aarch64-page) @g1 | 
 | ... |