; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs --version 5 ; RUN: opt -passes="ipsccp" -force-specialization \ ; RUN: -funcspec-max-iters=3 -S < %s | FileCheck %s ; RUN: opt -passes="ipsccp" -force-specialization \ ; RUN: -funcspec-for-literal-constant=false -funcspec-max-iters=3 \ ; RUN: -S < %s | FileCheck %s --check-prefix=NOLIT @global_true = constant i1 true @global_false = constant i1 false define i64 @main() { entry: %op1 = call ptr @select_op(ptr @global_true) %op2 = call ptr @select_op(ptr @global_false) %c1 = call i64 @compute(ptr %op1) %c2 = call i64 @compute(ptr %op2) %add = add i64 %c1, %c2 ret i64 %add } define ptr @select_op(ptr %flag) { %flag.val = load i1, ptr %flag %op = select i1 %flag.val, ptr @plus, ptr @minus ret ptr %op } define internal i64 @compute(ptr %op) { entry: %res = call i64 %op(i64 1) ret i64 %res } define internal i64 @plus(i64 %x) { entry: %sum = add i64 %x, 1 ret i64 %sum } define internal i64 @minus(i64 %x) { entry: %diff = sub i64 %x, 1 ret i64 %diff } ; CHECK-LABEL: define i64 @main() { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: [[OP1:%.*]] = call ptr @select_op.specialized.1(ptr @global_true) ; CHECK-NEXT: [[OP2:%.*]] = call ptr @select_op.specialized.2(ptr @global_false) ; CHECK-NEXT: [[C1:%.*]] = call i64 @compute.specialized.3(ptr @plus) ; CHECK-NEXT: [[C2:%.*]] = call i64 @compute.specialized.4(ptr @minus) ; CHECK-NEXT: [[ADD:%.*]] = add i64 [[C1]], [[C2]] ; CHECK-NEXT: ret i64 [[ADD]] ; ; ; CHECK-LABEL: define ptr @select_op( ; CHECK-SAME: ptr [[FLAG:%.*]]) { ; CHECK-NEXT: [[FLAG_VAL:%.*]] = load i1, ptr [[FLAG]], align 1 ; CHECK-NEXT: [[OP:%.*]] = select i1 [[FLAG_VAL]], ptr @plus, ptr @minus ; CHECK-NEXT: ret ptr [[OP]] ; ; ; CHECK-LABEL: define internal i64 @plus( ; CHECK-SAME: i64 [[X:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: [[SUM:%.*]] = add i64 [[X]], 1 ; CHECK-NEXT: ret i64 [[SUM]] ; ; ; CHECK-LABEL: define internal i64 @minus( ; CHECK-SAME: i64 [[X:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[X]], 1 ; CHECK-NEXT: ret i64 [[DIFF]] ; ; ; CHECK-LABEL: define internal ptr @select_op.specialized.1( ; CHECK-SAME: ptr [[FLAG:%.*]]) { ; CHECK-NEXT: ret ptr poison ; ; ; CHECK-LABEL: define internal ptr @select_op.specialized.2( ; CHECK-SAME: ptr [[FLAG:%.*]]) { ; CHECK-NEXT: ret ptr poison ; ; ; CHECK-LABEL: define internal i64 @compute.specialized.3( ; CHECK-SAME: ptr [[OP:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: [[RES:%.*]] = call i64 @plus(i64 1) ; CHECK-NEXT: ret i64 [[RES]] ; ; ; CHECK-LABEL: define internal i64 @compute.specialized.4( ; CHECK-SAME: ptr [[OP:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: [[RES:%.*]] = call i64 @minus(i64 1) ; CHECK-NEXT: ret i64 [[RES]] ; ; ; NOLIT-LABEL: define i64 @main() { ; NOLIT-NEXT: [[ENTRY:.*:]] ; NOLIT-NEXT: [[OP1:%.*]] = call ptr @select_op.specialized.1(ptr @global_true) ; NOLIT-NEXT: [[OP2:%.*]] = call ptr @select_op.specialized.2(ptr @global_false) ; NOLIT-NEXT: [[C1:%.*]] = call i64 @compute(ptr @plus) ; NOLIT-NEXT: [[C2:%.*]] = call i64 @compute(ptr @minus) ; NOLIT-NEXT: [[ADD:%.*]] = add i64 [[C1]], [[C2]] ; NOLIT-NEXT: ret i64 [[ADD]] ; ; ; NOLIT-LABEL: define ptr @select_op( ; NOLIT-SAME: ptr [[FLAG:%.*]]) { ; NOLIT-NEXT: [[FLAG_VAL:%.*]] = load i1, ptr [[FLAG]], align 1 ; NOLIT-NEXT: [[OP:%.*]] = select i1 [[FLAG_VAL]], ptr @plus, ptr @minus ; NOLIT-NEXT: ret ptr [[OP]] ; ; ; NOLIT-LABEL: define internal i64 @compute( ; NOLIT-SAME: ptr [[OP:%.*]]) { ; NOLIT-NEXT: [[ENTRY:.*:]] ; NOLIT-NEXT: [[RES:%.*]] = call i64 [[OP]](i64 1) ; NOLIT-NEXT: ret i64 [[RES]] ; ; ; NOLIT-LABEL: define internal i64 @plus( ; NOLIT-SAME: i64 [[X:%.*]]) { ; NOLIT-NEXT: [[ENTRY:.*:]] ; NOLIT-NEXT: [[SUM:%.*]] = add i64 [[X]], 1 ; NOLIT-NEXT: ret i64 [[SUM]] ; ; ; NOLIT-LABEL: define internal i64 @minus( ; NOLIT-SAME: i64 [[X:%.*]]) { ; NOLIT-NEXT: [[ENTRY:.*:]] ; NOLIT-NEXT: [[DIFF:%.*]] = sub i64 [[X]], 1 ; NOLIT-NEXT: ret i64 [[DIFF]] ; ; ; NOLIT-LABEL: define internal ptr @select_op.specialized.1( ; NOLIT-SAME: ptr [[FLAG:%.*]]) { ; NOLIT-NEXT: ret ptr poison ; ; ; NOLIT-LABEL: define internal ptr @select_op.specialized.2( ; NOLIT-SAME: ptr [[FLAG:%.*]]) { ; NOLIT-NEXT: ret ptr poison ;