| # RUN: llc -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 | |
| ... |