Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / X86 / pr48064.mir
bloba6c927185881f153083a66a5e067b103f4943df5
1 # RUN: llc -mtriple="i386-pc-windows-msvc" -run-pass=stack-coloring %s -o - | FileCheck %s
3 # There is a problem with the exception handler, we found in windows, when set
4 # LifetimeStartOnFirstUse=true for stack-coloring in default. Take the following
5 # case for example:
7 #// Compile with "clang-cl -m32 -O2 -EHs test.cpp"
8 #__attribute__((noinline,nothrow,weak)) void escape(int *p) { }
9 #struct object {
10 #  int i;
11 #  object() {
12 #    i = 1;
13 #  }
14 #  ~object() {
15 #    // if "object" and "exp" are assigned to the same slot,
16 #    // this assign will corrupt "exp".
17 #    i = 9999;
18 #    escape(&i);
19 #  }
20 #};
21 #inline void throwit() { throw 999; }
23 #volatile int v;
24 #inline void func() {
25 #  try {
26 #    object o;
27 #    throwit();
28 #  }
29 #  // "exp" is written by the OS when the "throw" occurs.
30 #  // Then the destructor is called, and the store-assign
31 #  // clobbers the value of "exp".
32 #  // The dereference of "exp" (with value 9999) causes a crash.
33 #  // All these done in libruntime, so it is hard to check in IR.
34 #  catch (int &exp) {
35 #    v = exp;
36 #  }
39 #int main() {
40 #  func();
41 #  return 0;
44 ## Make sure that o.i not merge with exp.i
45 # CHECK:      stack:
46 # CHECK:  id: 2, name: o.i, type: default, offset: 0, size: 4, alignment: 4,
47 # CHECK:  id: 3, name: exp.i, type: default, offset: 0, size: 4, alignment: 4,
49 ## Make sure that %stack.3.exp.i not replaced with %stack.2.o.i
50 # CHECK:  bb.3.catch.i (landing-pad, ehfunclet-entry):
51 # CHECK:    %7:gr32 = MOV32rm %stack.3.exp.i, 1, $noreg, 0, $noreg :: (dereferenceable load (s32) from %ir.exp.i)
53 --- |
54   ; ModuleID = 'test-pre-stc.mir'
55   source_filename = "test.cpp"
56   target datalayout = "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:32-n8:16:32-a:0:32-S32"
58   %rtti.TypeDescriptor2 = type { ptr, ptr, [3 x i8] }
59   %eh.CatchableType = type { i32, ptr, i32, i32, i32, i32, ptr }
60   %eh.CatchableTypeArray.1 = type { i32, [1 x ptr] }
61   %eh.ThrowInfo = type { i32, ptr, ptr, ptr }
62   %CXXExceptionRegistration = type { ptr, %EHRegistrationNode, i32 }
63   %EHRegistrationNode = type { ptr, ptr }
64   %struct.object = type { i32 }
66   $"_R0H@8" = comdat any
68   $"_CT_R0H@84" = comdat any
70   $_CTA1H = comdat any
72   $_TI1H = comdat any
74   @v__3HC = dso_local global i32 0, align 4
75   @"_7type_info__6B@" = external constant ptr
76   @"_R0H@8" = linkonce_odr global %rtti.TypeDescriptor2 { ptr @"_7type_info__6B@", ptr null, [3 x i8] c".H\00" }, comdat
77   @"_CT_R0H@84" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 1, ptr @"_R0H@8", i32 0, i32 -1, i32 0, i32 4, ptr null }, section ".xdata", comdat
78   @_CTA1H = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x ptr] [ptr @"_CT_R0H@84"] }, section ".xdata", comdat
79   @_TI1H = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, ptr null, ptr null, ptr @_CTA1H }, section ".xdata", comdat
81   ; Function Attrs: noinline nounwind sspstrong
82   define weak dso_local void @"escape__YAXPAH@Z"(ptr %p) local_unnamed_addr #0 {
83   entry:
84     ret void
85   }
87   ; Function Attrs: norecurse sspstrong
88   define dso_local i32 @main() local_unnamed_addr #1 personality i32 (...)* @__CxxFrameHandler3 {
89   entry:
90     %0 = alloca %CXXExceptionRegistration, align 4
91     %1 = bitcast ptr %0 to ptr
92     call void @llvm.x86.seh.ehregnode(ptr %1)
93     %2 = call ptr @llvm.stacksave()
94     %3 = getelementptr inbounds %CXXExceptionRegistration, ptr %0, i32 0, i32 0
95     store ptr %2, ptr %3, align 4
96     %4 = getelementptr inbounds %CXXExceptionRegistration, ptr %0, i32 0, i32 2
97     store i32 -1, ptr %4, align 4
98     %5 = getelementptr inbounds %CXXExceptionRegistration, ptr %0, i32 0, i32 1
99     %6 = getelementptr inbounds %EHRegistrationNode, ptr %5, i32 0, i32 1
100     store ptr @"__ehhandler$main", ptr %6, align 4
101     %7 = load ptr, ptr addrspace(257) null, align 4
102     %8 = getelementptr inbounds %EHRegistrationNode, ptr %5, i32 0, i32 0
103     store ptr %7, ptr %8, align 4
104     store ptr %5, ptr addrspace(257) null, align 4
105     %tmp.i.i = alloca i32, align 4
106     %o.i = alloca %struct.object, align 4
107     %zx = alloca ptr, align 4
108     %exp.i = alloca ptr, align 4
109     %9 = bitcast ptr %exp.i to ptr
110     call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %9)
111     %10 = bitcast ptr %o.i to ptr
112     call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %10) #7
113     %i.i.i1 = bitcast ptr %o.i to ptr
114     store i32 1, ptr %i.i.i1, align 4
115     %11 = bitcast ptr %tmp.i.i to ptr
116     call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %11)
117     store i32 999, ptr %tmp.i.i, align 4
118     %12 = getelementptr inbounds %CXXExceptionRegistration, ptr %0, i32 0, i32 2
119     store i32 1, ptr %12, align 4
120     invoke void @_CxxThrowException(ptr nonnull %11, ptr nonnull @_TI1H) #8
121             to label %.noexc.i unwind label %ehcleanup.i
123   .noexc.i:                                         ; preds = %entry
124     unreachable
126   ehcleanup.i:                                      ; preds = %entry
127     %13 = cleanuppad within none []
128     %14 = bitcast ptr %o.i to ptr
129     %15 = bitcast ptr %o.i to ptr
130     store i32 9999, ptr %14, align 4
131     call void @"escape__YAXPAH@Z"(ptr nonnull %14) #7 [ "funclet"(token %13) ]
132     call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %15) #7
133     cleanupret from %13 unwind label %catch.dispatch.i
135   catch.dispatch.i:                                 ; preds = %ehcleanup.i
136     %16 = catchswitch within none [label %catch.i] unwind to caller
138   catch.i:                                          ; preds = %catch.dispatch.i
139     %17 = catchpad within %16 [ptr @"_R0H@8", i32 8, ptr %exp.i]
140     %18 = load ptr, ptr %exp.i, align 4
141     %19 = load i32, ptr %18, align 4
142     store atomic volatile i32 %19, ptr @v__3HC release, align 4
143     catchret from %17 to label %func__YAXXZ.exit
145   func__YAXXZ.exit:                                 ; preds = %catch.i
146     %20 = bitcast ptr %exp.i to ptr
147     call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %20)
148     %21 = getelementptr inbounds %CXXExceptionRegistration, ptr %0, i32 0, i32 1
149     %22 = getelementptr inbounds %EHRegistrationNode, ptr %21, i32 0, i32 0
150     %23 = load ptr, ptr %22, align 4
151     store ptr %23, ptr addrspace(257) null, align 4
152     ret i32 0
153   }
155   ; Function Attrs: argmemonly nofree nosync nounwind willreturn
156   declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #2
158   ; Function Attrs: nofree
159   declare dso_local i32 @__CxxFrameHandler3(...) #3
161   ; Function Attrs: argmemonly nofree nosync nounwind willreturn
162   declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #2
164   ; Function Attrs: nofree
165   declare dso_local x86_stdcallcc void @_CxxThrowException(ptr, ptr) local_unnamed_addr #3
167   declare i32 @_setjmp3(ptr, i32, ...)
169   ; Function Attrs: nofree nosync nounwind willreturn
170   declare ptr @llvm.stacksave() #4
172   define internal i32 @"__ehhandler$main"(ptr %0, ptr %1, ptr %2, ptr %3) #5 {
173   entry:
174     %4 = call ptr @llvm.x86.seh.lsda(ptr @main)
175     %5 = tail call i32 @__CxxFrameHandler3(ptr inreg %4, ptr %0, ptr %1, ptr %2, ptr %3)
176     ret i32 %5
177   }
179   ; Function Attrs: nounwind readnone
180   declare ptr @llvm.x86.seh.lsda(ptr) #6
182   declare x86_stdcallcc void @__CxxLongjmpUnwind(ptr)
184   ; Function Attrs: nounwind
185   declare void @llvm.x86.seh.ehregnode(ptr) #7
187   attributes #0 = { noinline nounwind sspstrong "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" }
188   attributes #1 = { norecurse sspstrong "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" }
189   attributes #2 = { argmemonly nofree nosync nounwind willreturn }
190   attributes #3 = { nofree }
191   attributes #4 = { nofree nosync nounwind willreturn }
192   attributes #5 = { "safeseh" }
193   attributes #6 = { nounwind readnone }
194   attributes #7 = { nounwind }
195   attributes #8 = { noreturn }
197   !llvm.linker.options = !{!0, !1, !2}
198   !llvm.module.flags = !{!3, !4}
199   !llvm.ident = !{!5}
201   !0 = !{!"/DEFAULTLIB:libcmt.lib"}
202   !1 = !{!"/DEFAULTLIB:libmmt.lib"}
203   !2 = !{!"/DEFAULTLIB:oldnames.lib"}
204   !3 = !{i32 1, !"NumRegisterParameters", i32 0}
205   !4 = !{i32 1, !"wchar_size", i32 2}
206   !5 = !{!"Intel(R) oneAPI DPC++ Compiler Pro 2021.1 (YYYY.x.0.MMDD)"}
210 name:            'escape__YAXPAH@Z'
211 alignment:       16
212 exposesReturnsTwice: false
213 legalized:       false
214 regBankSelected: false
215 selected:        false
216 failedISel:      false
217 tracksRegLiveness: true
218 hasWinCFI:       false
219 registers:       []
220 liveins:         []
221 frameInfo:
222   isFrameAddressTaken: false
223   isReturnAddressTaken: false
224   hasStackMap:     false
225   hasPatchPoint:   false
226   stackSize:       0
227   offsetAdjustment: 0
228   maxAlignment:    4
229   adjustsStack:    false
230   hasCalls:        false
231   stackProtector:  ''
232   maxCallFrameSize: 4294967295
233   cvBytesOfCalleeSavedRegisters: 0
234   hasOpaqueSPAdjustment: false
235   hasVAStart:      false
236   hasMustTailInVarArgFunc: false
237   localFrameSize:  0
238   savePoint:       ''
239   restorePoint:    ''
240 fixedStack:
241   - { id: 0, type: default, offset: 0, size: 4, alignment: 4, stack-id: default,
242       isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
243       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
244 stack:           []
245 callSites:       []
246 debugValueSubstitutions: []
247 constants:       []
248 machineFunctionInfo: {}
249 body:             |
250   bb.0.entry:
251     RET 0
255 name:            main
256 alignment:       16
257 exposesReturnsTwice: false
258 legalized:       false
259 regBankSelected: false
260 selected:        false
261 failedISel:      false
262 tracksRegLiveness: true
263 hasWinCFI:       false
264 registers:
265   - { id: 0, class: gr32, preferred-register: '' }
266   - { id: 1, class: gr32, preferred-register: '' }
267   - { id: 2, class: gr32, preferred-register: '' }
268   - { id: 3, class: gr32, preferred-register: '' }
269   - { id: 4, class: gr32, preferred-register: '' }
270   - { id: 5, class: gr32, preferred-register: '' }
271   - { id: 6, class: gr32, preferred-register: '' }
272   - { id: 7, class: gr32, preferred-register: '' }
273   - { id: 8, class: gr32, preferred-register: '' }
274   - { id: 9, class: gr32, preferred-register: '' }
275   - { id: 10, class: gr32, preferred-register: '' }
276 liveins:         []
277 frameInfo:
278   isFrameAddressTaken: false
279   isReturnAddressTaken: false
280   hasStackMap:     false
281   hasPatchPoint:   false
282   stackSize:       0
283   offsetAdjustment: 0
284   maxAlignment:    4
285   adjustsStack:    false
286   hasCalls:        true
287   stackProtector:  ''
288   maxCallFrameSize: 4294967295
289   cvBytesOfCalleeSavedRegisters: 0
290   hasOpaqueSPAdjustment: true
291   hasVAStart:      false
292   hasMustTailInVarArgFunc: false
293   localFrameSize:  0
294   savePoint:       ''
295   restorePoint:    ''
296 fixedStack:      []
297 stack:
298   - { id: 0, name: zx, type: default, offset: 0, size: 16, alignment: 4,
299       stack-id: default, callee-saved-register: '', callee-saved-restored: true,
300       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
301   - { id: 1, name: tmp.i.i, type: default, offset: 0, size: 4, alignment: 4,
302       stack-id: default, callee-saved-register: '', callee-saved-restored: true,
303       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
304   - { id: 2, name: o.i, type: default, offset: 0, size: 4, alignment: 4,
305       stack-id: default, callee-saved-register: '', callee-saved-restored: true,
306       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
307   - { id: 3, name: exp.i, type: default, offset: 0, size: 4, alignment: 4,
308       stack-id: default, callee-saved-register: '', callee-saved-restored: true,
309       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
310 callSites:       []
311 debugValueSubstitutions: []
312 constants:       []
313 machineFunctionInfo: {}
314 body:             |
315   bb.0.entry:
316     successors: %bb.1(0x7ffff800), %bb.2(0x00000800)
318     %0:gr32 = COPY $esp
319     MOV32mr %stack.0.zx, 1, $noreg, 0, $noreg, %0 :: (store (s32) into %ir.3)
320     MOV32mi %stack.0.zx, 1, $noreg, 12, $noreg, -1 :: (store (s32) into %ir.4)
321     %1:gr32 = nuw LEA32r %stack.0.zx, 1, $noreg, 4, $noreg
322     MOV32mi %stack.0.zx, 1, $noreg, 8, $noreg, @"__ehhandler$main" :: (store (s32) into %ir.6)
323     %2:gr32 = MOV32rm $noreg, 1, $noreg, 0, $fs :: (load (s32) from `ptr addrspace(257) null`, addrspace 257)
324     MOV32mr %stack.0.zx, 1, $noreg, 4, $noreg, killed %2 :: (store (s32) into %ir.8)
325     MOV32mr $noreg, 1, $noreg, 0, $fs, killed %1 :: (store (s32) into `ptr addrspace(257) null`, addrspace 257)
326     MOV32mi %stack.2.o.i, 1, $noreg, 0, $noreg, 1 :: (store (s32) into %ir.i.i.i1)
327     MOV32mi %stack.1.tmp.i.i, 1, $noreg, 0, $noreg, 999 :: (store (s32) into %ir.tmp.i.i)
328     MOV32mi %stack.0.zx, 1, $noreg, 12, $noreg, 1 :: (store (s32) into %ir.12)
329     ADJCALLSTACKDOWN32 8, 0, 0, implicit-def dead $esp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $esp, implicit $ssp
330     %3:gr32 = COPY $esp
331     %4:gr32 = LEA32r %stack.1.tmp.i.i, 1, $noreg, 0, $noreg
332     MOV32mr %3, 1, $noreg, 0, $noreg, killed %4 :: (store (s32) into stack)
333     MOV32mi %3, 1, $noreg, 4, $noreg, @_TI1H :: (store (s32) into stack + 4)
334     CALLpcrel32 @_CxxThrowException, csr_noregs, implicit $esp, implicit $ssp, implicit-def $esp, implicit-def $ssp
335     ADJCALLSTACKUP32 8, 0, implicit-def dead $esp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $esp, implicit $ssp
336     JMP_1 %bb.1
338   bb.1..noexc.i:
339     successors:
342   bb.2.ehcleanup.i (landing-pad, ehfunclet-entry):
343     successors: %bb.3(0x80000000)
345     MOV32mi %stack.2.o.i, 1, $noreg, 0, $noreg, 9999 :: (store (s32) into %ir.14)
346     ADJCALLSTACKDOWN32 4, 0, 0, implicit-def dead $esp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $esp, implicit $ssp
347     %5:gr32 = COPY $esp
348     %6:gr32 = LEA32r %stack.2.o.i, 1, $noreg, 0, $noreg
349     MOV32mr %5, 1, $noreg, 0, $noreg, killed %6 :: (store (s32) into stack)
350     CALLpcrel32 @"escape__YAXPAH@Z", csr_32, implicit $esp, implicit $ssp, implicit-def $esp, implicit-def $ssp
351     ADJCALLSTACKUP32 4, 0, implicit-def dead $esp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $esp, implicit $ssp
352     CLEANUPRET
354   bb.3.catch.i (landing-pad, ehfunclet-entry):
355     successors: %bb.4(0x80000000)
357     %7:gr32 = MOV32rm %stack.3.exp.i, 1, $noreg, 0, $noreg :: (dereferenceable load (s32) from %ir.exp.i)
358     %8:gr32 = MOV32rm killed %7, 1, $noreg, 0, $noreg :: (load (s32) from %ir.18)
359     MOV32mr $noreg, 1, $noreg, @v__3HC, $noreg, killed %8 :: (volatile store release (s32) into @v__3HC)
360     CATCHRET %bb.4, %bb.0
362   bb.4.catch.i (landing-pad):
363     successors: %bb.5(0x80000000)
365     JMP_4 %bb.5
367   bb.5.func__YAXXZ.exit:
368     %9:gr32 = MOV32rm %stack.0.zx, 1, $noreg, 4, $noreg :: (dereferenceable load (s32) from %ir.22)
369     MOV32mr $noreg, 1, $noreg, 0, $fs, killed %9 :: (store (s32) into `ptr addrspace(257) null`, addrspace 257)
370     %10:gr32 = MOV32r0 implicit-def dead $eflags
371     $eax = COPY %10
372     RET 0, $eax
376 name:            '__ehhandler$main'
377 alignment:       16
378 exposesReturnsTwice: false
379 legalized:       false
380 regBankSelected: false
381 selected:        false
382 failedISel:      false
383 tracksRegLiveness: true
384 hasWinCFI:       false
385 registers:
386   - { id: 0, class: gr32, preferred-register: '' }
387 liveins:         []
388 frameInfo:
389   isFrameAddressTaken: false
390   isReturnAddressTaken: false
391   hasStackMap:     false
392   hasPatchPoint:   false
393   stackSize:       0
394   offsetAdjustment: 0
395   maxAlignment:    4
396   adjustsStack:    false
397   hasCalls:        false
398   stackProtector:  ''
399   maxCallFrameSize: 4294967295
400   cvBytesOfCalleeSavedRegisters: 0
401   hasOpaqueSPAdjustment: false
402   hasVAStart:      false
403   hasMustTailInVarArgFunc: false
404   localFrameSize:  0
405   savePoint:       ''
406   restorePoint:    ''
407 fixedStack:
408   - { id: 0, type: default, offset: 0, size: 4, alignment: 4, stack-id: default,
409       isImmutable: false, isAliased: false, callee-saved-register: '',
410       callee-saved-restored: true, debug-info-variable: '', debug-info-expression: '',
411       debug-info-location: '' }
412   - { id: 1, type: default, offset: 4, size: 4, alignment: 4, stack-id: default,
413       isImmutable: false, isAliased: false, callee-saved-register: '',
414       callee-saved-restored: true, debug-info-variable: '', debug-info-expression: '',
415       debug-info-location: '' }
416   - { id: 2, type: default, offset: 8, size: 4, alignment: 4, stack-id: default,
417       isImmutable: false, isAliased: false, callee-saved-register: '',
418       callee-saved-restored: true, debug-info-variable: '', debug-info-expression: '',
419       debug-info-location: '' }
420   - { id: 3, type: default, offset: 12, size: 4, alignment: 4, stack-id: default,
421       isImmutable: false, isAliased: false, callee-saved-register: '',
422       callee-saved-restored: true, debug-info-variable: '', debug-info-expression: '',
423       debug-info-location: '' }
424 stack:           []
425 callSites:       []
426 debugValueSubstitutions: []
427 constants:       []
428 machineFunctionInfo: {}
429 body:             |
430   bb.0.entry:
431     %0:gr32 = MOV32ri <mcsymbol L__ehtable$main>
432     $eax = COPY %0
433     TCRETURNdi @__CxxFrameHandler3, 0, csr_32, implicit $esp, implicit $ssp, implicit $eax