1# RUN: llc -x mir < %s -run-pass=greedy,virtregrewriter,stack-slot-coloring | FileCheck %s 2--- | 3 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 4 target triple = "x86_64-unknown-linux-gnu" 5 6 define dso_local i32 @main() local_unnamed_addr { 7 entry: 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 13 ret i32 0 14 } 15 16... 17--- 18name: main 19alignment: 16 20exposesReturnsTwice: false 21legalized: false 22regBankSelected: false 23selected: false 24failedISel: false 25tracksRegLiveness: true 26registers: 27liveins: 28frameInfo: 29 isFrameAddressTaken: false 30 isReturnAddressTaken: false 31 hasStackMap: false 32 hasPatchPoint: false 33 stackSize: 0 34 offsetAdjustment: 0 35 maxAlignment: 16 36 adjustsStack: false 37 hasCalls: true 38 stackProtector: '' 39 maxCallFrameSize: 4294967295 40 hasOpaqueSPAdjustment: false 41 hasVAStart: false 42 hasMustTailInVarArgFunc: false 43 localFrameSize: 0 44 savePoint: '' 45 restorePoint: '' 46fixedStack: 47stack: 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: default, 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: '' } 58constants: 59body: | 60 bb.0.entry: 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. 70 71 ; Make first 15 $xmm registers live 72 $xmm0 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 16 from %ir.india) 73 $xmm1 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 16 from %ir.india) 74 $xmm2 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 16 from %ir.india) 75 $xmm3 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 16 from %ir.india) 76 $xmm4 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 16 from %ir.india) 77 $xmm5 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 16 from %ir.india) 78 $xmm6 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 16 from %ir.india) 79 $xmm7 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 16 from %ir.india) 80 $xmm8 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 16 from %ir.india) 81 $xmm9 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 16 from %ir.india) 82 $xmm10 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 16 from %ir.india) 83 $xmm11 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 16 from %ir.india) 84 $xmm12 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 16 from %ir.india) 85 $xmm13 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 16 from %ir.india) 86 $xmm14 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 16 from %ir.india) 87 88 ; First vreg load 89 %1:vr128 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 16 from %ir.india) 90 91 ; First faulty sequence; %1 spilt 92 %12:fr64 = MOVSDrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 8 from %ir.india) 93 %13:vr128 = COPY killed %12 94 MOVAPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %13 :: (volatile store 16 into %ir.india) 95 ; CHECK: renamable $xmm{{[0-9]+}} = MOVSDrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 8 from %ir.india) 96 ; CHECK-NEXT: MOVAPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed renamable $xmm{{[0-9]+}} :: (volatile store 16 into %ir.india) 97 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 16 into %ir.india) 100 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 16 from %ir.india) 104 105 %22:fr64 = MOVSDrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 8 from %ir.india) 106 %23:vr128 = COPY killed %22 107 MOVAPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %23 :: (volatile store 16 into %ir.india) 108 109 ; CHECK: renamable $xmm{{[0-9]+}} = MOVSDrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 8 from %ir.india) 110 ; CHECK-NEXT: MOVAPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed renamable $xmm{{[0-9]+}} :: (volatile store 16 into %ir.india) 111 112 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %2 :: (volatile dereferenceable store 16 into %ir.india) 113 114 115 ; Test some sequences that _should_ be eliminated 116 %3:vr128 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 16 from %ir.india) 117 118 %32:fr64 = VMOVSDrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (dereferenceable load 8 from %ir.india) 119 %33:fr64 = COPY killed %32 120 VMOVSDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %33 :: (store 8 into %ir.india) 121 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 16 into %stack.3) 125 ; CHECK-NEXT:renamable $xmm{{[0-9]+}} = MOVAPSrm %stack.3, 1, $noreg, 0, $noreg :: (load 16 from %stack.3) 126 127 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %3 :: (volatile dereferenceable store 16 into %ir.india) 128 129 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 16 from %ir.india) 132 133 %42:fr32 = MOVSSrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (dereferenceable load 4 from %ir.india) 134 %43:fr32 = COPY killed %42 135 VMOVSSZmr %stack.2.india, 1, $noreg, 0, $noreg, killed %43 :: (store 4 into %ir.india) 136 137 ; CHECK: MOVAPSmr %stack.3, 1, $noreg, 0, $noreg, killed renamable $xmm{{[0-9]+}} :: (store 16 into %stack.3) 138 ; CHECK-NEXT:renamable $xmm{{[0-9]+}} = MOVAPSrm %stack.3, 1, $noreg, 0, $noreg :: (load 16 from %stack.3) 139 140 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %4 :: (volatile dereferenceable store 16 into %ir.india) 141 142 143 ; Same deal with double-size 144 %5:vr128 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 16 from %ir.india) 145 146 %52:fr64 = MOVSDrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (dereferenceable load 8 from %ir.india) 147 %53:fr64 = COPY killed %52 148 VMOVSDZmr %stack.2.india, 1, $noreg, 0, $noreg, killed %53 :: (store 8 into %ir.india) 149 150 ; CHECK: MOVAPSmr %stack.3, 1, $noreg, 0, $noreg, killed renamable $xmm{{[0-9]+}} :: (store 16 into %stack.3) 151 ; CHECK-NEXT:renamable $xmm{{[0-9]+}} = MOVAPSrm %stack.3, 1, $noreg, 0, $noreg :: (load 16 from %stack.3) 152 153 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %5 :: (volatile dereferenceable store 16 into %ir.india) 154 155 156 ; Last two repeated, with load/store opcode flipped 157 %6:vr128 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 16 from %ir.india) 158 159 %62:fr32 = VMOVSSZrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (dereferenceable load 4 from %ir.india) 160 %63:fr32 = COPY killed %62 161 MOVSSmr %stack.2.india, 1, $noreg, 0, $noreg, killed %63 :: (store 4 into %ir.india) 162 163 ; CHECK: MOVAPSmr %stack.3, 1, $noreg, 0, $noreg, killed renamable $xmm{{[0-9]+}} :: (store 16 into %stack.3) 164 ; CHECK-NEXT:renamable $xmm{{[0-9]+}} = MOVAPSrm %stack.3, 1, $noreg, 0, $noreg :: (load 16 from %stack.3) 165 166 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %6 :: (volatile dereferenceable store 16 into %ir.india) 167 168 169 ; Flipped double-size different-encoding test 170 %7:vr128 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load 16 from %ir.india) 171 172 %72:fr64 = VMOVSDZrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (dereferenceable load 8 from %ir.india) 173 %73:fr64 = COPY killed %72 174 MOVSDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %73 :: (store 8 into %ir.india) 175 176 ; CHECK: MOVAPSmr %stack.3, 1, $noreg, 0, $noreg, killed renamable $xmm{{[0-9]+}} :: (store 16 into %stack.3) 177 ; CHECK-NEXT:renamable $xmm{{[0-9]+}} = MOVAPSrm %stack.3, 1, $noreg, 0, $noreg :: (load 16 from %stack.3) 178 179 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %7 :: (volatile dereferenceable store 16 into %ir.india) 180 181 182 ; Stores of first 15 $xmm registers to keep them live across the middle of 183 ; this bb. 184 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm0 :: (volatile dereferenceable store 16 into %ir.india) 185 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm1 :: (volatile dereferenceable store 16 into %ir.india) 186 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm2 :: (volatile dereferenceable store 16 into %ir.india) 187 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm3 :: (volatile dereferenceable store 16 into %ir.india) 188 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm4 :: (volatile dereferenceable store 16 into %ir.india) 189 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm5 :: (volatile dereferenceable store 16 into %ir.india) 190 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm6 :: (volatile dereferenceable store 16 into %ir.india) 191 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm7 :: (volatile dereferenceable store 16 into %ir.india) 192 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm8 :: (volatile dereferenceable store 16 into %ir.india) 193 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm9 :: (volatile dereferenceable store 16 into %ir.india) 194 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm10 :: (volatile dereferenceable store 16 into %ir.india) 195 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm11 :: (volatile dereferenceable store 16 into %ir.india) 196 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm12 :: (volatile dereferenceable store 16 into %ir.india) 197 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm13 :: (volatile dereferenceable store 16 into %ir.india) 198 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm14 :: (volatile dereferenceable store 16 into %ir.india) 199 200 RET 0 201 202... 203