204 lines · plain
1# RUN: llc -x mir < %s -run-pass=greedy,virtregrewriter,stack-slot-coloring | FileCheck %s2# RUN: llc -x mir < %s -passes=greedy,virt-reg-rewriter,stack-slot-coloring | FileCheck %s3--- |4 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"5 target triple = "x86_64-unknown-linux-gnu"6 7 define dso_local i32 @main() local_unnamed_addr {8 entry:9 ; Dummy IR that just performs some allocas -- the machine IR function10 ; below is what this test is about.11 %alpha = alloca i8, align 112 %foxtrot = alloca <2 x double>, align 1613 %india = alloca <2 x double>, align 1614 ret i32 015 }16 17...18---19name: main20alignment: 1621exposesReturnsTwice: false22legalized: false23regBankSelected: false24selected: false25failedISel: false26tracksRegLiveness: true27registers:28liveins:29frameInfo:30 isFrameAddressTaken: false31 isReturnAddressTaken: false32 hasStackMap: false33 hasPatchPoint: false34 stackSize: 035 offsetAdjustment: 036 maxAlignment: 1637 adjustsStack: false38 hasCalls: true39 stackProtector: ''40 maxCallFrameSize: 429496729541 hasOpaqueSPAdjustment: false42 hasVAStart: false43 hasMustTailInVarArgFunc: false44 localFrameSize: 045 savePoint: []46 restorePoint: []47fixedStack:48stack:49 - { id: 0, name: alpha, type: default, offset: 0, size: 1, alignment: 1,50 stack-id: default, callee-saved-register: '', callee-saved-restored: true,51 debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }52 - { id: 1, name: foxtrot, type: default, offset: 0, size: 16, alignment: 16,53 stack-id: default, callee-saved-register: '', callee-saved-restored: true,54 debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }55 - { id: 2, name: india, type: spill-slot, offset: 0, size: 16, alignment: 16,56 stack-id: default, callee-saved-register: '', callee-saved-restored: true,57 debug-info-variable: '', debug-info-expression: '',58 debug-info-location: '' }59constants:60body: |61 bb.0.entry:62 ; To trick stack-slot-colouring to run its dead-store-elimination phase,63 ; which is at fault, we need the register allocator to run, and spill in two64 ; places that can have their slots merged. Achieve this by volatile-loading65 ; data into $xmm[0-14] and volatile storing them later, leaving regalloc only66 ; $xmm15 to play with in the middle.67 ; Then, perform two virtreg load-and-store pairs, with the faulty code68 ; sequence in the middle (MOVSDrm then MOVAPDmr on the same slot). The 69 ; virtreg gets spilt; the corresponding stack slots merged; and faulty code70 ; sequence eliminated if LLVM is broken.71 72 ; Make first 15 $xmm registers live73 $xmm0 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)74 $xmm1 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)75 $xmm2 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)76 $xmm3 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)77 $xmm4 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)78 $xmm5 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)79 $xmm6 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)80 $xmm7 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)81 $xmm8 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)82 $xmm9 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)83 $xmm10 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)84 $xmm11 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)85 $xmm12 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)86 $xmm13 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)87 $xmm14 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)88 89 ; First vreg load90 %1:vr128 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)91 92 ; First faulty sequence; %1 spilt93 %12:fr64 = MOVSDrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s64) from %ir.india)94 %13:vr128 = COPY killed %1295 MOVAPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %13 :: (volatile store (s128) into %ir.india)96 ; CHECK: renamable $xmm{{[0-9]+}} = MOVSDrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s64) from %ir.india)97 ; CHECK-NEXT: MOVAPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed renamable $xmm{{[0-9]+}} :: (volatile store (s128) into %ir.india)98 99 ; Store %1 to avoid it being optimised out, will result in a load-from-spill100 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %1 :: (volatile dereferenceable store (s128) into %ir.india)101 102 ; That code sequence a second time, to generate a second spill slot that103 ; will get coloured and merged.104 %2:vr128 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)105 106 %22:fr64 = MOVSDrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s64) from %ir.india)107 %23:vr128 = COPY killed %22108 MOVAPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %23 :: (volatile store (s128) into %ir.india)109 110 ; CHECK: renamable $xmm{{[0-9]+}} = MOVSDrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s64) from %ir.india)111 ; CHECK-NEXT: MOVAPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed renamable $xmm{{[0-9]+}} :: (volatile store (s128) into %ir.india)112 113 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %2 :: (volatile dereferenceable store (s128) into %ir.india)114 115 116 ; Test some sequences that _should_ be eliminated117 %3:vr128 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)118 119 %32:fr64 = VMOVSDrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (dereferenceable load (s64) from %ir.india)120 %33:fr64 = COPY killed %32121 VMOVSDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %33 :: (store (s64) into %ir.india)122 123 ; This is the spill introduced by regalloc; we check that the inner dead124 ; store and load were eliminated125 ; CHECK: MOVAPSmr %stack.3, 1, $noreg, 0, $noreg, killed renamable $xmm{{[0-9]+}} :: (store (s128) into %stack.3)126 ; CHECK-NEXT:renamable $xmm{{[0-9]+}} = MOVAPSrm %stack.3, 1, $noreg, 0, $noreg :: (load (s128) from %stack.3)127 128 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %3 :: (volatile dereferenceable store (s128) into %ir.india)129 130 131 ; Moves with different encodings but same size should be eliminated132 %4:vr128 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)133 134 %42:fr32 = MOVSSrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (dereferenceable load (s32) from %ir.india)135 %43:fr32 = COPY killed %42136 VMOVSSZmr %stack.2.india, 1, $noreg, 0, $noreg, killed %43 :: (store (s32) into %ir.india)137 138 ; CHECK: MOVAPSmr %stack.3, 1, $noreg, 0, $noreg, killed renamable $xmm{{[0-9]+}} :: (store (s128) into %stack.3)139 ; CHECK-NEXT:renamable $xmm{{[0-9]+}} = MOVAPSrm %stack.3, 1, $noreg, 0, $noreg :: (load (s128) from %stack.3)140 141 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %4 :: (volatile dereferenceable store (s128) into %ir.india)142 143 144 ; Same deal with double-size145 %5:vr128 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)146 147 %52:fr64 = MOVSDrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (dereferenceable load (s64) from %ir.india)148 %53:fr64 = COPY killed %52149 VMOVSDZmr %stack.2.india, 1, $noreg, 0, $noreg, killed %53 :: (store (s64) into %ir.india)150 151 ; CHECK: MOVAPSmr %stack.3, 1, $noreg, 0, $noreg, killed renamable $xmm{{[0-9]+}} :: (store (s128) into %stack.3)152 ; CHECK-NEXT:renamable $xmm{{[0-9]+}} = MOVAPSrm %stack.3, 1, $noreg, 0, $noreg :: (load (s128) from %stack.3)153 154 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %5 :: (volatile dereferenceable store (s128) into %ir.india)155 156 157 ; Last two repeated, with load/store opcode flipped158 %6:vr128 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)159 160 %62:fr32 = VMOVSSZrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (dereferenceable load (s32) from %ir.india)161 %63:fr32 = COPY killed %62162 MOVSSmr %stack.2.india, 1, $noreg, 0, $noreg, killed %63 :: (store (s32) into %ir.india)163 164 ; CHECK: MOVAPSmr %stack.3, 1, $noreg, 0, $noreg, killed renamable $xmm{{[0-9]+}} :: (store (s128) into %stack.3)165 ; CHECK-NEXT:renamable $xmm{{[0-9]+}} = MOVAPSrm %stack.3, 1, $noreg, 0, $noreg :: (load (s128) from %stack.3)166 167 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %6 :: (volatile dereferenceable store (s128) into %ir.india)168 169 170 ; Flipped double-size different-encoding test171 %7:vr128 = MOVUPDrm %stack.2.india, 1, $noreg, 0, $noreg :: (volatile dereferenceable load (s128) from %ir.india)172 173 %72:fr64 = VMOVSDZrm_alt %stack.2.india, 1, $noreg, 0, $noreg :: (dereferenceable load (s64) from %ir.india)174 %73:fr64 = COPY killed %72175 MOVSDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %73 :: (store (s64) into %ir.india)176 177 ; CHECK: MOVAPSmr %stack.3, 1, $noreg, 0, $noreg, killed renamable $xmm{{[0-9]+}} :: (store (s128) into %stack.3)178 ; CHECK-NEXT:renamable $xmm{{[0-9]+}} = MOVAPSrm %stack.3, 1, $noreg, 0, $noreg :: (load (s128) from %stack.3)179 180 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed %7 :: (volatile dereferenceable store (s128) into %ir.india)181 182 183 ; Stores of first 15 $xmm registers to keep them live across the middle of184 ; this bb.185 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm0 :: (volatile dereferenceable store (s128) into %ir.india)186 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm1 :: (volatile dereferenceable store (s128) into %ir.india)187 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm2 :: (volatile dereferenceable store (s128) into %ir.india)188 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm3 :: (volatile dereferenceable store (s128) into %ir.india)189 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm4 :: (volatile dereferenceable store (s128) into %ir.india)190 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm5 :: (volatile dereferenceable store (s128) into %ir.india)191 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm6 :: (volatile dereferenceable store (s128) into %ir.india)192 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm7 :: (volatile dereferenceable store (s128) into %ir.india)193 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm8 :: (volatile dereferenceable store (s128) into %ir.india)194 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm9 :: (volatile dereferenceable store (s128) into %ir.india)195 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm10 :: (volatile dereferenceable store (s128) into %ir.india)196 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm11 :: (volatile dereferenceable store (s128) into %ir.india)197 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm12 :: (volatile dereferenceable store (s128) into %ir.india)198 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm13 :: (volatile dereferenceable store (s128) into %ir.india)199 MOVUPDmr %stack.2.india, 1, $noreg, 0, $noreg, killed $xmm14 :: (volatile dereferenceable store (s128) into %ir.india)200 201 RET 0202 203...204