1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs --version 5 2; RUN: opt -passes="ipsccp<func-spec>" -force-specialization \ 3; RUN: -funcspec-max-iters=3 -S < %s | FileCheck %s 4 5; RUN: opt -passes="ipsccp<func-spec>" -force-specialization \ 6; RUN: -funcspec-for-literal-constant=false -funcspec-max-iters=3 \ 7; RUN: -S < %s | FileCheck %s --check-prefix=NOLIT 8 9@global_true = constant i1 true 10@global_false = constant i1 false 11 12define i64 @main() { 13entry: 14 %op1 = call ptr @select_op(ptr @global_true) 15 %op2 = call ptr @select_op(ptr @global_false) 16 17 %c1 = call i64 @compute(ptr %op1) 18 %c2 = call i64 @compute(ptr %op2) 19 %add = add i64 %c1, %c2 20 ret i64 %add 21} 22 23define ptr @select_op(ptr %flag) { 24 %flag.val = load i1, ptr %flag 25 %op = select i1 %flag.val, ptr @plus, ptr @minus 26 ret ptr %op 27} 28 29define internal i64 @compute(ptr %op) { 30entry: 31 %res = call i64 %op(i64 1) 32 ret i64 %res 33} 34 35define internal i64 @plus(i64 %x) { 36entry: 37 %sum = add i64 %x, 1 38 ret i64 %sum 39} 40 41define internal i64 @minus(i64 %x) { 42entry: 43 %diff = sub i64 %x, 1 44 ret i64 %diff 45} 46; CHECK-LABEL: define i64 @main() { 47; CHECK-NEXT: [[ENTRY:.*:]] 48; CHECK-NEXT: [[OP1:%.*]] = call ptr @select_op.specialized.1(ptr @global_true) 49; CHECK-NEXT: [[OP2:%.*]] = call ptr @select_op.specialized.2(ptr @global_false) 50; CHECK-NEXT: [[C1:%.*]] = call i64 @compute.specialized.3(ptr @plus) 51; CHECK-NEXT: [[C2:%.*]] = call i64 @compute.specialized.4(ptr @minus) 52; CHECK-NEXT: [[ADD:%.*]] = add i64 [[C1]], [[C2]] 53; CHECK-NEXT: ret i64 [[ADD]] 54; 55; 56; CHECK-LABEL: define ptr @select_op( 57; CHECK-SAME: ptr [[FLAG:%.*]]) { 58; CHECK-NEXT: [[FLAG_VAL:%.*]] = load i1, ptr [[FLAG]], align 1 59; CHECK-NEXT: [[OP:%.*]] = select i1 [[FLAG_VAL]], ptr @plus, ptr @minus 60; CHECK-NEXT: ret ptr [[OP]] 61; 62; 63; CHECK-LABEL: define internal i64 @plus( 64; CHECK-SAME: i64 [[X:%.*]]) { 65; CHECK-NEXT: [[ENTRY:.*:]] 66; CHECK-NEXT: [[SUM:%.*]] = add i64 [[X]], 1 67; CHECK-NEXT: ret i64 [[SUM]] 68; 69; 70; CHECK-LABEL: define internal i64 @minus( 71; CHECK-SAME: i64 [[X:%.*]]) { 72; CHECK-NEXT: [[ENTRY:.*:]] 73; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[X]], 1 74; CHECK-NEXT: ret i64 [[DIFF]] 75; 76; 77; CHECK-LABEL: define internal ptr @select_op.specialized.1( 78; CHECK-SAME: ptr [[FLAG:%.*]]) { 79; CHECK-NEXT: ret ptr poison 80; 81; 82; CHECK-LABEL: define internal ptr @select_op.specialized.2( 83; CHECK-SAME: ptr [[FLAG:%.*]]) { 84; CHECK-NEXT: ret ptr poison 85; 86; 87; CHECK-LABEL: define internal i64 @compute.specialized.3( 88; CHECK-SAME: ptr [[OP:%.*]]) { 89; CHECK-NEXT: [[ENTRY:.*:]] 90; CHECK-NEXT: [[RES:%.*]] = call i64 @plus(i64 1) 91; CHECK-NEXT: ret i64 [[RES]] 92; 93; 94; CHECK-LABEL: define internal i64 @compute.specialized.4( 95; CHECK-SAME: ptr [[OP:%.*]]) { 96; CHECK-NEXT: [[ENTRY:.*:]] 97; CHECK-NEXT: [[RES:%.*]] = call i64 @minus(i64 1) 98; CHECK-NEXT: ret i64 [[RES]] 99; 100; 101; NOLIT-LABEL: define i64 @main() { 102; NOLIT-NEXT: [[ENTRY:.*:]] 103; NOLIT-NEXT: [[OP1:%.*]] = call ptr @select_op.specialized.1(ptr @global_true) 104; NOLIT-NEXT: [[OP2:%.*]] = call ptr @select_op.specialized.2(ptr @global_false) 105; NOLIT-NEXT: [[C1:%.*]] = call i64 @compute(ptr @plus) 106; NOLIT-NEXT: [[C2:%.*]] = call i64 @compute(ptr @minus) 107; NOLIT-NEXT: [[ADD:%.*]] = add i64 [[C1]], [[C2]] 108; NOLIT-NEXT: ret i64 [[ADD]] 109; 110; 111; NOLIT-LABEL: define ptr @select_op( 112; NOLIT-SAME: ptr [[FLAG:%.*]]) { 113; NOLIT-NEXT: [[FLAG_VAL:%.*]] = load i1, ptr [[FLAG]], align 1 114; NOLIT-NEXT: [[OP:%.*]] = select i1 [[FLAG_VAL]], ptr @plus, ptr @minus 115; NOLIT-NEXT: ret ptr [[OP]] 116; 117; 118; NOLIT-LABEL: define internal i64 @compute( 119; NOLIT-SAME: ptr [[OP:%.*]]) { 120; NOLIT-NEXT: [[ENTRY:.*:]] 121; NOLIT-NEXT: [[RES:%.*]] = call i64 [[OP]](i64 1) 122; NOLIT-NEXT: ret i64 [[RES]] 123; 124; 125; NOLIT-LABEL: define internal i64 @plus( 126; NOLIT-SAME: i64 [[X:%.*]]) { 127; NOLIT-NEXT: [[ENTRY:.*:]] 128; NOLIT-NEXT: [[SUM:%.*]] = add i64 [[X]], 1 129; NOLIT-NEXT: ret i64 [[SUM]] 130; 131; 132; NOLIT-LABEL: define internal i64 @minus( 133; NOLIT-SAME: i64 [[X:%.*]]) { 134; NOLIT-NEXT: [[ENTRY:.*:]] 135; NOLIT-NEXT: [[DIFF:%.*]] = sub i64 [[X]], 1 136; NOLIT-NEXT: ret i64 [[DIFF]] 137; 138; 139; NOLIT-LABEL: define internal ptr @select_op.specialized.1( 140; NOLIT-SAME: ptr [[FLAG:%.*]]) { 141; NOLIT-NEXT: ret ptr poison 142; 143; 144; NOLIT-LABEL: define internal ptr @select_op.specialized.2( 145; NOLIT-SAME: ptr [[FLAG:%.*]]) { 146; NOLIT-NEXT: ret ptr poison 147; 148