; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt %s -passes=ipsccp -S | FileCheck %s declare i1 @cond() declare void @use(i1) define internal {i64, i64} @struct1() { ; CHECK-LABEL: @struct1( ; CHECK-NEXT: [[C:%.*]] = call i1 @cond() ; CHECK-NEXT: br i1 [[C]], label [[TRUE:%.*]], label [[FALSE:%.*]] ; CHECK: true: ; CHECK-NEXT: br label [[EXIT:%.*]] ; CHECK: false: ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: [[R:%.*]] = phi { i64, i64 } [ { i64 20, i64 200 }, [[TRUE]] ], [ { i64 30, i64 300 }, [[FALSE]] ] ; CHECK-NEXT: ret { i64, i64 } [[R]] ; %c = call i1 @cond() br i1 %c, label %true, label %false true: %s.1 = insertvalue {i64, i64} undef, i64 20, 0 %s.2 = insertvalue {i64, i64} %s.1, i64 200, 1 br label %exit false: %s.3 = insertvalue {i64, i64} undef, i64 30, 0 %s.4 = insertvalue {i64, i64} %s.3, i64 300, 1 br label %exit exit: %r = phi {i64, i64} [ %s.2, %true], [ %s.4, %false ] ret {i64, i64} %r } define void @struct1_caller() { ; CHECK-LABEL: @struct1_caller( ; CHECK-NEXT: [[S:%.*]] = call { i64, i64 } @struct1() ; CHECK-NEXT: [[V1:%.*]] = extractvalue { i64, i64 } [[S]], 0 ; CHECK-NEXT: [[V2:%.*]] = extractvalue { i64, i64 } [[S]], 1 ; CHECK-NEXT: [[T_1:%.*]] = icmp ne i64 [[V1]], 10 ; CHECK-NEXT: call void @use(i1 [[T_1]]) ; CHECK-NEXT: [[T_2:%.*]] = icmp ult i64 [[V1]], 100 ; CHECK-NEXT: call void @use(i1 [[T_2]]) ; CHECK-NEXT: [[T_3:%.*]] = icmp ne i64 [[V2]], 0 ; CHECK-NEXT: call void @use(i1 [[T_3]]) ; CHECK-NEXT: [[T_4:%.*]] = icmp ult i64 [[V2]], 301 ; CHECK-NEXT: call void @use(i1 [[T_4]]) ; CHECK-NEXT: ret void ; %s = call {i64, i64} @struct1() %v1 = extractvalue {i64, i64} %s, 0 %v2 = extractvalue {i64, i64} %s, 1 %t.1 = icmp ne i64 %v1, 10 call void @use(i1 %t.1) %t.2 = icmp ult i64 %v1, 100 call void @use(i1 %t.2) %t.3 = icmp ne i64 %v2, 0 call void @use(i1 %t.3) %t.4 = icmp ult i64 %v2, 301 call void @use(i1 %t.4) ret void } define internal {i64, i64} @struct2() { ; CHECK-LABEL: @struct2( ; CHECK-NEXT: [[C:%.*]] = call i1 @cond() ; CHECK-NEXT: br i1 [[C]], label [[TRUE:%.*]], label [[FALSE:%.*]] ; CHECK: true: ; CHECK-NEXT: br label [[EXIT:%.*]] ; CHECK: false: ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: [[V1:%.*]] = phi i64 [ 20, [[TRUE]] ], [ 30, [[FALSE]] ] ; CHECK-NEXT: [[V2:%.*]] = phi i64 [ 200, [[TRUE]] ], [ 300, [[FALSE]] ] ; CHECK-NEXT: [[S_1:%.*]] = insertvalue { i64, i64 } undef, i64 [[V1]], 0 ; CHECK-NEXT: [[S_2:%.*]] = insertvalue { i64, i64 } [[S_1]], i64 [[V2]], 1 ; CHECK-NEXT: ret { i64, i64 } [[S_2]] ; %c = call i1 @cond() br i1 %c, label %true, label %false true: br label %exit false: br label %exit exit: %v1 = phi i64 [ 20, %true ], [ 30, %false ] %v2 = phi i64 [ 200, %true ], [ 300, %false ] %s.1 = insertvalue {i64, i64} undef, i64 %v1, 0 %s.2 = insertvalue {i64, i64} %s.1, i64 %v2, 1 ret {i64, i64} %s.2 } define void @struct2_caller() { ; CHECK-LABEL: @struct2_caller( ; CHECK-NEXT: [[S:%.*]] = call { i64, i64 } @struct2() ; CHECK-NEXT: [[V1:%.*]] = extractvalue { i64, i64 } [[S]], 0 ; CHECK-NEXT: [[V2:%.*]] = extractvalue { i64, i64 } [[S]], 1 ; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: [[C_1:%.*]] = icmp eq i64 [[V1]], 25 ; CHECK-NEXT: call void @use(i1 [[C_1]]) ; CHECK-NEXT: [[C_2:%.*]] = icmp ult i64 [[V1]], 25 ; CHECK-NEXT: call void @use(i1 [[C_2]]) ; CHECK-NEXT: [[C_3:%.*]] = icmp eq i64 [[V2]], 250 ; CHECK-NEXT: call void @use(i1 [[C_3]]) ; CHECK-NEXT: [[C_4:%.*]] = icmp ugt i64 [[V2]], 250 ; CHECK-NEXT: call void @use(i1 [[C_4]]) ; CHECK-NEXT: ret void ; %s = call {i64, i64} @struct2() %v1 = extractvalue {i64, i64} %s, 0 %v2 = extractvalue {i64, i64} %s, 1 %t.1 = icmp ne i64 %v1, 10 call void @use(i1 %t.1) %t.2 = icmp ult i64 %v1, 100 call void @use(i1 %t.2) %t.3 = icmp ne i64 %v2, 0 call void @use(i1 %t.3) %t.4 = icmp ult i64 %v2, 301 call void @use(i1 %t.4) %f.1 = icmp eq i64 %v1, 10 call void @use(i1 %f.1) %f.2 = icmp ult i64 %v1, 19 call void @use(i1 %f.2) %f.3 = icmp eq i64 %v2, 50 call void @use(i1 %f.3) %f.4 = icmp ugt i64 %v2, 301 call void @use(i1 %f.4) %c.1 = icmp eq i64 %v1, 25 call void @use(i1 %c.1) %c.2 = icmp ult i64 %v1, 25 call void @use(i1 %c.2) %c.3 = icmp eq i64 %v2, 250 call void @use(i1 %c.3) %c.4 = icmp ugt i64 %v2, 250 call void @use(i1 %c.4) ret void }