1 # RUN: llc -x mir < %s -run-pass=greedy,virtregrewriter,stack-slot-coloring | FileCheck %s
3 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4 target triple = "x86_64-unknown-linux-gnu"
6 define dso_local i32 @main() local_unnamed_addr {
8 ; Dummy IR that just performs some allocas -- the machine IR function
9 ; below is what this test is about.
10 %alpha = alloca i8, align 1
11 %foxtrot = alloca <2 x double>, align 16
12 %india = alloca <2 x double>, align 16
20 exposesReturnsTwice: false
22 regBankSelected: false
25 tracksRegLiveness: true
29 isFrameAddressTaken: false
30 isReturnAddressTaken: false
39 maxCallFrameSize: 4294967295
40 hasOpaqueSPAdjustment: false
42 hasMustTailInVarArgFunc: false
48 - { id: 0, name: alpha, type: default, offset: 0, size: 1, alignment: 1,
49 stack-id: default, callee-saved-register: '', callee-saved-restored: true,
50 debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
51 - { id: 1, name: foxtrot, type: default, offset: 0, size: 16, alignment: 16,
52 stack-id: default, callee-saved-register: '', callee-saved-restored: true,
53 debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
54 - { id: 2, name: india, type: spill-slot, offset: 0, size: 16, alignment: 16,
55 stack-id: default, callee-saved-register: '', callee-saved-restored: true,
56 debug-info-variable: '', debug-info-expression: '',
57 debug-info-location: '' }
61 ; To trick stack-slot-colouring to run its dead-store-elimination phase,
62 ; which is at fault, we need the register allocator to run, and spill in two
63 ; places that can have their slots merged. Achieve this by volatile-loading
64 ; data into $xmm[0-14] and volatile storing them later, leaving regalloc only
65 ; $xmm15 to play with in the middle.
66 ; Then, perform two virtreg load-and-store pairs, with the faulty code
67 ; sequence in the middle (MOVSDrm then MOVAPDmr on the same slot). The
68 ; virtreg gets spilt; the corresponding stack slots merged; and faulty code
69 ; sequence eliminated if LLVM is broken.
71 ; Make first 15 $xmm registers live
72 $xmm0 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
73 $xmm1 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
74 $xmm2 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
75 $xmm3 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
76 $xmm4 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
77 $xmm5 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
78 $xmm6 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
79 $xmm7 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
80 $xmm8 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
81 $xmm9 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
82 $xmm10 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
83 $xmm11 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
84 $xmm12 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
85 $xmm13 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
86 $xmm14 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
89 %1:vr128 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
91 ; First faulty sequence; %1 spilt
92 %12:fr64 = MOVSDrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s64) from %ir.india)
93 %13:vr128 = COPY killed %12
94 MOVAPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %13 :: (volatile store (s128) into %ir.india)
95 ; CHECK: renamable $xmm{{[0-9]+}} = MOVSDrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s64) from %ir.india)
96 ; CHECK-NEXT: MOVAPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed renamable $xmm{{[0-9]+}} :: (volatile store (s128) into %ir.india)
98 ; Store %1 to avoid it being optimised out, will result in a load-from-spill
99 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %1 :: (volatile dereferenceable store (s128) into %ir.india)
101 ; That code sequence a second time, to generate a second spill slot that
102 ; will get coloured and merged.
103 %2:vr128 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
105 %22:fr64 = MOVSDrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s64) from %ir.india)
106 %23:vr128 = COPY killed %22
107 MOVAPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %23 :: (volatile store (s128) into %ir.india)
109 ; CHECK: renamable $xmm{{[0-9]+}} = MOVSDrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s64) from %ir.india)
110 ; CHECK-NEXT: MOVAPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed renamable $xmm{{[0-9]+}} :: (volatile store (s128) into %ir.india)
112 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %2 :: (volatile dereferenceable store (s128) into %ir.india)
115 ; Test some sequences that _should_ be eliminated
116 %3:vr128 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
118 %32:fr64 = VMOVSDrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (dereferenceable load (s64) from %ir.india)
119 %33:fr64 = COPY killed %32
120 VMOVSDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %33 :: (store (s64) into %ir.india)
122 ; This is the spill introduced by regalloc; we check that the inner dead
123 ; store and load were eliminated
124 ; CHECK: MOVAPSmr %stack.3, 1, $noreg, 0, $noreg, killed renamable $xmm{{[0-9]+}} :: (store (s128) into %stack.3)
125 ; CHECK-NEXT:renamable $xmm{{[0-9]+}} = MOVAPSrm %stack.3, 1, $noreg, 0, $noreg :: (load (s128) from %stack.3)
127 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %3 :: (volatile dereferenceable store (s128) into %ir.india)
130 ; Moves with different encodings but same size should be eliminated
131 %4:vr128 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
133 %42:fr32 = MOVSSrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (dereferenceable load (s32) from %ir.india)
134 %43:fr32 = COPY killed %42
135 VMOVSSZmr %stack.2.india, 1, $noreg, 0, $noreg, killed %43 :: (store (s32) into %ir.india)
137 ; CHECK: MOVAPSmr %stack.3, 1, $noreg, 0, $noreg, killed renamable $xmm{{[0-9]+}} :: (store (s128) into %stack.3)
138 ; CHECK-NEXT:renamable $xmm{{[0-9]+}} = MOVAPSrm %stack.3, 1, $noreg, 0, $noreg :: (load (s128) from %stack.3)
140 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %4 :: (volatile dereferenceable store (s128) into %ir.india)
143 ; Same deal with double-size
144 %5:vr128 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
146 %52:fr64 = MOVSDrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (dereferenceable load (s64) from %ir.india)
147 %53:fr64 = COPY killed %52
148 VMOVSDZmr %stack.2.india, 1, $noreg, 0, $noreg, killed %53 :: (store (s64) into %ir.india)
150 ; CHECK: MOVAPSmr %stack.3, 1, $noreg, 0, $noreg, killed renamable $xmm{{[0-9]+}} :: (store (s128) into %stack.3)
151 ; CHECK-NEXT:renamable $xmm{{[0-9]+}} = MOVAPSrm %stack.3, 1, $noreg, 0, $noreg :: (load (s128) from %stack.3)
153 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %5 :: (volatile dereferenceable store (s128) into %ir.india)
156 ; Last two repeated, with load/store opcode flipped
157 %6:vr128 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
159 %62:fr32 = VMOVSSZrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (dereferenceable load (s32) from %ir.india)
160 %63:fr32 = COPY killed %62
161 MOVSSmr %stack.2.india, 1, $noreg, 0, $noreg, killed %63 :: (store (s32) into %ir.india)
163 ; CHECK: MOVAPSmr %stack.3, 1, $noreg, 0, $noreg, killed renamable $xmm{{[0-9]+}} :: (store (s128) into %stack.3)
164 ; CHECK-NEXT:renamable $xmm{{[0-9]+}} = MOVAPSrm %stack.3, 1, $noreg, 0, $noreg :: (load (s128) from %stack.3)
166 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %6 :: (volatile dereferenceable store (s128) into %ir.india)
169 ; Flipped double-size different-encoding test
170 %7:vr128 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)
172 %72:fr64 = VMOVSDZrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (dereferenceable load (s64) from %ir.india)
173 %73:fr64 = COPY killed %72
174 MOVSDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %73 :: (store (s64) into %ir.india)
176 ; CHECK: MOVAPSmr %stack.3, 1, $noreg, 0, $noreg, killed renamable $xmm{{[0-9]+}} :: (store (s128) into %stack.3)
177 ; CHECK-NEXT:renamable $xmm{{[0-9]+}} = MOVAPSrm %stack.3, 1, $noreg, 0, $noreg :: (load (s128) from %stack.3)
179 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %7 :: (volatile dereferenceable store (s128) into %ir.india)
182 ; Stores of first 15 $xmm registers to keep them live across the middle of
184 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm0 :: (volatile dereferenceable store (s128) into %ir.india)
185 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm1 :: (volatile dereferenceable store (s128) into %ir.india)
186 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm2 :: (volatile dereferenceable store (s128) into %ir.india)
187 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm3 :: (volatile dereferenceable store (s128) into %ir.india)
188 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm4 :: (volatile dereferenceable store (s128) into %ir.india)
189 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm5 :: (volatile dereferenceable store (s128) into %ir.india)
190 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm6 :: (volatile dereferenceable store (s128) into %ir.india)
191 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm7 :: (volatile dereferenceable store (s128) into %ir.india)
192 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm8 :: (volatile dereferenceable store (s128) into %ir.india)
193 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm9 :: (volatile dereferenceable store (s128) into %ir.india)
194 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm10 :: (volatile dereferenceable store (s128) into %ir.india)
195 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm11 :: (volatile dereferenceable store (s128) into %ir.india)
196 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm12 :: (volatile dereferenceable store (s128) into %ir.india)
197 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm13 :: (volatile dereferenceable store (s128) into %ir.india)
198 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm14 :: (volatile dereferenceable store (s128) into %ir.india)