Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / SimplifyCFG / fold-branch-to-common-dest-two-preds-cost.ll
blob8f41dfe90a0b72ae64a7e27b03178893b66f7282
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -bonus-inst-threshold=1 | FileCheck --check-prefixes=ALL,THR1 %s
3 ; RUN: opt < %s -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -bonus-inst-threshold=2 | FileCheck --check-prefixes=ALL,THR2 %s
5 declare void @sideeffect0()
6 declare void @sideeffect1()
7 declare void @sideeffect2()
8 declare void @use8(i8)
9 declare i1 @gen1()
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.
14 define 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]]
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]]
63 entry:
64   %c0 = icmp eq i8 %v0, 0
65   br i1 %c0, label %pred0, label %pred1
66 pred0:
67   %c1 = icmp eq i8 %v1, 0
68   br i1 %c1, label %final_left, label %dispatch
69 pred1:
70   %c2 = icmp eq i8 %v2, 0
71   br i1 %c2, label %dispatch, label %final_right
72 dispatch:
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
76 final_left:
77   call void @sideeffect0()
78   ret void
79 final_right:
80   call void @sideeffect1()
81   ret void
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.
88 define 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]]
115 entry:
116   %c0 = icmp eq i8 %v0, 0
117   br i1 %c0, label %pred0, label %pred1
118 pred0:
119   %c1 = icmp eq i8 %v1, 0
120   br i1 %c1, label %final_left, label %dispatch, !prof !0 ; likely branches to %final_left
121 pred1:
122   %c2 = icmp eq i8 %v2, 0
123   br i1 %c2, label %dispatch, label %final_right
124 dispatch:
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
128 final_left:
129   call void @sideeffect0()
130   ret void
131 final_right:
132   call void @sideeffect1()
133   ret void
136 !0 = !{!"branch_weights", i32 99, i32 1}
138 ; CHECK: !0 = !{!"branch_weights", i32 99, i32 1}