1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -S -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -bonus-inst-threshold=1 | FileCheck --check-prefixes=ALL,THR1 %s
3; RUN: opt < %s -S -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -bonus-inst-threshold=2 | FileCheck --check-prefixes=ALL,THR2 %s
4
5declare void @sideeffect0()
6declare void @sideeffect1()
7declare void @sideeffect2()
8declare void @use8(i8)
9declare i1 @gen1()
10
11; Here we'd want to duplicate %v3_adj into two predecessors,
12; but -bonus-inst-threshold=1 says that we can only clone it into one.
13; With -bonus-inst-threshold=2 we can clone it into both though.
14define void @two_preds_with_extra_op(i8 %v0, i8 %v1, i8 %v2, i8 %v3) {
15; THR1-LABEL: @two_preds_with_extra_op(
16; THR1-NEXT:  entry:
17; THR1-NEXT:    [[C0:%.*]] = icmp eq i8 [[V0:%.*]], 0
18; THR1-NEXT:    br i1 [[C0]], label [[PRED0:%.*]], label [[PRED1:%.*]]
19; THR1:       pred0:
20; THR1-NEXT:    [[C1:%.*]] = icmp eq i8 [[V1:%.*]], 0
21; THR1-NEXT:    br i1 [[C1]], label [[FINAL_LEFT:%.*]], label [[DISPATCH:%.*]]
22; THR1:       pred1:
23; THR1-NEXT:    [[C2:%.*]] = icmp eq i8 [[V2:%.*]], 0
24; THR1-NEXT:    br i1 [[C2]], label [[DISPATCH]], label [[FINAL_RIGHT:%.*]]
25; THR1:       dispatch:
26; THR1-NEXT:    [[V3_ADJ:%.*]] = add i8 [[V1]], [[V2]]
27; THR1-NEXT:    [[C3:%.*]] = icmp eq i8 [[V3_ADJ]], 0
28; THR1-NEXT:    br i1 [[C3]], label [[FINAL_LEFT]], label [[FINAL_RIGHT]]
29; THR1:       common.ret:
30; THR1-NEXT:    ret void
31; THR1:       final_left:
32; THR1-NEXT:    call void @sideeffect0()
33; THR1-NEXT:    br label [[COMMON_RET:%.*]]
34; THR1:       final_right:
35; THR1-NEXT:    call void @sideeffect1()
36; THR1-NEXT:    br label [[COMMON_RET]]
37;
38; THR2-LABEL: @two_preds_with_extra_op(
39; THR2-NEXT:  entry:
40; THR2-NEXT:    [[C0:%.*]] = icmp eq i8 [[V0:%.*]], 0
41; THR2-NEXT:    br i1 [[C0]], label [[PRED0:%.*]], label [[PRED1:%.*]]
42; THR2:       pred0:
43; THR2-NEXT:    [[C1:%.*]] = icmp eq i8 [[V1:%.*]], 0
44; THR2-NEXT:    [[V3_ADJ_OLD:%.*]] = add i8 [[V1]], [[V2:%.*]]
45; THR2-NEXT:    [[C3_OLD:%.*]] = icmp eq i8 [[V3_ADJ_OLD]], 0
46; THR2-NEXT:    [[OR_COND1:%.*]] = select i1 [[C1]], i1 true, i1 [[C3_OLD]]
47; THR2-NEXT:    br i1 [[OR_COND1]], label [[FINAL_LEFT:%.*]], label [[FINAL_RIGHT:%.*]]
48; THR2:       pred1:
49; THR2-NEXT:    [[C2:%.*]] = icmp eq i8 [[V2]], 0
50; THR2-NEXT:    [[V3_ADJ:%.*]] = add i8 [[V1]], [[V2]]
51; THR2-NEXT:    [[C3:%.*]] = icmp eq i8 [[V3_ADJ]], 0
52; THR2-NEXT:    [[OR_COND:%.*]] = select i1 [[C2]], i1 [[C3]], i1 false
53; THR2-NEXT:    br i1 [[OR_COND]], label [[FINAL_LEFT]], label [[FINAL_RIGHT]]
54; THR2:       common.ret:
55; THR2-NEXT:    ret void
56; THR2:       final_left:
57; THR2-NEXT:    call void @sideeffect0()
58; THR2-NEXT:    br label [[COMMON_RET:%.*]]
59; THR2:       final_right:
60; THR2-NEXT:    call void @sideeffect1()
61; THR2-NEXT:    br label [[COMMON_RET]]
62;
63entry:
64  %c0 = icmp eq i8 %v0, 0
65  br i1 %c0, label %pred0, label %pred1
66pred0:
67  %c1 = icmp eq i8 %v1, 0
68  br i1 %c1, label %final_left, label %dispatch
69pred1:
70  %c2 = icmp eq i8 %v2, 0
71  br i1 %c2, label %dispatch, label %final_right
72dispatch:
73  %v3_adj = add i8 %v1, %v2
74  %c3 = icmp eq i8 %v3_adj, 0
75  br i1 %c3, label %final_left, label %final_right
76final_left:
77  call void @sideeffect0()
78  ret void
79final_right:
80  call void @sideeffect1()
81  ret void
82}
83
84; Here we'd want to duplicate %v3_adj into two predecessors,
85; but -bonus-inst-threshold=1 says that we can only clone it into one.
86; But, we aren't going to clone it into one of the predecessors,
87; because that isn't profitable. So we should not use it in cost calculation.
88define void @two_preds_with_extra_op_and_branchweights(i8 %v0, i8 %v1, i8 %v2, i8 %v3) {
89; ALL-LABEL: @two_preds_with_extra_op_and_branchweights(
90; ALL-NEXT:  entry:
91; ALL-NEXT:    [[C0:%.*]] = icmp eq i8 [[V0:%.*]], 0
92; ALL-NEXT:    br i1 [[C0]], label [[PRED0:%.*]], label [[PRED1:%.*]]
93; ALL:       pred0:
94; ALL-NEXT:    [[C1:%.*]] = icmp eq i8 [[V1:%.*]], 0
95; ALL-NEXT:    br i1 [[C1]], label [[FINAL_LEFT:%.*]], label [[DISPATCH:%.*]], !prof [[PROF0:![0-9]+]]
96; ALL:       pred1:
97; ALL-NEXT:    [[C2:%.*]] = icmp eq i8 [[V2:%.*]], 0
98; ALL-NEXT:    [[V3_ADJ:%.*]] = add i8 [[V1]], [[V2]]
99; ALL-NEXT:    [[C3:%.*]] = icmp eq i8 [[V3_ADJ]], 0
100; ALL-NEXT:    [[OR_COND:%.*]] = select i1 [[C2]], i1 [[C3]], i1 false
101; ALL-NEXT:    br i1 [[OR_COND]], label [[FINAL_LEFT]], label [[FINAL_RIGHT:%.*]]
102; ALL:       dispatch:
103; ALL-NEXT:    [[V3_ADJ_OLD:%.*]] = add i8 [[V1]], [[V2]]
104; ALL-NEXT:    [[C3_OLD:%.*]] = icmp eq i8 [[V3_ADJ_OLD]], 0
105; ALL-NEXT:    br i1 [[C3_OLD]], label [[FINAL_LEFT]], label [[FINAL_RIGHT]]
106; ALL:       common.ret:
107; ALL-NEXT:    ret void
108; ALL:       final_left:
109; ALL-NEXT:    call void @sideeffect0()
110; ALL-NEXT:    br label [[COMMON_RET:%.*]]
111; ALL:       final_right:
112; ALL-NEXT:    call void @sideeffect1()
113; ALL-NEXT:    br label [[COMMON_RET]]
114;
115entry:
116  %c0 = icmp eq i8 %v0, 0
117  br i1 %c0, label %pred0, label %pred1
118pred0:
119  %c1 = icmp eq i8 %v1, 0
120  br i1 %c1, label %final_left, label %dispatch, !prof !0 ; likely branches to %final_left
121pred1:
122  %c2 = icmp eq i8 %v2, 0
123  br i1 %c2, label %dispatch, label %final_right
124dispatch:
125  %v3_adj = add i8 %v1, %v2
126  %c3 = icmp eq i8 %v3_adj, 0
127  br i1 %c3, label %final_left, label %final_right
128final_left:
129  call void @sideeffect0()
130  ret void
131final_right:
132  call void @sideeffect1()
133  ret void
134}
135
136!0 = !{!"branch_weights", i32 99, i32 1}
137
138; CHECK: !0 = !{!"branch_weights", i32 99, i32 1}
139