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 -funcspec-for-literal-constant=false -S < %s | FileCheck %s 3 4define i64 @main(i64 %x, i64 %y, i1 %flag) { 5entry: 6 br i1 %flag, label %plus, label %minus 7 8plus: 9 %cmp0 = call i64 @compute(i64 %x, i64 %y, ptr @plus, ptr @minus) 10 br label %merge 11 12minus: 13 %cmp1 = call i64 @compute(i64 %x, i64 %y, ptr @minus, ptr @plus) 14 br label %merge 15 16merge: 17 %ph = phi i64 [ %cmp0, %plus ], [ %cmp1, %minus] 18 %cmp2 = call i64 @compute(i64 %ph, i64 42, ptr @plus, ptr @minus) 19 ret i64 %cmp2 20} 21 22define internal i64 @compute(i64 %x, i64 %y, ptr %binop1, ptr %binop2) { 23entry: 24 %op0 = call i64 %binop1(i64 %x, i64 %y) 25 %op1 = call i64 %binop2(i64 %x, i64 %y) 26 %op2 = call i64 @compute(i64 %x, i64 %y, ptr %binop1, ptr @plus) 27 %add0 = add i64 %op0, %op1 28 %add1 = add i64 %add0, %op2 29 %div = sdiv i64 %add1, %x 30 %sub = sub i64 %div, %y 31 %mul = mul i64 %sub, 2 32 ret i64 %mul 33} 34 35define internal i64 @plus(i64 %x, i64 %y) { 36entry: 37 %add = add i64 %x, %y 38 ret i64 %add 39} 40 41define internal i64 @minus(i64 %x, i64 %y) { 42entry: 43 %sub = sub i64 %x, %y 44 ret i64 %sub 45} 46 47 48 49; CHECK-LABEL: define i64 @main( 50; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]], i1 [[FLAG:%.*]]) { 51; CHECK-NEXT: [[ENTRY:.*:]] 52; CHECK-NEXT: br i1 [[FLAG]], label %[[PLUS:.*]], label %[[MINUS:.*]] 53; CHECK: [[PLUS]]: 54; CHECK-NEXT: [[CMP0:%.*]] = call i64 @compute.specialized.2(i64 [[X]], i64 [[Y]], ptr @plus, ptr @minus) 55; CHECK-NEXT: br label %[[MERGE:.*]] 56; CHECK: [[MINUS]]: 57; CHECK-NEXT: [[CMP1:%.*]] = call i64 @compute.specialized.3(i64 [[X]], i64 [[Y]], ptr @minus, ptr @plus) 58; CHECK-NEXT: br label %[[MERGE]] 59; CHECK: [[MERGE]]: 60; CHECK-NEXT: [[PH:%.*]] = phi i64 [ [[CMP0]], %[[PLUS]] ], [ [[CMP1]], %[[MINUS]] ] 61; CHECK-NEXT: [[CMP2:%.*]] = call i64 @compute.specialized.2(i64 [[PH]], i64 42, ptr @plus, ptr @minus) 62; CHECK-NEXT: ret i64 [[CMP2]] 63; 64; 65; CHECK-LABEL: define internal i64 @plus( 66; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) { 67; CHECK-NEXT: [[ENTRY:.*:]] 68; CHECK-NEXT: [[ADD:%.*]] = add i64 [[X]], [[Y]] 69; CHECK-NEXT: ret i64 [[ADD]] 70; 71; 72; CHECK-LABEL: define internal i64 @minus( 73; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) { 74; CHECK-NEXT: [[ENTRY:.*:]] 75; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[X]], [[Y]] 76; CHECK-NEXT: ret i64 [[SUB]] 77; 78; 79; CHECK-LABEL: define internal i64 @compute.specialized.1( 80; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]], ptr [[BINOP1:%.*]], ptr [[BINOP2:%.*]]) { 81; CHECK-NEXT: [[ENTRY:.*:]] 82; CHECK-NEXT: [[OP1:%.*]] = call i64 [[BINOP1]](i64 [[X]], i64 [[Y]]) 83; CHECK-NEXT: [[OP0:%.*]] = call i64 @plus(i64 [[X]], i64 [[Y]]) 84; CHECK-NEXT: [[OP2:%.*]] = call i64 @compute.specialized.1(i64 [[X]], i64 [[Y]], ptr [[BINOP1]], ptr @plus) 85; CHECK-NEXT: [[ADD0:%.*]] = add i64 [[OP1]], [[OP0]] 86; CHECK-NEXT: [[ADD1:%.*]] = add i64 [[ADD0]], [[OP2]] 87; CHECK-NEXT: [[DIV:%.*]] = sdiv i64 [[ADD1]], [[X]] 88; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[DIV]], [[Y]] 89; CHECK-NEXT: [[MUL:%.*]] = mul i64 [[SUB]], 2 90; CHECK-NEXT: ret i64 [[MUL]] 91; 92; 93; CHECK-LABEL: define internal i64 @compute.specialized.2( 94; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]], ptr [[BINOP1:%.*]], ptr [[BINOP2:%.*]]) { 95; CHECK-NEXT: [[ENTRY:.*:]] 96; CHECK-NEXT: [[OP0:%.*]] = call i64 @plus(i64 [[X]], i64 [[Y]]) 97; CHECK-NEXT: [[OP1:%.*]] = call i64 @minus(i64 [[X]], i64 [[Y]]) 98; CHECK-NEXT: [[OP2:%.*]] = call i64 @compute.specialized.1(i64 [[X]], i64 [[Y]], ptr @plus, ptr @plus) 99; CHECK-NEXT: [[ADD0:%.*]] = add i64 [[OP0]], [[OP1]] 100; CHECK-NEXT: [[ADD1:%.*]] = add i64 [[ADD0]], [[OP2]] 101; CHECK-NEXT: [[DIV:%.*]] = sdiv i64 [[ADD1]], [[X]] 102; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[DIV]], [[Y]] 103; CHECK-NEXT: [[MUL:%.*]] = mul i64 [[SUB]], 2 104; CHECK-NEXT: ret i64 [[MUL]] 105; 106; 107; CHECK-LABEL: define internal i64 @compute.specialized.3( 108; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]], ptr [[BINOP1:%.*]], ptr [[BINOP2:%.*]]) { 109; CHECK-NEXT: [[ENTRY:.*:]] 110; CHECK-NEXT: [[OP0:%.*]] = call i64 @minus(i64 [[X]], i64 [[Y]]) 111; CHECK-NEXT: [[OP1:%.*]] = call i64 @plus(i64 [[X]], i64 [[Y]]) 112; CHECK-NEXT: [[OP2:%.*]] = call i64 @compute.specialized.3(i64 [[X]], i64 [[Y]], ptr @minus, ptr @plus) 113; CHECK-NEXT: [[ADD0:%.*]] = add i64 [[OP0]], [[OP1]] 114; CHECK-NEXT: [[ADD1:%.*]] = add i64 [[ADD0]], [[OP2]] 115; CHECK-NEXT: [[DIV:%.*]] = sdiv i64 [[ADD1]], [[X]] 116; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[DIV]], [[Y]] 117; CHECK-NEXT: [[MUL:%.*]] = mul i64 [[SUB]], 2 118; CHECK-NEXT: ret i64 [[MUL]] 119; 120