1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -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
5 target 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"
6 target triple = "x86_64-pc-linux-gnu"
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.
11 define void @t0(i4 %cond, i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h) {
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]]
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
31 ; CHECK-NEXT: unreachable
33 switch i4 %cond, label %end [
44 %r3 = add i32 %v1, %v2
45 call void @use32(i32 %r3)
52 %r7 = add i32 %v5, %v6
53 call void @use32(i32 %r7)
60 ; Same, as @t0, but there's also a loop.
61 define void @t1(i4 %cond, i1 %cond.loop, i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h) {
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]]
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]]
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]]
84 ; CHECK-NEXT: call void @sideeffect()
85 ; CHECK-NEXT: br i1 [[COND_LOOP:%.*]], label [[END_EARLY]], label [[END:%.*]]
87 ; CHECK-NEXT: call void @sideeffect()
88 ; CHECK-NEXT: unreachable
90 switch i4 %cond, label %end.early [
101 %r3 = add i32 %v1, %v2
102 call void @use32(i32 %r3)
107 %v5 = add i32 %v4, %c
109 %r7 = add i32 %v5, %v6
110 call void @use32(i32 %r7)
114 call void @sideeffect()
115 br i1 %cond.loop, label %end.early, label %end
118 call void @sideeffect()
122 declare void @use32(i32) speculatable
124 declare void @sideeffect()