| # RUN: llc -run-pass=aarch64-ldst-opt -mtriple=arm64-apple-iphoneos -verify-machineinstrs -aarch64-load-store-renaming=true -o - %s | FileCheck %s |
| # RUN: llc -run-pass=aarch64-ldst-opt -mtriple=arm64-apple-iphoneos -verify-machineinstrs -o - %s | FileCheck --check-prefix=NO-RENAME %s |
| |
| # NO-RENAME-NOT: STP |
| # NO-RENAME: test12 |
| # NO-RENAME: STP |
| # NO-RENAME-NOT: STP |
| # |
| --- |
| # CHECK-LABEL: name: test1 |
| # CHECK: bb.0: |
| # CHECK-NEXT: liveins: $x0, $x1 |
| # CHECK: $x10, renamable $x8 = LDPXi renamable $x0, 0 :: (load 8) |
| # CHECK-NEXT: renamable $x9 = LDRXui renamable $x0, 1 :: (load 8) |
| # CHECK-NEXT: STRXui renamable $x9, renamable $x0, 100 :: (store 8, align 4) |
| # CHECK-NEXT: renamable $x8 = ADDXrr $x8, $x8 |
| # CHECK-NEXT: STPXi renamable $x8, killed $x10, renamable $x0, 10 :: (store 8, align 4) |
| # CHECK-NEXT: RET undef $lr |
| |
| name: test1 |
| alignment: 4 |
| tracksRegLiveness: true |
| liveins: |
| - { reg: '$x0' } |
| - { reg: '$x1' } |
| - { reg: '$x8' } |
| frameInfo: |
| maxAlignment: 1 |
| maxCallFrameSize: 0 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1 |
| renamable $x9, renamable $x8 = LDPXi renamable $x0, 0 :: (load 8) |
| STRXui renamable killed $x9, renamable $x0, 11 :: (store 8, align 4) |
| renamable $x9 = LDRXui renamable $x0, 1 :: (load 8) |
| STRXui renamable $x9, renamable $x0, 100 :: (store 8, align 4) |
| renamable $x8 = ADDXrr $x8, $x8 |
| STRXui renamable $x8, renamable $x0, 10 :: (store 8, align 4) |
| RET undef $lr |
| |
| ... |
| --- |
| # CHECK-LABEL: name: test2 |
| # CHECK-LABEL: bb.0: |
| # CHECK-NEXT: liveins: $x0, $x9, $x1 |
| |
| # CHECK: $x10, renamable $x8 = LDPXi renamable $x9, 0 :: (load 8) |
| # CHECK-NEXT: renamable $x9 = LDRXui renamable $x0, 2 :: (load 8) |
| # CHECK-NEXT: STRXui renamable $x9, renamable $x0, 100 :: (store 8, align 4) |
| # CHECK-NEXT: renamable $x8 = ADDXrr $x8, $x8 |
| # CHECK-NEXT: STPXi renamable $x8, killed $x10, renamable $x0, 10 :: (store 8, align 4) |
| # CHECK-NEXT: RET undef $lr |
| |
| name: test2 |
| alignment: 4 |
| tracksRegLiveness: true |
| liveins: |
| - { reg: '$x0' } |
| - { reg: '$x1' } |
| - { reg: '$x9' } |
| frameInfo: |
| maxAlignment: 1 |
| maxCallFrameSize: 0 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x9, $x1 |
| renamable $x9, renamable $x8 = LDPXi renamable $x9, 0 :: (load 8) |
| STRXui renamable killed $x9, renamable $x0, 11 :: (store 8, align 4) |
| renamable $x9 = LDRXui renamable $x0, 2 :: (load 8) |
| STRXui renamable $x9, renamable $x0, 100 :: (store 8, align 4) |
| renamable $x8 = ADDXrr $x8, $x8 |
| STRXui renamable $x8, renamable $x0, 10 :: (store 8, align 4) |
| RET undef $lr |
| |
| ... |
| --- |
| # MOVK has a tied operand and we currently do not rename across tied defs. |
| # CHECK-LABEL: bb.0: |
| # CHECK-NEXT: liveins: $x0 |
| # |
| # CHECK: renamable $x8 = MRS 58880 |
| # CHECK-NEXT: renamable $x8 = MOVZXi 15309, 0 |
| # CHECK-NEXT: renamable $x8 = MOVKXi renamable $x8, 26239, 16 |
| # CHECK-NEXT: STRXui renamable $x8, renamable $x0, 0, implicit killed $x8 :: (store 8) |
| # CHECK-NEXT: renamable $x8 = MRS 55840 |
| # CHECK-NEXT: STRXui killed renamable $x8, killed renamable $x0, 1, implicit killed $x8 :: (store 8) |
| # CHECK-NEXT: RET undef $lr |
| # |
| name: test3 |
| alignment: 2 |
| tracksRegLiveness: true |
| liveins: |
| - { reg: '$x0' } |
| frameInfo: |
| maxCallFrameSize: 0 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0 |
| |
| renamable $x8 = MRS 58880 |
| renamable $x8 = MOVZXi 15309, 0 |
| renamable $x8 = MOVKXi renamable $x8, 26239, 16 |
| STRXui renamable $x8, renamable $x0, 0, implicit killed $x8 :: (store 8) |
| renamable $x8 = MRS 55840 |
| STRXui killed renamable $x8, renamable killed $x0, 1, implicit killed $x8 :: (store 8) |
| RET undef $lr |
| |
| ... |
| --- |
| # CHECK-LABEL: name: test4 |
| # CHECK-LABEL: bb.0: |
| # CHECK-NEXT: liveins: $x0, $x1 |
| |
| # CHECK: $x9 = MRS 58880 |
| # CHECK-NEXT: renamable $x8 = MRS 55840 |
| # CHECK-NEXT: STPXi $x9, killed renamable $x8, killed renamable $x0, 0 :: (store 4) |
| # CHECK-NEXT: RET undef $lr |
| |
| name: test4 |
| alignment: 4 |
| tracksRegLiveness: true |
| liveins: |
| - { reg: '$x0' } |
| - { reg: '$x1' } |
| - { reg: '$x8' } |
| frameInfo: |
| maxAlignment: 1 |
| maxCallFrameSize: 0 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1 |
| |
| renamable $x8 = MRS 58880 |
| STRXui renamable $x8, renamable $x0, 0, implicit killed $x8 :: (store 4) |
| renamable $x8 = MRS 55840 |
| STRXui killed renamable $x8, renamable killed $x0, 1, implicit killed $x8 :: (store 4) |
| RET undef $lr |
| |
| ... |
| --- |
| # CHECK-LABEL: name: test5 |
| # CHECK-LABEL: bb.0: |
| # CHECK-NEXT: liveins: $x0, $x1 |
| |
| # CHECK: $x9 = MRS 58880 |
| # CHECK-NEXT: renamable $x8 = MRS 55840 |
| # CHECK-NEXT: STPWi $w9, killed renamable $w8, killed renamable $x0, 0 :: (store 4) |
| # CHECK-NEXT: RET undef $lr |
| |
| name: test5 |
| alignment: 4 |
| tracksRegLiveness: true |
| liveins: |
| - { reg: '$x0' } |
| - { reg: '$x1' } |
| - { reg: '$x8' } |
| frameInfo: |
| maxAlignment: 1 |
| maxCallFrameSize: 0 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1 |
| |
| renamable $x8 = MRS 58880 |
| STRWui renamable $w8, renamable $x0, 0, implicit killed $x8 :: (store 4) |
| renamable $x8 = MRS 55840 |
| STRWui killed renamable $w8, renamable killed $x0, 1, implicit killed $x8 :: (store 4) |
| RET undef $lr |
| |
| ... |
| --- |
| # CHECK-LABEL: name: test6 |
| # CHECK-LABEL bb.0: |
| # CHECK: liveins: $x0, $x1, $q3 |
| |
| # CHECK: renamable $q9 = LDRQui $x0, 0 :: (load 16) |
| # CHECK-NEXT: renamable $q9 = XTNv8i16 renamable $q9, killed renamable $q3 |
| # CHECK-NEXT: STRQui renamable $q9, renamable $x0, 11 :: (store 16, align 4) |
| # CHECK-NEXT: renamable $q9 = FADDv2f64 renamable $q9, renamable $q9 |
| # CHECK-NEXT: STRQui renamable $q9, renamable $x0, 10 :: (store 16, align 4) |
| # CHECK-NEXT: RET undef $lr |
| |
| # XTN has a tied use-def. |
| name: test6 |
| alignment: 4 |
| tracksRegLiveness: true |
| liveins: |
| - { reg: '$x0' } |
| - { reg: '$x1' } |
| - { reg: '$x8' } |
| - { reg: '$q3' } |
| frameInfo: |
| maxAlignment: 1 |
| maxCallFrameSize: 0 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $q3 |
| renamable $q9 = LDRQui $x0, 0 :: (load 16) |
| renamable $q9 = XTNv8i16 renamable $q9, killed renamable $q3 |
| STRQui renamable $q9, renamable $x0, 11 :: (store 16, align 4) |
| renamable $q9 = FADDv2f64 renamable $q9, renamable $q9 |
| STRQui renamable $q9, renamable $x0, 10 :: (store 16, align 4) |
| RET undef $lr |
| |
| ... |
| --- |
| # Currently we do not rename across frame-setup instructions. |
| # CHECK-LABEL: name: test7 |
| # CHECK-LABEL: bb.0: |
| # CHECK-NEXT: liveins: $x0, $x1 |
| |
| # CHECK: $sp = frame-setup SUBXri $sp, 64, 0 |
| # CHECK-NEXT: renamable $x9 = frame-setup LDRXui renamable $x0, 0 :: (load 8) |
| # CHECK-NEXT: STRXui renamable $x9, $x0, 10 :: (store 8, align 4) |
| # CHECK-NEXT: renamable $x9 = LDRXui renamable $x0, 1 :: (load 8) |
| # CHECK-NEXT: STRXui renamable $x9, $x0, 11 :: (store 8, align 4) |
| # CHECK-NEXT: RET undef $lr |
| # |
| name: test7 |
| alignment: 4 |
| tracksRegLiveness: true |
| liveins: |
| - { reg: '$x0' } |
| - { reg: '$x1' } |
| - { reg: '$x8' } |
| frameInfo: |
| stackSize: 64 |
| maxAlignment: 16 |
| adjustsStack: true |
| hasCalls: true |
| maxCallFrameSize: 0 |
| stack: |
| - { id: 0, type: spill-slot, offset: -48, size: 16, alignment: 16 } |
| - { id: 1, type: spill-slot, offset: -64, size: 16, alignment: 16 } |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1 |
| $sp = frame-setup SUBXri $sp, 64, 0 |
| renamable $x9 = frame-setup LDRXui renamable $x0, 0 :: (load 8) |
| STRXui renamable $x9, $x0, 10 :: (store 8, align 4) |
| renamable $x9 = LDRXui renamable $x0, 1 :: (load 8) |
| STRXui renamable $x9, $x0, 11 :: (store 8, align 4) |
| RET undef $lr |
| ... |
| --- |
| # CHECK-LABEL: name: test8 |
| # CHECK-LABEL: bb.0: |
| # CHECK-NEXT: liveins: $x0, $x1 |
| |
| # CHECK: renamable $x8 = MRS 58880 |
| # CHECK-NEXT: $w9 = ORRWrs $wzr, killed renamable $w8, 0, implicit-def $x9 |
| # CHECK-NEXT: renamable $x8 = MRS 55840 |
| # CHECK-NEXT: STPWi $w9, killed renamable $w8, killed renamable $x0, 0 :: (store 4) |
| # CHECK-NEXT: RET undef $lr |
| |
| name: test8 |
| alignment: 4 |
| tracksRegLiveness: true |
| liveins: |
| - { reg: '$x0' } |
| - { reg: '$x1' } |
| - { reg: '$x8' } |
| frameInfo: |
| maxAlignment: 1 |
| maxCallFrameSize: 0 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1 |
| |
| renamable $x8 = MRS 58880 |
| renamable $w8 = ORRWrs $wzr, killed renamable $w8, 0, implicit-def $x8 |
| STRWui renamable $w8, renamable $x0, 0, implicit killed $x8 :: (store 4) |
| renamable $x8 = MRS 55840 |
| STRWui killed renamable $w8, renamable killed $x0, 1, implicit killed $x8 :: (store 4) |
| RET undef $lr |
| |
| ... |
| --- |
| # The reg class returned for $q9 contains only the first 16 Q registers. |
| # TODO: Can we check that all instructions that require renaming also support |
| # the second 16 Q registers? |
| # CHECK-LABEL: name: test9 |
| # CHECK-LABEL bb.0: |
| # CHECK: liveins: $x0, $x1, $q0, $q1, $q2, $q3, $q4, $q5, $q6, $q7 |
| |
| # CHECK: renamable $q9 = LDRQui $x0, 0 :: (load 16) |
| # CHECK-NEXT: STRQui killed renamable $q9, renamable $x0, 10 :: (store 16, align 4) |
| # CHECK: renamable $q9 = LDRQui $x0, 1 :: (load 16) |
| # CHECK-NEXT: STRQui renamable $q9, renamable $x0, 11 :: (store 16, align 4) |
| # CHECK-NEXT: RET undef $lr |
| |
| name: test9 |
| alignment: 4 |
| tracksRegLiveness: true |
| liveins: |
| - { reg: '$x0' } |
| - { reg: '$x1' } |
| - { reg: '$x8' } |
| - { reg: '$q3' } |
| frameInfo: |
| maxAlignment: 1 |
| maxCallFrameSize: 0 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $q0, $q1, $q2, $q3, $q4, $q5, $q6, $q7 |
| renamable $q9 = LDRQui $x0, 0 :: (load 16) |
| STRQui renamable killed $q9, renamable $x0, 10 :: (store 16, align 4) |
| renamable $q9 = LDRQui $x0, 1 :: (load 16) |
| STRQui renamable $q9, renamable $x0, 11 :: (store 16, align 4) |
| RET undef $lr |
| |
| ... |
| --- |
| # The livein $q7 is killed early, so we can re-use it for renaming. |
| # CHECK-LABEL: name: test10 |
| # CHECK-LABEL bb.0: |
| # CHECK: liveins: $x0, $x1, $q0, $q1, $q2, $q3, $q4, $q5, $q6, $q7 |
| |
| # CHECK: renamable $q7 = FADDv2f64 renamable $q7, renamable $q7 |
| # CHECK-NEXT: STRQui killed renamable $q7, renamable $x0, 100 :: (store 16, align 4) |
| # CHECK-NEXT: $q7 = LDRQui $x0, 0 :: (load 16) |
| # CHECK-NEXT: renamable $q9 = LDRQui $x0, 1 :: (load 16) |
| # CHECK-NEXT: STPQi killed renamable $q9, killed $q7, renamable $x0, 10 :: (store 16, align 4) |
| # CHECK-NEXT: RET undef $lr |
| |
| name: test10 |
| alignment: 4 |
| tracksRegLiveness: true |
| liveins: |
| - { reg: '$x0' } |
| - { reg: '$x1' } |
| - { reg: '$x8' } |
| - { reg: '$q3' } |
| frameInfo: |
| maxAlignment: 1 |
| maxCallFrameSize: 0 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $q0, $q1, $q2, $q3, $q4, $q5, $q6, $q7 |
| renamable $q7 = FADDv2f64 renamable $q7, renamable $q7 |
| STRQui renamable killed $q7, renamable $x0, 100 :: (store 16, align 4) |
| renamable $q9 = LDRQui $x0, 0 :: (load 16) |
| STRQui renamable killed $q9, renamable $x0, 11 :: (store 16, align 4) |
| renamable $q9 = LDRQui $x0, 1 :: (load 16) |
| STRQui renamable killed $q9, renamable $x0, 10 :: (store 16, align 4) |
| RET undef $lr |
| |
| ... |
| --- |
| # Make sure we do not use any registers that are defined between paired candidates |
| # ($x14 in this example) |
| # CHECK-LABEL: name: test11 |
| # CHECK: bb.0: |
| # CHECK-NEXT: liveins: $x0, $x1, $x11, $x12, $x13 |
| |
| # CHECK: renamable $w10 = LDRWui renamable $x0, 0 :: (load 8) |
| # CHECK-NEXT: $x15, renamable $x8 = LDPXi renamable $x0, 1 :: (load 8) |
| # CHECK-NEXT: renamable $x9 = LDRXui renamable $x0, 3 :: (load 8) |
| # CHECK-NEXT: renamable $x14 = LDRXui renamable $x0, 5 :: (load 8) |
| # CHECK-NEXT: STPXi renamable $x9, killed $x15, renamable $x0, 10 :: (store 8, align 4) |
| # CHECK-NEXT: STRXui killed renamable $x14, renamable $x0, 200 :: (store 8, align 4) |
| # CHECK-NEXT: renamable $w8 = ADDWrr $w10, $w10 |
| # CHECK-NEXT: STRWui renamable $w8, renamable $x0, 100 :: (store 8, align 4) |
| # CHECK-NEXT: RET undef $lr |
| # |
| name: test11 |
| alignment: 4 |
| tracksRegLiveness: true |
| liveins: |
| - { reg: '$x0' } |
| - { reg: '$x1' } |
| - { reg: '$x8' } |
| frameInfo: |
| maxAlignment: 1 |
| maxCallFrameSize: 0 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $x11, $x12, $x13 |
| renamable $w10 = LDRWui renamable $x0, 0 :: (load 8) |
| renamable $x9, renamable $x8 = LDPXi renamable $x0, 1 :: (load 8) |
| STRXui renamable killed $x9, renamable $x0, 11 :: (store 8, align 4) |
| renamable $x9 = LDRXui renamable $x0, 3 :: (load 8) |
| renamable $x14 = LDRXui renamable $x0, 5 :: (load 8) |
| STRXui renamable $x9, renamable $x0, 10 :: (store 8, align 4) |
| STRXui renamable killed $x14, renamable $x0, 200 :: (store 8, align 4) |
| renamable $w8 = ADDWrr $w10, $w10 |
| STRWui renamable $w8, renamable $x0, 100 :: (store 8, align 4) |
| RET undef $lr |
| |
| ... |
| --- |
| # Check that we correctly deal with killed registers in stores that get merged forward, |
| # which extends the live range of the first store operand. |
| # CHECK-LABEL: name: test12 |
| # CHECK: bb.0: |
| # CHECK-NEXT: liveins: $x0, $x1 |
| # |
| # CHECK: renamable $x10 = LDRXui renamable $x0, 0 :: (load 8) |
| # CHECK-NEXT: $x11, renamable $x8 = LDPXi renamable $x0, 3 :: (load 8) |
| # CHECK-NEXT: renamable $x9 = LDRXui renamable $x0, 2 :: (load 8) |
| # CHECK-NEXT: renamable $x8 = ADDXrr $x8, $x8 |
| # CHECK-NEXT: STPXi renamable $x8, killed $x11, renamable $x0, 10 :: (store 8, align 4) |
| # CHECK-NEXT: STPXi killed renamable $x10, renamable $x9, renamable $x0, 20 :: (store 8, align 4) |
| # CHECK-NEXT: RET undef $lr |
| |
| name: test12 |
| alignment: 4 |
| tracksRegLiveness: true |
| liveins: |
| - { reg: '$x0' } |
| - { reg: '$x1' } |
| - { reg: '$x8' } |
| frameInfo: |
| maxAlignment: 1 |
| maxCallFrameSize: 0 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1 |
| renamable $x10 = LDRXui renamable $x0, 0 :: (load 8) |
| STRXui renamable killed $x10, renamable $x0, 20 :: (store 8, align 4) |
| renamable $x9, renamable $x8 = LDPXi renamable $x0, 3 :: (load 8) |
| STRXui renamable killed $x9, renamable $x0, 11 :: (store 8, align 4) |
| renamable $x9 = LDRXui renamable $x0, 2 :: (load 8) |
| renamable $x8 = ADDXrr $x8, $x8 |
| STRXui renamable $x8, renamable $x0, 10 :: (store 8, align 4) |
| STRXui renamable $x9, renamable $x0, 21 :: (store 8, align 4) |
| RET undef $lr |
| |
| ... |
| --- |
| # Make sure we do not use any registers that are defined between def to rename and the first |
| # paired store. ($x14 in this example) |
| # CHECK-LABEL: name: test13 |
| # CHECK: bb.0: |
| # CHECK-NEXT: liveins: $x0, $x1, $x10, $x11, $x12, $x13 |
| # CHECK: $x15, renamable $x8 = LDPXi renamable $x0, 0 :: (load 8) |
| # CHECK-NEXT: renamable $x14 = LDRXui renamable $x0, 4 :: (load 8) |
| # CHECK-NEXT: STRXui killed renamable $x14, renamable $x0, 100 :: (store 8, align 4) |
| # CHECK-NEXT: renamable $x9 = LDRXui renamable $x0, 2 :: (load 8) |
| # CHECK-NEXT: STPXi renamable $x9, killed $x15, renamable $x0, 10 :: (store 8, align 4) |
| # CHECK-NEXT: RET undef $lr |
| # |
| name: test13 |
| alignment: 4 |
| tracksRegLiveness: true |
| liveins: |
| - { reg: '$x0' } |
| - { reg: '$x1' } |
| - { reg: '$x8' } |
| frameInfo: |
| maxAlignment: 1 |
| maxCallFrameSize: 0 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $x10, $x11, $x12, $x13 |
| renamable $x9, renamable $x8 = LDPXi renamable $x0, 0 :: (load 8) |
| renamable $x14 = LDRXui renamable $x0, 4 :: (load 8) |
| STRXui renamable killed $x14, renamable $x0, 100 :: (store 8, align 4) |
| STRXui renamable killed $x9, renamable $x0, 11 :: (store 8, align 4) |
| renamable $x9 = LDRXui renamable $x0, 2 :: (load 8) |
| STRXui renamable $x9, renamable $x0, 10 :: (store 8) |
| RET undef $lr |
| |
| ... |
| # Make sure we do not rename if pseudo-defs. Noop pseudo instructions like KILL |
| # may lead to a missing definition of the rename register. |
| # |
| # CHECK-LABEL: name: test14_pseudo |
| # CHECK: bb.0: |
| # CHECK-NEXT: liveins: $w8, $fp, $w25 |
| # CHECK: renamable $w8 = KILL killed renamable $w8, implicit-def $x8 |
| # CHECK-NEXT: STURXi killed renamable $x8, $fp, -40 :: (store 8) |
| # CHECK-NEXT: $w8 = ORRWrs $wzr, killed $w25, 0, implicit-def $x8 |
| # CHECK-NEXT: STURXi killed renamable $x8, $fp, -32 :: (store 8) |
| # CHECK-NEXT: RET undef $lr |
| # |
| name: test14_pseudo |
| alignment: 4 |
| tracksRegLiveness: true |
| liveins: |
| - { reg: '$x0' } |
| - { reg: '$x1' } |
| - { reg: '$x8' } |
| frameInfo: |
| maxAlignment: 1 |
| maxCallFrameSize: 0 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $w8, $fp, $w25 |
| |
| renamable $w8 = KILL killed renamable $w8, implicit-def $x8 |
| STURXi killed renamable $x8, $fp, -40 :: (store 8) |
| $w8 = ORRWrs $wzr, killed $w25, 0, implicit-def $x8 |
| STURXi killed renamable $x8, $fp, -32 :: (store 8) |
| RET undef $lr |
| ... |