xref: /llvm-project/llvm/test/Transforms/SimplifyCFG/X86/sink-common-code-into-unreachable.ll (revision 07b9d231ff9baa6473b0dd588a3ce5330d3e4871)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -sink-common-insts -S | FileCheck %s
3; RUN: opt < %s -passes='simplifycfg<sink-common-insts>' -S | FileCheck %s
4
5target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
6target triple = "x86_64-pc-linux-gnu"
7
8; `unreachable` block has conditional predecessors,
9; but everything we'd sink from unconditional predecessors are speculatable.
10; Also, too many phi's would normally be needed.
11define void @t0(i4 %cond,  i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h) {
12; CHECK-LABEL: @t0(
13; CHECK-NEXT:    switch i4 [[COND:%.*]], label [[END:%.*]] [
14; CHECK-NEXT:      i4 0, label [[END_SINK_SPLIT:%.*]]
15; CHECK-NEXT:      i4 -1, label [[END_SINK_SPLIT]]
16; CHECK-NEXT:      i4 1, label [[BB1:%.*]]
17; CHECK-NEXT:      i4 -2, label [[BB1]]
18; CHECK-NEXT:    ]
19; CHECK:       bb1:
20; CHECK-NEXT:    br label [[END_SINK_SPLIT]]
21; CHECK:       end.sink.split:
22; CHECK-NEXT:    [[H_SINK:%.*]] = phi i32 [ [[H:%.*]], [[BB1]] ], [ [[E:%.*]], [[TMP0:%.*]] ], [ [[E]], [[TMP0]] ]
23; CHECK-NEXT:    [[G_SINK:%.*]] = phi i32 [ [[G:%.*]], [[BB1]] ], [ [[D:%.*]], [[TMP0]] ], [ [[D]], [[TMP0]] ]
24; CHECK-NEXT:    [[V4:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
25; CHECK-NEXT:    [[V5:%.*]] = add i32 [[V4]], [[C:%.*]]
26; CHECK-NEXT:    [[V6:%.*]] = add i32 [[G_SINK]], [[H_SINK]]
27; CHECK-NEXT:    [[R7:%.*]] = add i32 [[V5]], [[V6]]
28; CHECK-NEXT:    call void @use32(i32 [[R7]])
29; CHECK-NEXT:    unreachable
30; CHECK:       end:
31; CHECK-NEXT:    unreachable
32;
33  switch i4 %cond, label %end [
34  i4 0, label %bb0
35  i4 -1, label %bb0
36  i4  1, label %bb1
37  i4 -2, label %bb1
38  ]
39
40bb0:
41  %v0 = add i32 %a, %b
42  %v1 = add i32 %v0, %c
43  %v2 = add i32 %d, %e
44  %r3 = add i32 %v1, %v2
45  call void @use32(i32 %r3)
46  br label %end
47
48bb1:
49  %v4 = add i32 %a, %b
50  %v5 = add i32 %v4, %c
51  %v6 = add i32 %g, %h
52  %r7 = add i32 %v5, %v6
53  call void @use32(i32 %r7)
54  br label %end
55
56end:
57  unreachable
58}
59
60; Same, as @t0, but there's also a loop.
61define void @t1(i4 %cond, i1 %cond.loop, i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h) {
62; CHECK-LABEL: @t1(
63; CHECK-NEXT:    switch i4 [[COND:%.*]], label [[END_EARLY:%.*]] [
64; CHECK-NEXT:      i4 0, label [[BB0:%.*]]
65; CHECK-NEXT:      i4 -1, label [[BB0]]
66; CHECK-NEXT:      i4 1, label [[BB1:%.*]]
67; CHECK-NEXT:      i4 -2, label [[BB1]]
68; CHECK-NEXT:    ]
69; CHECK:       bb0:
70; CHECK-NEXT:    [[V0:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
71; CHECK-NEXT:    [[V1:%.*]] = add i32 [[V0]], [[C:%.*]]
72; CHECK-NEXT:    [[V2:%.*]] = add i32 [[D:%.*]], [[E:%.*]]
73; CHECK-NEXT:    [[R3:%.*]] = add i32 [[V1]], [[V2]]
74; CHECK-NEXT:    call void @use32(i32 [[R3]])
75; CHECK-NEXT:    br label [[END_EARLY]]
76; CHECK:       bb1:
77; CHECK-NEXT:    [[V4:%.*]] = add i32 [[A]], [[B]]
78; CHECK-NEXT:    [[V5:%.*]] = add i32 [[V4]], [[C]]
79; CHECK-NEXT:    [[V6:%.*]] = add i32 [[G:%.*]], [[H:%.*]]
80; CHECK-NEXT:    [[R7:%.*]] = add i32 [[V5]], [[V6]]
81; CHECK-NEXT:    call void @use32(i32 [[R7]])
82; CHECK-NEXT:    br label [[END_EARLY]]
83; CHECK:       end.early:
84; CHECK-NEXT:    call void @sideeffect()
85; CHECK-NEXT:    br i1 [[COND_LOOP:%.*]], label [[END_EARLY]], label [[END:%.*]]
86; CHECK:       end:
87; CHECK-NEXT:    call void @sideeffect()
88; CHECK-NEXT:    unreachable
89;
90  switch i4 %cond, label %end.early [
91  i4 0, label %bb0
92  i4 -1, label %bb0
93  i4  1, label %bb1
94  i4 -2, label %bb1
95  ]
96
97bb0:
98  %v0 = add i32 %a, %b
99  %v1 = add i32 %v0, %c
100  %v2 = add i32 %d, %e
101  %r3 = add i32 %v1, %v2
102  call void @use32(i32 %r3)
103  br label %end.early
104
105bb1:
106  %v4 = add i32 %a, %b
107  %v5 = add i32 %v4, %c
108  %v6 = add i32 %g, %h
109  %r7 = add i32 %v5, %v6
110  call void @use32(i32 %r7)
111  br label %end.early
112
113end.early:
114  call void @sideeffect()
115  br i1 %cond.loop, label %end.early, label %end
116
117end:
118  call void @sideeffect()
119  unreachable
120}
121
122declare void @use32(i32) speculatable
123
124declare void @sideeffect()
125