1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
2 ; RUN: opt -passes=ipsccp -S %s -o -| FileCheck %s
4 define void @caller.1(ptr %arg) {
5 ; CHECK-LABEL: define {{[^@]+}}@caller.1
6 ; CHECK-SAME: (ptr [[ARG:%.*]]) {
7 ; CHECK-NEXT: [[R_1:%.*]] = tail call i32 @callee.1(i32 4)
8 ; CHECK-NEXT: [[R_2:%.*]] = tail call i32 @callee.1(i32 2)
9 ; CHECK-NEXT: call void @use(i32 20)
10 ; CHECK-NEXT: ret void
12 %r.1 = tail call i32 @callee.1(i32 4)
13 %r.2 = tail call i32 @callee.1(i32 2)
14 %r.3 = add i32 %r.1, %r.2
15 call void @use(i32 %r.3)
19 define internal i32 @callee.1(i32 %arg) {
20 ; CHECK-LABEL: define {{[^@]+}}@callee.1
21 ; CHECK-SAME: (i32 range(i32 2, 5) [[ARG:%.*]]) {
22 ; CHECK-NEXT: [[SEL:%.*]] = select i1 false, i32 16, i32 [[ARG]]
23 ; CHECK-NEXT: br label [[BB10:%.*]]
25 ; CHECK-NEXT: ret i32 poison
27 %c.1 = icmp slt i32 %arg, 0
28 %sel = select i1 %c.1, i32 16, i32 %arg
29 %c.2 = icmp eq i32 %sel, 0
30 br i1 %c.2, label %bb12, label %bb10
35 bb12: ; preds = %bb8, %bb3, %bb
39 declare void @use(i32)
41 define internal i1 @f1(i32 %x, i32 %y, i1 %cmp) {
42 ; CHECK-LABEL: define {{[^@]+}}@f1
43 ; CHECK-SAME: (i32 range(i32 10, 21) [[X:%.*]], i32 range(i32 100, 201) [[Y:%.*]], i1 [[CMP:%.*]]) {
44 ; CHECK-NEXT: [[SEL_1:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[Y]]
45 ; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i32 [[SEL_1]], 100
46 ; CHECK-NEXT: [[C_3:%.*]] = icmp eq i32 [[SEL_1]], 50
47 ; CHECK-NEXT: [[RES_1:%.*]] = add nuw nsw i1 false, [[C_2]]
48 ; CHECK-NEXT: [[RES_2:%.*]] = add i1 [[RES_1]], [[C_3]]
49 ; CHECK-NEXT: [[RES_3:%.*]] = add nuw nsw i1 [[RES_2]], false
50 ; CHECK-NEXT: ret i1 [[RES_3]]
52 %sel.1 = select i1 %cmp, i32 %x, i32 %y
53 %c.1 = icmp sgt i32 %sel.1, 300
54 %c.2 = icmp sgt i32 %sel.1, 100
55 %c.3 = icmp eq i32 %sel.1, 50
56 %c.4 = icmp slt i32 %sel.1, 9
57 %res.1 = add i1 %c.1, %c.2
58 %res.2 = add i1 %res.1, %c.3
59 %res.3 = add i1 %res.2, %c.4
63 define i1 @caller1(i1 %cmp) {
64 ; CHECK-LABEL: define {{[^@]+}}@caller1
65 ; CHECK-SAME: (i1 [[CMP:%.*]]) {
66 ; CHECK-NEXT: [[CALL_1:%.*]] = tail call i1 @f1(i32 10, i32 100, i1 [[CMP]])
67 ; CHECK-NEXT: [[CALL_2:%.*]] = tail call i1 @f1(i32 20, i32 200, i1 [[CMP]])
68 ; CHECK-NEXT: [[RES:%.*]] = and i1 [[CALL_1]], [[CALL_2]]
69 ; CHECK-NEXT: ret i1 [[RES]]
71 %call.1 = tail call i1 @f1(i32 10, i32 100, i1 %cmp)
72 %call.2 = tail call i1 @f1(i32 20, i32 200, i1 %cmp)
73 %res = and i1 %call.1, %call.2
78 define i1 @f2(i32 %x, i32 %y, i1 %cmp) {
79 ; CHECK-LABEL: define {{[^@]+}}@f2
80 ; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]], i1 [[CMP:%.*]]) {
81 ; CHECK-NEXT: [[SEL_1:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[Y]]
82 ; CHECK-NEXT: [[C_1:%.*]] = icmp sgt i32 [[SEL_1]], 300
83 ; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i32 [[SEL_1]], 100
84 ; CHECK-NEXT: [[C_3:%.*]] = icmp eq i32 [[SEL_1]], 50
85 ; CHECK-NEXT: [[C_4:%.*]] = icmp slt i32 [[SEL_1]], 9
86 ; CHECK-NEXT: [[RES_1:%.*]] = add i1 [[C_1]], [[C_2]]
87 ; CHECK-NEXT: [[RES_2:%.*]] = add i1 [[RES_1]], [[C_3]]
88 ; CHECK-NEXT: [[RES_3:%.*]] = add i1 [[RES_2]], [[C_4]]
89 ; CHECK-NEXT: ret i1 [[RES_3]]
91 %sel.1 = select i1 %cmp, i32 %x, i32 %y
92 %c.1 = icmp sgt i32 %sel.1, 300
93 %c.2 = icmp sgt i32 %sel.1, 100
94 %c.3 = icmp eq i32 %sel.1, 50
95 %c.4 = icmp slt i32 %sel.1, 9
96 %res.1 = add i1 %c.1, %c.2
97 %res.2 = add i1 %res.1, %c.3
98 %res.3 = add i1 %res.2, %c.4
102 define i1 @caller2(i32 %y, i1 %cmp) {
103 ; CHECK-LABEL: define {{[^@]+}}@caller2
104 ; CHECK-SAME: (i32 [[Y:%.*]], i1 [[CMP:%.*]]) {
105 ; CHECK-NEXT: [[CALL_1:%.*]] = tail call i1 @f2(i32 10, i32 [[Y]], i1 [[CMP]])
106 ; CHECK-NEXT: [[CALL_2:%.*]] = tail call i1 @f2(i32 20, i32 [[Y]], i1 [[CMP]])
107 ; CHECK-NEXT: [[RES:%.*]] = and i1 [[CALL_1]], [[CALL_2]]
108 ; CHECK-NEXT: ret i1 [[RES]]
110 %call.1 = tail call i1 @f2(i32 10, i32 %y, i1 %cmp)
111 %call.2 = tail call i1 @f2(i32 20, i32 %y, i1 %cmp)
112 %res = and i1 %call.1, %call.2
116 define i32 @f3_constantexpr_cond(i32 %x, i32 %y) {
117 ; CHECK-LABEL: define {{[^@]+}}@f3_constantexpr_cond
118 ; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
119 ; CHECK-NEXT: [[SEL_1:%.*]] = select i1 ptrtoint (ptr @f3_constantexpr_cond to i1), i32 [[X]], i32 [[Y]]
120 ; CHECK-NEXT: ret i32 [[SEL_1]]
122 %sel.1 = select i1 ptrtoint (ptr @f3_constantexpr_cond to i1), i32 %x, i32 %y
126 define i32 @caller3(i32 %y) {
127 ; CHECK-LABEL: define {{[^@]+}}@caller3
128 ; CHECK-SAME: (i32 [[Y:%.*]]) {
129 ; CHECK-NEXT: [[CALL_1:%.*]] = tail call i32 @f3_constantexpr_cond(i32 10, i32 [[Y]])
130 ; CHECK-NEXT: [[CALL_2:%.*]] = tail call i32 @f3_constantexpr_cond(i32 20, i32 [[Y]])
131 ; CHECK-NEXT: [[RES:%.*]] = and i32 [[CALL_1]], [[CALL_2]]
132 ; CHECK-NEXT: ret i32 [[RES]]
134 %call.1 = tail call i32 @f3_constantexpr_cond(i32 10, i32 %y)
135 %call.2 = tail call i32 @f3_constantexpr_cond(i32 20, i32 %y)
136 %res = and i32 %call.1, %call.2