1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt %s -passes=ipsccp -S | FileCheck %s
7 define internal {i64, i64} @struct1() {
8 ; CHECK-LABEL: @struct1(
9 ; CHECK-NEXT: [[C:%.*]] = call i1 @cond()
10 ; CHECK-NEXT: br i1 [[C]], label [[TRUE:%.*]], label [[FALSE:%.*]]
12 ; CHECK-NEXT: br label [[EXIT:%.*]]
14 ; CHECK-NEXT: br label [[EXIT]]
16 ; CHECK-NEXT: [[R:%.*]] = phi { i64, i64 } [ { i64 20, i64 200 }, [[TRUE]] ], [ { i64 30, i64 300 }, [[FALSE]] ]
17 ; CHECK-NEXT: ret { i64, i64 } [[R]]
20 br i1 %c, label %true, label %false
23 %s.1 = insertvalue {i64, i64} undef, i64 20, 0
24 %s.2 = insertvalue {i64, i64} %s.1, i64 200, 1
28 %s.3 = insertvalue {i64, i64} undef, i64 30, 0
29 %s.4 = insertvalue {i64, i64} %s.3, i64 300, 1
33 %r = phi {i64, i64} [ %s.2, %true], [ %s.4, %false ]
37 define void @struct1_caller() {
38 ; CHECK-LABEL: @struct1_caller(
39 ; CHECK-NEXT: [[S:%.*]] = call { i64, i64 } @struct1()
40 ; CHECK-NEXT: [[V1:%.*]] = extractvalue { i64, i64 } [[S]], 0
41 ; CHECK-NEXT: [[V2:%.*]] = extractvalue { i64, i64 } [[S]], 1
42 ; CHECK-NEXT: [[T_1:%.*]] = icmp ne i64 [[V1]], 10
43 ; CHECK-NEXT: call void @use(i1 [[T_1]])
44 ; CHECK-NEXT: [[T_2:%.*]] = icmp ult i64 [[V1]], 100
45 ; CHECK-NEXT: call void @use(i1 [[T_2]])
46 ; CHECK-NEXT: [[T_3:%.*]] = icmp ne i64 [[V2]], 0
47 ; CHECK-NEXT: call void @use(i1 [[T_3]])
48 ; CHECK-NEXT: [[T_4:%.*]] = icmp ult i64 [[V2]], 301
49 ; CHECK-NEXT: call void @use(i1 [[T_4]])
50 ; CHECK-NEXT: ret void
52 %s = call {i64, i64} @struct1()
53 %v1 = extractvalue {i64, i64} %s, 0
54 %v2 = extractvalue {i64, i64} %s, 1
56 %t.1 = icmp ne i64 %v1, 10
57 call void @use(i1 %t.1)
58 %t.2 = icmp ult i64 %v1, 100
59 call void @use(i1 %t.2)
60 %t.3 = icmp ne i64 %v2, 0
61 call void @use(i1 %t.3)
62 %t.4 = icmp ult i64 %v2, 301
63 call void @use(i1 %t.4)
68 define internal {i64, i64} @struct2() {
69 ; CHECK-LABEL: @struct2(
70 ; CHECK-NEXT: [[C:%.*]] = call i1 @cond()
71 ; CHECK-NEXT: br i1 [[C]], label [[TRUE:%.*]], label [[FALSE:%.*]]
73 ; CHECK-NEXT: br label [[EXIT:%.*]]
75 ; CHECK-NEXT: br label [[EXIT]]
77 ; CHECK-NEXT: [[V1:%.*]] = phi i64 [ 20, [[TRUE]] ], [ 30, [[FALSE]] ]
78 ; CHECK-NEXT: [[V2:%.*]] = phi i64 [ 200, [[TRUE]] ], [ 300, [[FALSE]] ]
79 ; CHECK-NEXT: [[S_1:%.*]] = insertvalue { i64, i64 } undef, i64 [[V1]], 0
80 ; CHECK-NEXT: [[S_2:%.*]] = insertvalue { i64, i64 } [[S_1]], i64 [[V2]], 1
81 ; CHECK-NEXT: ret { i64, i64 } [[S_2]]
84 br i1 %c, label %true, label %false
93 %v1 = phi i64 [ 20, %true ], [ 30, %false ]
94 %v2 = phi i64 [ 200, %true ], [ 300, %false ]
95 %s.1 = insertvalue {i64, i64} undef, i64 %v1, 0
96 %s.2 = insertvalue {i64, i64} %s.1, i64 %v2, 1
100 define void @struct2_caller() {
101 ; CHECK-LABEL: @struct2_caller(
102 ; CHECK-NEXT: [[S:%.*]] = call { i64, i64 } @struct2()
103 ; CHECK-NEXT: [[V1:%.*]] = extractvalue { i64, i64 } [[S]], 0
104 ; CHECK-NEXT: [[V2:%.*]] = extractvalue { i64, i64 } [[S]], 1
105 ; CHECK-NEXT: call void @use(i1 true)
106 ; CHECK-NEXT: call void @use(i1 true)
107 ; CHECK-NEXT: call void @use(i1 true)
108 ; CHECK-NEXT: call void @use(i1 true)
109 ; CHECK-NEXT: call void @use(i1 false)
110 ; CHECK-NEXT: call void @use(i1 false)
111 ; CHECK-NEXT: call void @use(i1 false)
112 ; CHECK-NEXT: call void @use(i1 false)
113 ; CHECK-NEXT: [[C_1:%.*]] = icmp eq i64 [[V1]], 25
114 ; CHECK-NEXT: call void @use(i1 [[C_1]])
115 ; CHECK-NEXT: [[C_2:%.*]] = icmp ult i64 [[V1]], 25
116 ; CHECK-NEXT: call void @use(i1 [[C_2]])
117 ; CHECK-NEXT: [[C_3:%.*]] = icmp eq i64 [[V2]], 250
118 ; CHECK-NEXT: call void @use(i1 [[C_3]])
119 ; CHECK-NEXT: [[C_4:%.*]] = icmp ugt i64 [[V2]], 250
120 ; CHECK-NEXT: call void @use(i1 [[C_4]])
121 ; CHECK-NEXT: ret void
123 %s = call {i64, i64} @struct2()
124 %v1 = extractvalue {i64, i64} %s, 0
125 %v2 = extractvalue {i64, i64} %s, 1
127 %t.1 = icmp ne i64 %v1, 10
128 call void @use(i1 %t.1)
129 %t.2 = icmp ult i64 %v1, 100
130 call void @use(i1 %t.2)
131 %t.3 = icmp ne i64 %v2, 0
132 call void @use(i1 %t.3)
133 %t.4 = icmp ult i64 %v2, 301
134 call void @use(i1 %t.4)
136 %f.1 = icmp eq i64 %v1, 10
137 call void @use(i1 %f.1)
138 %f.2 = icmp ult i64 %v1, 19
139 call void @use(i1 %f.2)
140 %f.3 = icmp eq i64 %v2, 50
141 call void @use(i1 %f.3)
142 %f.4 = icmp ugt i64 %v2, 301
143 call void @use(i1 %f.4)
145 %c.1 = icmp eq i64 %v1, 25
146 call void @use(i1 %c.1)
147 %c.2 = icmp ult i64 %v1, 25
148 call void @use(i1 %c.2)
149 %c.3 = icmp eq i64 %v2, 250
150 call void @use(i1 %c.3)
151 %c.4 = icmp ugt i64 %v2, 250
152 call void @use(i1 %c.4)