1ccba60a7SCraig Topper# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2ccba60a7SCraig Topper# RUN: llc -run-pass=stack-coloring %s -o - | FileCheck %s
3ccba60a7SCraig Topper
4ccba60a7SCraig Topper## %tmpcast is between 2 allocas. %ref.tmp will replaced by %tmp. Make sure
5ccba60a7SCraig Topper## that we reorder %tmp to be before the use in %tmpcast.
6ccba60a7SCraig Topper
7ccba60a7SCraig Topper# CHECK: %a = alloca %struct.e, align 1
8ccba60a7SCraig Topper# CHECK: %tmp = alloca %"struct.e::f", align 8
9ccba60a7SCraig Topper# CHECK: %0 = bitcast %"struct.e::f"* %tmp to { <2 x float>, <2 x float> }*
10ccba60a7SCraig Topper# CHECK: %ref.tmp = alloca { <2 x float>, <2 x float> }, align 8
11ccba60a7SCraig Topper# CHECK: %tmpcast = bitcast { <2 x float>, <2 x float> }* %0 to %class.d*
12ccba60a7SCraig Topper# CHECK: %b = alloca %struct.j, align 4
13ccba60a7SCraig Topper
14ccba60a7SCraig Topper--- |
15ccba60a7SCraig Topper  source_filename = "<stdin>"
16ccba60a7SCraig Topper  target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
17ccba60a7SCraig Topper  target triple = "x86_64-apple-macosx10.15.0"
18ccba60a7SCraig Topper
19ccba60a7SCraig Topper  %class.d = type { [4 x float] }
20ccba60a7SCraig Topper  %struct.e = type { i8 }
21ccba60a7SCraig Topper  %struct.j = type { i32 }
22ccba60a7SCraig Topper  %"struct.e::f" = type { [4 x i32*] }
23ccba60a7SCraig Topper
24ccba60a7SCraig Topper  @i = local_unnamed_addr global %class.d zeroinitializer, align 8
25ccba60a7SCraig Topper
26ccba60a7SCraig Topper  ; Function Attrs: ssp uwtable
27ccba60a7SCraig Topper  define void @_Z1gv() local_unnamed_addr #0 {
28ccba60a7SCraig Topper  entry:
29ccba60a7SCraig Topper    %a = alloca %struct.e, align 1
30ccba60a7SCraig Topper    %ref.tmp = alloca { <2 x float>, <2 x float> }, align 8
31ccba60a7SCraig Topper    %tmpcast = bitcast { <2 x float>, <2 x float> }* %ref.tmp to %class.d*
32ccba60a7SCraig Topper    %b = alloca %struct.j, align 4
33ccba60a7SCraig Topper    %tmp = alloca %"struct.e::f", align 8
34ccba60a7SCraig Topper    %0 = bitcast %struct.e* %a to i8*
35ccba60a7SCraig Topper    call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull %0) #3
36ccba60a7SCraig Topper    %1 = bitcast { <2 x float>, <2 x float> }* %ref.tmp to i8*
37ccba60a7SCraig Topper    call void @llvm.lifetime.start.p0i8(i64 16, i8* nonnull %1) #3
38ccba60a7SCraig Topper    %agg.tmp.sroa.0.0.copyload = load <2 x float>, <2 x float>* bitcast (%class.d* @i to <2 x float>*), align 8, !tbaa.struct !3
39ccba60a7SCraig Topper    %agg.tmp.sroa.2.0.copyload = load <2 x float>, <2 x float>* bitcast (float* getelementptr inbounds (%class.d, %class.d* @i, i64 0, i32 0, i64 2) to <2 x float>*), align 8, !tbaa.struct !3
40ccba60a7SCraig Topper    %call = tail call { <2 x float>, <2 x float> } @_Zng1d(<2 x float> %agg.tmp.sroa.0.0.copyload, <2 x float> %agg.tmp.sroa.2.0.copyload)
41ccba60a7SCraig Topper    %2 = bitcast { <2 x float>, <2 x float> }* %ref.tmp to <2 x float>*
42ccba60a7SCraig Topper    %3 = extractvalue { <2 x float>, <2 x float> } %call, 0
43ccba60a7SCraig Topper    store <2 x float> %3, <2 x float>* %2, align 8
44ccba60a7SCraig Topper    %4 = getelementptr inbounds { <2 x float>, <2 x float> }, { <2 x float>, <2 x float> }* %ref.tmp, i64 0, i32 1
45ccba60a7SCraig Topper    %5 = extractvalue { <2 x float>, <2 x float> } %call, 1
46ccba60a7SCraig Topper    store <2 x float> %5, <2 x float>* %4, align 8
47ccba60a7SCraig Topper    call void @_ZN1e1hERK1d(%struct.e* nonnull %a, %class.d* nonnull dereferenceable(16) %tmpcast)
48ccba60a7SCraig Topper    call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull %1) #3
49ccba60a7SCraig Topper    %6 = bitcast %struct.j* %b to i8*
50ccba60a7SCraig Topper    call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %6) #3
51ccba60a7SCraig Topper    %7 = bitcast %"struct.e::f"* %tmp to i8*
52ccba60a7SCraig Topper    call void @llvm.lifetime.start.p0i8(i64 32, i8* nonnull %7) #3
5320c43d6bSMatt Arsenault    call void @_ZN1j1kEv(%"struct.e::f"* nonnull sret(%"struct.e::f") align 8 %tmp, %struct.j* nonnull %b)
54ccba60a7SCraig Topper    call void @llvm.lifetime.end.p0i8(i64 32, i8* nonnull %7) #3
55ccba60a7SCraig Topper    call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %6) #3
56ccba60a7SCraig Topper    call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull %0) #3
57ccba60a7SCraig Topper    ret void
58ccba60a7SCraig Topper  }
59ccba60a7SCraig Topper
60ccba60a7SCraig Topper  ; Function Attrs: argmemonly nounwind willreturn
61ccba60a7SCraig Topper  declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1
62ccba60a7SCraig Topper
63ccba60a7SCraig Topper  declare void @_ZN1e1hERK1d(%struct.e*, %class.d* dereferenceable(16)) local_unnamed_addr #2
64ccba60a7SCraig Topper
65ccba60a7SCraig Topper  declare { <2 x float>, <2 x float> } @_Zng1d(<2 x float>, <2 x float>) local_unnamed_addr #2
66ccba60a7SCraig Topper
67ccba60a7SCraig Topper  ; Function Attrs: argmemonly nounwind willreturn
68ccba60a7SCraig Topper  declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1
69ccba60a7SCraig Topper
7020c43d6bSMatt Arsenault  declare void @_ZN1j1kEv(%"struct.e::f"* sret(%"struct.e::f") align 8, %struct.j*) local_unnamed_addr #2
71ccba60a7SCraig Topper
72ccba60a7SCraig Topper  ; Function Attrs: nounwind
73ccba60a7SCraig Topper  declare void @llvm.stackprotector(i8*, i8**) #3
74ccba60a7SCraig Topper
754ab3041aSserge-sans-paille  attributes #0 = { ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="64" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
76ccba60a7SCraig Topper  attributes #1 = { argmemonly nounwind willreturn }
774ab3041aSserge-sans-paille  attributes #2 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
78ccba60a7SCraig Topper  attributes #3 = { nounwind }
79ccba60a7SCraig Topper
80ccba60a7SCraig Topper  !llvm.module.flags = !{!0, !1}
81ccba60a7SCraig Topper  !llvm.ident = !{!2}
82ccba60a7SCraig Topper
83ccba60a7SCraig Topper  !0 = !{i32 1, !"wchar_size", i32 4}
84ccba60a7SCraig Topper  !1 = !{i32 7, !"PIC Level", i32 2}
85ccba60a7SCraig Topper  !2 = !{!"clang version 11.0.0 (https://github.com/llvm/llvm-project.git 82093e8fb7d65486ff450d33bf386aabd0d194f7)"}
86ccba60a7SCraig Topper  !3 = !{i64 0, i64 16, !4}
87ccba60a7SCraig Topper  !4 = !{!5, !5, i64 0}
88ccba60a7SCraig Topper  !5 = !{!"omnipotent char", !6, i64 0}
89ccba60a7SCraig Topper  !6 = !{!"Simple C++ TBAA"}
90ccba60a7SCraig Topper
91ccba60a7SCraig Topper...
92ccba60a7SCraig Topper---
93ccba60a7SCraig Toppername:            _Z1gv
94ccba60a7SCraig Topperalignment:       16
95ccba60a7SCraig TopperexposesReturnsTwice: false
96ccba60a7SCraig Topperlegalized:       false
97ccba60a7SCraig TopperregBankSelected: false
98ccba60a7SCraig Topperselected:        false
99ccba60a7SCraig TopperfailedISel:      false
100ccba60a7SCraig ToppertracksRegLiveness: true
101ccba60a7SCraig TopperhasWinCFI:       false
102ccba60a7SCraig Topperregisters:
103ccba60a7SCraig Topper  - { id: 0, class: vr128, preferred-register: '' }
104ccba60a7SCraig Topper  - { id: 1, class: vr128, preferred-register: '' }
105ccba60a7SCraig Topper  - { id: 2, class: vr128, preferred-register: '' }
106ccba60a7SCraig Topper  - { id: 3, class: vr128, preferred-register: '' }
107ccba60a7SCraig Topper  - { id: 4, class: gr64, preferred-register: '' }
108ccba60a7SCraig Topper  - { id: 5, class: gr64, preferred-register: '' }
109ccba60a7SCraig Topper  - { id: 6, class: gr64, preferred-register: '' }
110ccba60a7SCraig Topper  - { id: 7, class: gr64, preferred-register: '' }
111ccba60a7SCraig Topperliveins:         []
112ccba60a7SCraig TopperframeInfo:
113ccba60a7SCraig Topper  isFrameAddressTaken: false
114ccba60a7SCraig Topper  isReturnAddressTaken: false
115ccba60a7SCraig Topper  hasStackMap:     false
116ccba60a7SCraig Topper  hasPatchPoint:   false
117ccba60a7SCraig Topper  stackSize:       0
118ccba60a7SCraig Topper  offsetAdjustment: 0
119ccba60a7SCraig Topper  maxAlignment:    8
120ccba60a7SCraig Topper  adjustsStack:    false
121ccba60a7SCraig Topper  hasCalls:        true
122ccba60a7SCraig Topper  stackProtector:  ''
123ccba60a7SCraig Topper  maxCallFrameSize: 4294967295
124ccba60a7SCraig Topper  cvBytesOfCalleeSavedRegisters: 0
125ccba60a7SCraig Topper  hasOpaqueSPAdjustment: false
126ccba60a7SCraig Topper  hasVAStart:      false
127ccba60a7SCraig Topper  hasMustTailInVarArgFunc: false
128ccba60a7SCraig Topper  localFrameSize:  0
129ccba60a7SCraig Topper  savePoint:       ''
130ccba60a7SCraig Topper  restorePoint:    ''
131ccba60a7SCraig TopperfixedStack:      []
132ccba60a7SCraig Topperstack:
133ccba60a7SCraig Topper  - { id: 0, name: a, type: default, offset: 0, size: 1, alignment: 8,
134ccba60a7SCraig Topper      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
135ccba60a7SCraig Topper      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
136ccba60a7SCraig Topper  - { id: 1, name: ref.tmp, type: default, offset: 0, size: 16, alignment: 8,
137ccba60a7SCraig Topper      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
138ccba60a7SCraig Topper      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
139ccba60a7SCraig Topper  - { id: 2, name: b, type: default, offset: 0, size: 4, alignment: 8,
140ccba60a7SCraig Topper      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
141ccba60a7SCraig Topper      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
142ccba60a7SCraig Topper  - { id: 3, name: tmp, type: default, offset: 0, size: 32, alignment: 8,
143ccba60a7SCraig Topper      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
144ccba60a7SCraig Topper      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
145ccba60a7SCraig ToppercallSites:       []
146ccba60a7SCraig Topperconstants:       []
147ccba60a7SCraig ToppermachineFunctionInfo: {}
148ccba60a7SCraig Topperbody:             |
149ccba60a7SCraig Topper  bb.0.entry:
150ccba60a7SCraig Topper    ; CHECK-LABEL: name: _Z1gv
151*fae05692SMatt Arsenault    ; CHECK: [[MOVSDrm:%[0-9]+]]:vr128 = MOVSDrm $rip, 1, $noreg, @i, $noreg :: (dereferenceable load (s64) from `<2 x float>* bitcast (%class.d* @i to <2 x float>*)`)
152*fae05692SMatt Arsenault    ; CHECK: [[MOVSDrm1:%[0-9]+]]:vr128 = MOVSDrm $rip, 1, $noreg, @i + 8, $noreg :: (dereferenceable load (s64) from `<2 x float>* bitcast (float* getelementptr inbounds (%class.d, %class.d* @i, i64 0, i32 0, i64 2) to <2 x float>*)`)
153ccba60a7SCraig Topper    ; CHECK: ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
154ccba60a7SCraig Topper    ; CHECK: $xmm0 = COPY [[MOVSDrm]]
155ccba60a7SCraig Topper    ; CHECK: $xmm1 = COPY [[MOVSDrm1]]
156ccba60a7SCraig Topper    ; CHECK: CALL64pcrel32 @_Zng1d, csr_64, implicit $rsp, implicit $ssp, implicit $xmm0, implicit $xmm1, implicit-def $rsp, implicit-def $ssp, implicit-def $xmm0, implicit-def $xmm1
157ccba60a7SCraig Topper    ; CHECK: ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
158ccba60a7SCraig Topper    ; CHECK: [[COPY:%[0-9]+]]:vr128 = COPY $xmm0
159ccba60a7SCraig Topper    ; CHECK: [[COPY1:%[0-9]+]]:vr128 = COPY $xmm1
160*fae05692SMatt Arsenault    ; CHECK: MOVLPDmr %stack.3.tmp, 1, $noreg, 0, $noreg, [[COPY]] :: (store (s64) into %ir.3)
161*fae05692SMatt Arsenault    ; CHECK: MOVLPDmr %stack.3.tmp, 1, $noreg, 8, $noreg, [[COPY1]] :: (store (s64) into %ir.5)
162ccba60a7SCraig Topper    ; CHECK: ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
163ccba60a7SCraig Topper    ; CHECK: [[LEA64r:%[0-9]+]]:gr64 = LEA64r %stack.0.a, 1, $noreg, 0, $noreg
164ccba60a7SCraig Topper    ; CHECK: [[LEA64r1:%[0-9]+]]:gr64 = LEA64r %stack.3.tmp, 1, $noreg, 0, $noreg
165ccba60a7SCraig Topper    ; CHECK: $rdi = COPY [[LEA64r]]
166ccba60a7SCraig Topper    ; CHECK: $rsi = COPY [[LEA64r1]]
167ccba60a7SCraig Topper    ; CHECK: CALL64pcrel32 @_ZN1e1hERK1d, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit $rsi, implicit-def $rsp, implicit-def $ssp
168ccba60a7SCraig Topper    ; CHECK: ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
169ccba60a7SCraig Topper    ; CHECK: ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
170ccba60a7SCraig Topper    ; CHECK: [[LEA64r2:%[0-9]+]]:gr64 = LEA64r %stack.3.tmp, 1, $noreg, 0, $noreg
171ccba60a7SCraig Topper    ; CHECK: [[LEA64r3:%[0-9]+]]:gr64 = LEA64r %stack.2.b, 1, $noreg, 0, $noreg
172ccba60a7SCraig Topper    ; CHECK: $rdi = COPY [[LEA64r2]]
173ccba60a7SCraig Topper    ; CHECK: $rsi = COPY [[LEA64r3]]
174ccba60a7SCraig Topper    ; CHECK: CALL64pcrel32 @_ZN1j1kEv, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit $rsi, implicit-def $rsp, implicit-def $ssp
175ccba60a7SCraig Topper    ; CHECK: ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
176ccba60a7SCraig Topper    ; CHECK: RET 0
177ccba60a7SCraig Topper    LIFETIME_START %stack.0.a
178ccba60a7SCraig Topper    LIFETIME_START %stack.1.ref.tmp
179*fae05692SMatt Arsenault    %0:vr128 = MOVSDrm $rip, 1, $noreg, @i, $noreg :: (dereferenceable load (s64) from `<2 x float>* bitcast (%class.d* @i to <2 x float>*)`)
180*fae05692SMatt Arsenault    %1:vr128 = MOVSDrm $rip, 1, $noreg, @i + 8, $noreg :: (dereferenceable load (s64) from `<2 x float>* bitcast (float* getelementptr inbounds (%class.d, %class.d* @i, i64 0, i32 0, i64 2) to <2 x float>*)`)
181ccba60a7SCraig Topper    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
182ccba60a7SCraig Topper    $xmm0 = COPY %0
183ccba60a7SCraig Topper    $xmm1 = COPY %1
184ccba60a7SCraig Topper    CALL64pcrel32 @_Zng1d, csr_64, implicit $rsp, implicit $ssp, implicit $xmm0, implicit $xmm1, implicit-def $rsp, implicit-def $ssp, implicit-def $xmm0, implicit-def $xmm1
185ccba60a7SCraig Topper    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
186ccba60a7SCraig Topper    %2:vr128 = COPY $xmm0
187ccba60a7SCraig Topper    %3:vr128 = COPY $xmm1
188*fae05692SMatt Arsenault    MOVLPDmr %stack.1.ref.tmp, 1, $noreg, 0, $noreg, %2 :: (store (s64) into %ir.2)
189*fae05692SMatt Arsenault    MOVLPDmr %stack.1.ref.tmp, 1, $noreg, 8, $noreg, %3 :: (store (s64) into %ir.4)
190ccba60a7SCraig Topper    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
191ccba60a7SCraig Topper    %4:gr64 = LEA64r %stack.0.a, 1, $noreg, 0, $noreg
192ccba60a7SCraig Topper    %5:gr64 = LEA64r %stack.1.ref.tmp, 1, $noreg, 0, $noreg
193ccba60a7SCraig Topper    $rdi = COPY %4
194ccba60a7SCraig Topper    $rsi = COPY %5
195ccba60a7SCraig Topper    CALL64pcrel32 @_ZN1e1hERK1d, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit $rsi, implicit-def $rsp, implicit-def $ssp
196ccba60a7SCraig Topper    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
197ccba60a7SCraig Topper    LIFETIME_END %stack.1.ref.tmp
198ccba60a7SCraig Topper    LIFETIME_START %stack.2.b
199ccba60a7SCraig Topper    LIFETIME_START %stack.3.tmp
200ccba60a7SCraig Topper    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
201ccba60a7SCraig Topper    %6:gr64 = LEA64r %stack.3.tmp, 1, $noreg, 0, $noreg
202ccba60a7SCraig Topper    %7:gr64 = LEA64r %stack.2.b, 1, $noreg, 0, $noreg
203ccba60a7SCraig Topper    $rdi = COPY %6
204ccba60a7SCraig Topper    $rsi = COPY %7
205ccba60a7SCraig Topper    CALL64pcrel32 @_ZN1j1kEv, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit $rsi, implicit-def $rsp, implicit-def $ssp
206ccba60a7SCraig Topper    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
207ccba60a7SCraig Topper    LIFETIME_END %stack.3.tmp
208ccba60a7SCraig Topper    LIFETIME_END %stack.2.b
209ccba60a7SCraig Topper    LIFETIME_END %stack.0.a
210ccba60a7SCraig Topper    RET 0
211ccba60a7SCraig Topper
212ccba60a7SCraig Topper...
213