xref: /llvm-project/llvm/test/CodeGen/X86/noreturn-call.ll (revision 2f448bf509432c1a19ec46ab8cbc7353c03c6280)
1; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s
2
3define void @test1(i32 %c) {
4; CHECK-LABEL: test1:
5entry:
6  %0 = alloca i8, i32 %c
7  %tobool = icmp eq i32 %c, 0
8  br i1 %tobool, label %if.end, label %if.then
9
10if.end:
11  call void @g(ptr %0)
12  ret void
13
14if.then:
15  call void @crash(ptr %0)
16  unreachable
17; CHECK: calll _crash
18; There is no need to adjust the stack after the call, since
19; the function is noreturn and that code will therefore never run.
20; CHECK-NOT: add
21; CHECK-NOT: pop
22}
23
24define void @test2(i32 %c) {
25; CHECK-LABEL: test2:
26entry:
27  %0 = alloca i8, i32 %c
28  %tobool = icmp eq i32 %c, 0
29  br i1 %tobool, label %if.end, label %if.then
30
31if.end:
32  call void @g(ptr %0)
33  ret void
34
35if.then:
36  call void @crash2(ptr %0)
37  unreachable
38; CHECK: calll _crash2
39; Even though _crash2 is not marked noreturn, it is in practice because
40; of the "unreachable" right after it. This happens e.g. when falling off
41; a non-void function after a call.
42; CHECK-NOT: add
43; CHECK-NOT: pop
44}
45
46declare void @crash(ptr) noreturn
47declare void @crash2(ptr)
48declare void @g(ptr)
49
50%struct.ByVal = type { [10 x i32] }
51
52define dso_local i32 @pr43155() {
53entry:
54  %agg.tmp = alloca %struct.ByVal, align 4
55  %agg.tmp5 = alloca %struct.ByVal, align 4
56  %agg.tmp6 = alloca %struct.ByVal, align 4
57  %call = tail call i32 @cond()
58  %tobool = icmp eq i32 %call, 0
59  br i1 %tobool, label %if.end, label %if.then
60
61if.then:                                          ; preds = %entry
62  tail call x86_stdcallcc void @stdcall_abort(i32 12, i32 2)
63  unreachable
64
65if.end:                                           ; preds = %entry
66  %call1 = tail call i32 @cond()
67  %tobool2 = icmp eq i32 %call1, 0
68  br i1 %tobool2, label %if.end4, label %if.then3
69
70if.then3:                                         ; preds = %if.end
71  tail call x86_stdcallcc void @stdcall_abort(i32 15, i32 2)
72  unreachable
73
74if.end4:                                          ; preds = %if.end
75  call void @getbyval(ptr nonnull sret(%struct.ByVal) %agg.tmp)
76  call void @make_push_unprofitable(ptr nonnull byval(%struct.ByVal) align 4 %agg.tmp)
77  call void @getbyval(ptr nonnull sret(%struct.ByVal) %agg.tmp5)
78  call void @make_push_unprofitable(ptr nonnull byval(%struct.ByVal) align 4 %agg.tmp5)
79  call void @getbyval(ptr nonnull sret(%struct.ByVal) %agg.tmp6)
80  call void @make_push_unprofitable(ptr nonnull byval(%struct.ByVal) align 4 %agg.tmp6)
81  ret i32 0
82}
83
84;   Check that there are no stack adjustments after stdcall_abort.
85; CHECK-LABEL: pr43155:
86;   The main function body contents are not important.
87; CHECK: retl
88; CHECK:  # %if.then
89; CHECK: calll _stdcall_abort@8
90; CHECK-NOT: sub
91; CHECK-NOT: add
92; CHECK:  # %if.then3
93; CHECK: calll _stdcall_abort@8
94; CHECK-NOT: sub
95; CHECK-NOT: add
96; CHECK: # -- End function
97
98declare dso_local i32 @cond()
99
100declare dso_local x86_stdcallcc void @stdcall_abort(i32, i32) noreturn
101
102declare dso_local void @make_push_unprofitable(ptr byval(%struct.ByVal) align 4)
103
104declare dso_local void @getbyval(ptr sret(%struct.ByVal))
105