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