1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass greedy -verify-machineinstrs -o - %s | FileCheck %s
# RUN: llc -mtriple=aarch64_be-none-linux-gnu -run-pass greedy -verify-machineinstrs -o - %s | FileCheck %s
--- |
define i64 @test_subreg_spill_fold() { ret i64 0 }
define i64 @test_subreg_spill_fold2() { ret i64 0 }
define i64 @test_subreg_spill_fold3() { ret i64 0 }
define <4 x float> @test_subreg_spill_fold4() { ret <4 x float> undef }
define i64 @test_subreg_fill_fold() { ret i64 0 }
define double @test_subreg_fill_fold2() { ret double 0.0 }
define <4 x float> @test_subreg_fill_fold3() { ret <4 x float> undef }
define i64 @test_nzcv_spill_fold() { ret i64 0 }
...
---
# CHECK-LABEL: name: test_subreg_spill_fold
# Ensure that the spilled subreg COPY is eliminated and folded into the spill store.
name: test_subreg_spill_fold
registers:
- { id: 0, class: gpr64 }
body: |
bb.0:
; CHECK: STRXui $xzr, %stack.0, 0 :: (store (s64) into %stack.0)
undef %0.sub_32 = COPY $wzr
INLINEASM &nop, 1, 12, implicit-def dead $x0, 12, implicit-def dead $x1, 12, implicit-def dead $x2, 12, implicit-def dead $x3, 12, implicit-def dead $x4, 12, implicit-def dead $x5, 12, implicit-def dead $x6, 12, implicit-def dead $x7, 12, implicit-def dead $x8, 12, implicit-def dead $x9, 12, implicit-def dead $x10, 12, implicit-def dead $x11, 12, implicit-def dead $x12, 12, implicit-def dead $x13, 12, implicit-def dead $x14, 12, implicit-def dead $x15, 12, implicit-def dead $x16, 12, implicit-def dead $x17, 12, implicit-def dead $x18, 12, implicit-def dead $x19, 12, implicit-def dead $x20, 12, implicit-def dead $x21, 12, implicit-def dead $x22, 12, implicit-def dead $x23, 12, implicit-def dead $x24, 12, implicit-def dead $x25, 12, implicit-def dead $x26, 12, implicit-def dead $x27, 12, implicit-def dead $x28, 12, implicit-def dead $fp, 12, implicit-def dead $lr, 12, implicit-def $sp
$x0 = COPY %0
RET_ReallyLR implicit $x0
...
---
# CHECK-LABEL: name: test_subreg_spill_fold2
# Similar to test_subreg_spill_fold, but with a %0 register class not containing %WZR.
name: test_subreg_spill_fold2
registers:
- { id: 0, class: gpr64sp }
body: |
bb.0:
; CHECK: STRXui $xzr, %stack.0, 0 :: (store (s64) into %stack.0)
undef %0.sub_32 = COPY $wzr
INLINEASM &nop, 1, 12, implicit-def dead $x0, 12, implicit-def dead $x1, 12, implicit-def dead $x2, 12, implicit-def dead $x3, 12, implicit-def dead $x4, 12, implicit-def dead $x5, 12, implicit-def dead $x6, 12, implicit-def dead $x7, 12, implicit-def dead $x8, 12, implicit-def dead $x9, 12, implicit-def dead $x10, 12, implicit-def dead $x11, 12, implicit-def dead $x12, 12, implicit-def dead $x13, 12, implicit-def dead $x14, 12, implicit-def dead $x15, 12, implicit-def dead $x16, 12, implicit-def dead $x17, 12, implicit-def dead $x18, 12, implicit-def dead $x19, 12, implicit-def dead $x20, 12, implicit-def dead $x21, 12, implicit-def dead $x22, 12, implicit-def dead $x23, 12, implicit-def dead $x24, 12, implicit-def dead $x25, 12, implicit-def dead $x26, 12, implicit-def dead $x27, 12, implicit-def dead $x28, 12, implicit-def dead $fp, 12, implicit-def dead $lr, 12, implicit-def $sp
$x0 = ADDXri %0, 1, 0
RET_ReallyLR implicit $x0
...
---
# CHECK-LABEL: name: test_subreg_spill_fold3
# Similar to test_subreg_spill_fold, but with a cross register class copy.
name: test_subreg_spill_fold3
registers:
- { id: 0, class: fpr64 }
body: |
bb.0:
; CHECK: STRXui $xzr, %stack.0, 0 :: (store (s64) into %stack.0)
undef %0.ssub = COPY $wzr
INLINEASM &nop, 1, 12, implicit-def dead $d0, 12, implicit-def dead $d1, 12, implicit-def dead $d2, 12, implicit-def dead $d3, 12, implicit-def dead $d4, 12, implicit-def dead $d5, 12, implicit-def dead $d6, 12, implicit-def dead $d7, 12, implicit-def dead $d8, 12, implicit-def dead $d9, 12, implicit-def dead $d10, 12, implicit-def dead $d11, 12, implicit-def dead $d12, 12, implicit-def dead $d13, 12, implicit-def dead $d14, 12, implicit-def dead $d15, 12, implicit-def dead $d16, 12, implicit-def dead $d17, 12, implicit-def dead $d18, 12, implicit-def dead $d19, 12, implicit-def dead $d20, 12, implicit-def dead $d21, 12, implicit-def dead $d22, 12, implicit-def dead $d23, 12, implicit-def dead $d24, 12, implicit-def dead $d25, 12, implicit-def dead $d26, 12, implicit-def dead $d27, 12, implicit-def dead $d28, 12, implicit-def dead $d29, 12, implicit-def dead $d30, 12, implicit-def $d31
$x0 = COPY %0
RET_ReallyLR implicit $x0
...
---
# CHECK-LABEL: name: test_subreg_spill_fold4
# A spilled write to a 128-bit register needs a 128-bit store
name: test_subreg_spill_fold4
registers:
- { id: 0, class: fpr128 }
body: |
bb.0:
; CHECK: undef %1.ssub:fpr128 = COPY $wzr
; CHECK-NEXT: STRQui %1, %stack.0, 0 :: (store (s128) into %stack.0)
undef %0.ssub:fpr128 = COPY $wzr
INLINEASM &nop, 1, 12, implicit-def dead $d0, 12, implicit-def dead $d1, 12, implicit-def dead $d2, 12, implicit-def dead $d3, 12, implicit-def dead $d4, 12, implicit-def dead $d5, 12, implicit-def dead $d6, 12, implicit-def dead $d7, 12, implicit-def dead $d8, 12, implicit-def dead $d9, 12, implicit-def dead $d10, 12, implicit-def dead $d11, 12, implicit-def dead $d12, 12, implicit-def dead $d13, 12, implicit-def dead $d14, 12, implicit-def dead $d15, 12, implicit-def dead $d16, 12, implicit-def dead $d17, 12, implicit-def dead $d18, 12, implicit-def dead $d19, 12, implicit-def dead $d20, 12, implicit-def dead $d21, 12, implicit-def dead $d22, 12, implicit-def dead $d23, 12, implicit-def dead $d24, 12, implicit-def dead $d25, 12, implicit-def dead $d26, 12, implicit-def dead $d27, 12, implicit-def dead $d28, 12, implicit-def dead $d29, 12, implicit-def dead $d30, 12, implicit-def $d31
$q0 = COPY %0
RET_ReallyLR implicit $q0
...
---
# CHECK-LABEL: name: test_subreg_fill_fold
# Ensure that the filled COPY is eliminated and folded into the fill load.
name: test_subreg_fill_fold
registers:
- { id: 0, class: gpr32 }
- { id: 1, class: gpr64 }
body: |
bb.0:
%0 = COPY $wzr
INLINEASM &nop, 1, 12, implicit-def dead $x0, 12, implicit-def dead $x1, 12, implicit-def dead $x2, 12, implicit-def dead $x3, 12, implicit-def dead $x4, 12, implicit-def dead $x5, 12, implicit-def dead $x6, 12, implicit-def dead $x7, 12, implicit-def dead $x8, 12, implicit-def dead $x9, 12, implicit-def dead $x10, 12, implicit-def dead $x11, 12, implicit-def dead $x12, 12, implicit-def dead $x13, 12, implicit-def dead $x14, 12, implicit-def dead $x15, 12, implicit-def dead $x16, 12, implicit-def dead $x17, 12, implicit-def dead $x18, 12, implicit-def dead $x19, 12, implicit-def dead $x20, 12, implicit-def dead $x21, 12, implicit-def dead $x22, 12, implicit-def dead $x23, 12, implicit-def dead $x24, 12, implicit-def dead $x25, 12, implicit-def dead $x26, 12, implicit-def dead $x27, 12, implicit-def dead $x28, 12, implicit-def dead $fp, 12, implicit-def dead $lr, 12, implicit-def $sp
; CHECK: undef %1.sub_32:gpr64 = LDRWui %stack.0, 0 :: (load (s32) from %stack.0)
undef %1.sub_32 = COPY %0
$x0 = COPY %1
RET_ReallyLR implicit $x0
...
---
# CHECK-LABEL: name: test_subreg_fill_fold2
# Similar to test_subreg_fill_fold, but with a cross-class copy.
name: test_subreg_fill_fold2
registers:
- { id: 0, class: gpr32 }
- { id: 1, class: fpr64 }
body: |
bb.0:
%0 = COPY $wzr
INLINEASM &nop, 1, 12, implicit-def dead $x0, 12, implicit-def dead $x1, 12, implicit-def dead $x2, 12, implicit-def dead $x3, 12, implicit-def dead $x4, 12, implicit-def dead $x5, 12, implicit-def dead $x6, 12, implicit-def dead $x7, 12, implicit-def dead $x8, 12, implicit-def dead $x9, 12, implicit-def dead $x10, 12, implicit-def dead $x11, 12, implicit-def dead $x12, 12, implicit-def dead $x13, 12, implicit-def dead $x14, 12, implicit-def dead $x15, 12, implicit-def dead $x16, 12, implicit-def dead $x17, 12, implicit-def dead $x18, 12, implicit-def dead $x19, 12, implicit-def dead $x20, 12, implicit-def dead $x21, 12, implicit-def dead $x22, 12, implicit-def dead $x23, 12, implicit-def dead $x24, 12, implicit-def dead $x25, 12, implicit-def dead $x26, 12, implicit-def dead $x27, 12, implicit-def dead $x28, 12, implicit-def dead $fp, 12, implicit-def dead $lr, 12, implicit-def $sp
; CHECK: undef %1.ssub:fpr64 = LDRSui %stack.0, 0 :: (load (s32) from %stack.0)
undef %1.ssub = COPY %0
$d0 = COPY %1
RET_ReallyLR implicit $d0
...
---
# CHECK-LABEL: name: test_subreg_fill_fold3
# A filled copy from a sub-register should load the whole register
name: test_subreg_fill_fold3
tracksRegLiveness: true
registers:
- { id: 0, class: fpr128 }
liveins:
- { reg: '$q0' }
body: |
bb.0:
liveins: $q0
%0 = COPY $q0
INLINEASM &nop, 1, 12, implicit-def dead $d0, 12, implicit-def dead $d1, 12, implicit-def dead $d2, 12, implicit-def dead $d3, 12, implicit-def dead $d4, 12, implicit-def dead $d5, 12, implicit-def dead $d6, 12, implicit-def dead $d7, 12, implicit-def dead $d8, 12, implicit-def dead $d9, 12, implicit-def dead $d10, 12, implicit-def dead $d11, 12, implicit-def dead $d12, 12, implicit-def dead $d13, 12, implicit-def dead $d14, 12, implicit-def dead $d15, 12, implicit-def dead $d16, 12, implicit-def dead $d17, 12, implicit-def dead $d18, 12, implicit-def dead $d19, 12, implicit-def dead $d20, 12, implicit-def dead $d21, 12, implicit-def dead $d22, 12, implicit-def dead $d23, 12, implicit-def dead $d24, 12, implicit-def dead $d25, 12, implicit-def dead $d26, 12, implicit-def dead $d27, 12, implicit-def dead $d28, 12, implicit-def dead $d29, 12, implicit-def dead $d30, 12, implicit-def $d31
; CHECK: %1:fpr128 = LDRQui %stack.0, 0 :: (load (s128) from %stack.0)
; CHECK-NEXT: $s0 = COPY %1.ssub
$s0 = COPY %0.ssub
RET_ReallyLR implicit $s0
...
---
# CHECK-LABEL: name: test_nzcv_spill_fold
# Ensure that nzcv COPY cannot be folded.
name: test_nzcv_spill_fold
registers:
- { id: 0, class: gpr64 }
body: |
bb.0:
; CHECK: %1:gpr64 = COPY $nzcv
; CHECK: STRXui %1, %stack.0, 0 :: (store (s64) into %stack.0)
%0 = COPY $nzcv
INLINEASM &nop, 1, 12, implicit-def dead $x0, 12, implicit-def dead $x1, 12, implicit-def dead $x2, 12, implicit-def dead $x3, 12, implicit-def dead $x4, 12, implicit-def dead $x5, 12, implicit-def dead $x6, 12, implicit-def dead $x7, 12, implicit-def dead $x8, 12, implicit-def dead $x9, 12, implicit-def dead $x10, 12, implicit-def dead $x11, 12, implicit-def dead $x12, 12, implicit-def dead $x13, 12, implicit-def dead $x14, 12, implicit-def dead $x15, 12, implicit-def dead $x16, 12, implicit-def dead $x17, 12, implicit-def dead $x18, 12, implicit-def dead $x19, 12, implicit-def dead $x20, 12, implicit-def dead $x21, 12, implicit-def dead $x22, 12, implicit-def dead $x23, 12, implicit-def dead $x24, 12, implicit-def dead $x25, 12, implicit-def dead $x26, 12, implicit-def dead $x27, 12, implicit-def dead $x28, 12, implicit-def dead $fp, 12, implicit-def dead $lr, 12, implicit-def $sp
$x0 = COPY %0
RET_ReallyLR implicit $x0
...
|