; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -passes=attributor -attributor-disable=false -S < %s | FileCheck %s define i32 @test0(i32* %p) { ; CHECK-LABEL: define {{[^@]+}}@test0 ; CHECK-SAME: (i32* nocapture nofree nonnull readonly dereferenceable(4) [[P:%.*]]) ; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[P]], !range !0 ; CHECK-NEXT: ret i32 [[A]] ; %a = load i32, i32* %p, !range !0 ret i32 %a } define i32 @test0-range-check(i32* %p) { ; CHECK-LABEL: define {{[^@]+}}@test0-range-check ; CHECK-SAME: (i32* nocapture nofree readonly [[P:%.*]]) ; CHECK-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly [[P]]) ; CHECK-SAME: !range !0 ; CHECK-NEXT: ret i32 [[A]] ; %a = tail call i32 @test0(i32* %p) ret i32 %a } declare void @use3-dummy(i1, i1, i1) define void @use3(i1, i1, i1) { ; CHECK-LABEL: define {{[^@]+}}@use3 ; CHECK-SAME: (i1 [[TMP0:%.*]], i1 [[TMP1:%.*]], i1 [[TMP2:%.*]]) ; CHECK-NEXT: tail call void @use3-dummy(i1 [[TMP0]], i1 [[TMP1]], i1 [[TMP2]]) ; CHECK-NEXT: ret void ; tail call void @use3-dummy(i1 %0, i1 %1, i1 %2) ret void } ; TEST0 icmp test define void @test0-icmp-check(i32* %p){ ; CHECK-LABEL: define {{[^@]+}}@test0-icmp-check ; CHECK-SAME: (i32* nocapture nofree readonly [[P:%.*]]) ; CHECK-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly [[P]]) ; CHECK-SAME: !range !0 ; CHECK-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9 ; CHECK-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8 ; CHECK-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1 ; CHECK-NEXT: [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0 ; CHECK-NEXT: tail call void @use3(i1 false, i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]]) ; CHECK-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 false) ; CHECK-NEXT: [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9 ; CHECK-NEXT: [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8 ; CHECK-NEXT: [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1 ; CHECK-NEXT: [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0 ; CHECK-NEXT: tail call void @use3(i1 true, i1 [[CMP_NE_2]], i1 [[CMP_NE_3]]) ; CHECK-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 true) ; CHECK-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8 ; CHECK-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1 ; CHECK-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0 ; CHECK-NEXT: tail call void @use3(i1 false, i1 false, i1 [[CMP_UGT_3]]) ; CHECK-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 false) ; CHECK-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9 ; CHECK-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8 ; CHECK-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1 ; CHECK-NEXT: tail call void @use3(i1 false, i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]]) ; CHECK-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 true, i1 false) ; CHECK-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8 ; CHECK-NEXT: [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1 ; CHECK-NEXT: [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0 ; CHECK-NEXT: tail call void @use3(i1 false, i1 false, i1 [[CMP_SGT_3]]) ; CHECK-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 true) ; CHECK-NEXT: [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9 ; CHECK-NEXT: [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8 ; CHECK-NEXT: [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1 ; CHECK-NEXT: tail call void @use3(i1 false, i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]]) ; CHECK-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 true, i1 true) ; CHECK-NEXT: [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9 ; CHECK-NEXT: [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8 ; CHECK-NEXT: [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1 ; CHECK-NEXT: tail call void @use3(i1 true, i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]]) ; CHECK-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 false, i1 false) ; CHECK-NEXT: [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8 ; CHECK-NEXT: [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1 ; CHECK-NEXT: [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0 ; CHECK-NEXT: tail call void @use3(i1 true, i1 true, i1 [[CMP_LTE_3]]) ; CHECK-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 false) ; CHECK-NEXT: ret void ; ; ret = [0, 10) %ret = tail call i32 @test0(i32 *%p) ; ret = [0, 10), eq %cmp-eq-1 = icmp eq i32 %ret, 10 %cmp-eq-2 = icmp eq i32 %ret, 9 %cmp-eq-3 = icmp eq i32 %ret, 8 %cmp-eq-4 = icmp eq i32 %ret, 1 %cmp-eq-5 = icmp eq i32 %ret, 0 %cmp-eq-6 = icmp eq i32 %ret, -1 tail call void @use3(i1 %cmp-eq-1, i1 %cmp-eq-2, i1 %cmp-eq-3) tail call void @use3(i1 %cmp-eq-4, i1 %cmp-eq-5, i1 %cmp-eq-6) ; ret = [0, 10), ne %cmp-ne-1 = icmp ne i32 %ret, 10 %cmp-ne-2 = icmp ne i32 %ret, 9 %cmp-ne-3 = icmp ne i32 %ret, 8 %cmp-ne-4 = icmp ne i32 %ret, 1 %cmp-ne-5 = icmp ne i32 %ret, 0 %cmp-ne-6 = icmp ne i32 %ret, -1 tail call void @use3(i1 %cmp-ne-1, i1 %cmp-ne-2, i1 %cmp-ne-3) tail call void @use3(i1 %cmp-ne-4, i1 %cmp-ne-5, i1 %cmp-ne-6) ; ret = [0, 10), ugt %cmp-ugt-1 = icmp ugt i32 %ret, 10 %cmp-ugt-2 = icmp ugt i32 %ret, 9 %cmp-ugt-3 = icmp ugt i32 %ret, 8 %cmp-ugt-4 = icmp ugt i32 %ret, 1 %cmp-ugt-5 = icmp ugt i32 %ret, 0 %cmp-ugt-6 = icmp ugt i32 %ret, -1 tail call void @use3(i1 %cmp-ugt-1, i1 %cmp-ugt-2, i1 %cmp-ugt-3) tail call void @use3(i1 %cmp-ugt-4, i1 %cmp-ugt-5, i1 %cmp-ugt-6) ; ret = [0, 10), uge %cmp-uge-1 = icmp uge i32 %ret, 10 %cmp-uge-2 = icmp uge i32 %ret, 9 %cmp-uge-3 = icmp uge i32 %ret, 8 %cmp-uge-4 = icmp uge i32 %ret, 1 %cmp-uge-5 = icmp uge i32 %ret, 0 %cmp-uge-6 = icmp uge i32 %ret, -1 tail call void @use3(i1 %cmp-uge-1, i1 %cmp-uge-2, i1 %cmp-uge-3) tail call void @use3(i1 %cmp-uge-4, i1 %cmp-uge-5, i1 %cmp-uge-6) ; ret = [0, 10), sgt %cmp-sgt-1 = icmp sgt i32 %ret, 10 %cmp-sgt-2 = icmp sgt i32 %ret, 9 %cmp-sgt-3 = icmp sgt i32 %ret, 8 %cmp-sgt-4 = icmp sgt i32 %ret, 1 %cmp-sgt-5 = icmp sgt i32 %ret, 0 %cmp-sgt-6 = icmp sgt i32 %ret, -1 tail call void @use3(i1 %cmp-sgt-1, i1 %cmp-sgt-2, i1 %cmp-sgt-3) tail call void @use3(i1 %cmp-sgt-4, i1 %cmp-sgt-5, i1 %cmp-sgt-6) ; ret = [0, 10), sge %cmp-gte-1 = icmp sge i32 %ret, 10 %cmp-gte-2 = icmp sge i32 %ret, 9 %cmp-gte-3 = icmp sge i32 %ret, 8 %cmp-gte-4 = icmp sge i32 %ret, 1 %cmp-gte-5 = icmp sge i32 %ret, 0 %cmp-gte-6 = icmp sge i32 %ret, -1 tail call void @use3(i1 %cmp-gte-1, i1 %cmp-gte-2, i1 %cmp-gte-3) tail call void @use3(i1 %cmp-gte-4, i1 %cmp-gte-5, i1 %cmp-gte-6) ; ret = [0, 10), slt %cmp-slt-1 = icmp slt i32 %ret, 10 %cmp-slt-2 = icmp slt i32 %ret, 9 %cmp-slt-3 = icmp slt i32 %ret, 8 %cmp-slt-4 = icmp slt i32 %ret, 1 %cmp-slt-5 = icmp slt i32 %ret, 0 %cmp-slt-6 = icmp slt i32 %ret, -1 tail call void @use3(i1 %cmp-slt-1, i1 %cmp-slt-2, i1 %cmp-slt-3) tail call void @use3(i1 %cmp-slt-4, i1 %cmp-slt-5, i1 %cmp-slt-6) ; ret = [0, 10), sle %cmp-lte-1 = icmp sle i32 %ret, 10 %cmp-lte-2 = icmp sle i32 %ret, 9 %cmp-lte-3 = icmp sle i32 %ret, 8 %cmp-lte-4 = icmp sle i32 %ret, 1 %cmp-lte-5 = icmp sle i32 %ret, 0 %cmp-lte-6 = icmp sle i32 %ret, -1 tail call void @use3(i1 %cmp-lte-1, i1 %cmp-lte-2, i1 %cmp-lte-3) tail call void @use3(i1 %cmp-lte-4, i1 %cmp-lte-5, i1 %cmp-lte-6) ret void } define i32 @test1(i32* %p) { ; CHECK-LABEL: define {{[^@]+}}@test1 ; CHECK-SAME: (i32* nocapture nofree nonnull readonly dereferenceable(4) [[P:%.*]]) ; CHECK-NEXT: [[LOAD_10_100:%.*]] = load i32, i32* [[P]], !range !1 ; CHECK-NEXT: [[ADD_10_THEN_20_110:%.*]] = add i32 [[LOAD_10_100]], 10 ; CHECK-NEXT: [[MUL_10_THEN_200_1091:%.*]] = mul i32 [[ADD_10_THEN_20_110]], 10 ; CHECK-NEXT: ret i32 [[MUL_10_THEN_200_1091]] ; %load-10-100 = load i32, i32* %p, !range !1 %add-10-then-20-110 = add i32 %load-10-100, 10 %mul-10-then-200-1091 = mul i32 %add-10-then-20-110, 10 ret i32 %mul-10-then-200-1091 } define i1 @test1-check(i32* %p) { ; CHECK-LABEL: define {{[^@]+}}@test1-check ; CHECK-SAME: (i32* nocapture nofree readonly [[P:%.*]]) ; CHECK-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree readonly [[P]]) ; CHECK-SANME: !range !2 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500 ; CHECK-NEXT: ret i1 [[CMP]] ; %res = tail call i32 @test1(i32* %p) %cmp = icmp eq i32 %res, 500 ret i1 %cmp } ; TEST2 ; int test2(int *p) { return *p == 0 ? 4 : 3; } ; int test2_check(int *p) { ; int call = test2(p); ; if (call == 5) { ; // dead block ; return 2; ; } else { ; return 3; ; } ; } define i32 @test2(i32* %p) { ; CHECK-LABEL: define {{[^@]+}}@test2 ; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[P]], align 4 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 4, i32 3 ; CHECK-NEXT: ret i32 [[COND]] ; entry: %0 = load i32, i32* %p, align 4 %tobool = icmp eq i32 %0, 0 %cond = select i1 %tobool, i32 4, i32 3 ret i32 %cond } define i32 @test2_check(i32* %p) { ; CHECK-LABEL: define {{[^@]+}}@test2_check ; CHECK-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]]) ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[IF_THEN:%.*]] ; CHECK: if.then: ; CHECK-NEXT: br label [[RETURN:%.*]] ; CHECK: if.end: ; CHECK-NEXT: unreachable ; CHECK: return: ; CHECK-NEXT: ret i32 2 ; entry: %call = tail call i32 @test2(i32* %p) %cmp = icmp slt i32 %call, 5 br i1 %cmp, label %if.then, label %if.end if.then: ; preds = %entry br label %return if.end: ; preds = %entry br label %return return: ; preds = %if.end, %if.then %retval.0 = phi i32 [ 2, %if.then ], [ 3, %if.end ] ret i32 %retval.0 } ; TEST 3 SECV test ; void unkown(); ; int r1(unsigned int u){ ; int sum = 0; ; for(int i = 0; i<100;i++){ ; sum += i; ; } ; // sum = 50 * 49 / 2 ; if(sum > 10000){ ; // dead block ; return 20; ; }else { ; return 10; ; } ; } ; void f1(int u){ ; if(r1(u) > 15){ ; // deadblock ; unkown(); ; }else { ; return; ; } ; } declare dso_local void @unkown() define internal i32 @r1(i32) local_unnamed_addr { ; CHECK-LABEL: define {{[^@]+}}@r1() local_unnamed_addr ; CHECK-NEXT: br label [[TMP3:%.*]] ; CHECK: 1: ; CHECK-NEXT: br label [[F:%.*]] ; CHECK: 2: ; CHECK-NEXT: unreachable ; CHECK: f: ; CHECK-NEXT: ret i32 10 ; CHECK: 3: ; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[TMP7:%.*]], [[TMP3]] ] ; CHECK-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP0]] ], [ [[TMP6:%.*]], [[TMP3]] ] ; CHECK-NEXT: [[TMP6]] = add nuw nsw i32 [[TMP4]], [[TMP5]] ; CHECK-NEXT: [[TMP7]] = add nuw nsw i32 [[TMP4]], 1 ; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i32 [[TMP7]], 100 ; CHECK-NEXT: br i1 [[TMP8]], label [[TMP1:%.*]], label [[TMP3]] ; br label %5 2: ; preds = %5 %3 = icmp sgt i32 %8, 10000 br i1 %3, label %4, label %f 4: ret i32 20 f: ret i32 10 5: ; preds = %5, %1 %6 = phi i32 [ 0, %1 ], [ %9, %5 ] %7 = phi i32 [ 0, %1 ], [ %8, %5 ] %8 = add nuw nsw i32 %6, %7 %9 = add nuw nsw i32 %6, 1 %10 = icmp eq i32 %9, 100 br i1 %10, label %2, label %5 } define void @f1(i32){ ; CHECK-LABEL: define {{[^@]+}}@f1 ; CHECK-SAME: (i32 [[TMP0:%.*]]) ; CHECK-NEXT: [[TMP2:%.*]] = tail call i32 @r1() ; CHECK-NEXT: br label [[TMP4:%.*]] ; CHECK: 3: ; CHECK-NEXT: unreachable ; CHECK: 4: ; CHECK-NEXT: ret void ; %2 = tail call i32 @r1(i32 %0) %3 = icmp sgt i32 %2, 15 br i1 %3, label %4, label %5 4: ; preds = %1 tail call void @unkown() br label %5 5: ; preds = %1, %4 ret void } ; TEST4 LVI test ; f1 ; int test4-f1(int u){ ; if(u>=0) { ; return u; ; }else{ ; return 0; ; } ; } define dso_local i32 @test4-f1(i32 %u) { ; CHECK-LABEL: define {{[^@]+}}@test4-f1 ; CHECK-SAME: (i32 [[U:%.*]]) ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]] ; CHECK: if.then: ; CHECK-NEXT: br label [[RETURN]] ; CHECK: return: ; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[U]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ] ; CHECK-NEXT: ret i32 [[RETVAL_0]] ; ; FIXME: RETVAL_0 >= 0 entry: %cmp = icmp sgt i32 %u, -1 br i1 %cmp, label %if.then, label %return if.then: ; preds = %entry br label %return return: ; preds = %entry, %if.then %retval.0 = phi i32 [ %u, %if.then ], [ 0, %entry ] ret i32 %retval.0 } define dso_local i32 @test4-g1(i32 %u) { ; CHECK-LABEL: define {{[^@]+}}@test4-g1 ; CHECK-SAME: (i32 [[U:%.*]]) ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) ; CHECK-NEXT: ret i32 [[CALL]] ; ; FIXME: %call should have range [0, inf] entry: %call = tail call i32 @test4-f1(i32 %u) ret i32 %call } ; f2 ; int test4-f1(int u){ ; if(u>-1) { ; return u+1; ; }else{ ; return 1; ; } ; } define dso_local i32 @test4-f2(i32 %u) { ; CHECK-LABEL: define {{[^@]+}}@test4-f2 ; CHECK-SAME: (i32 [[U:%.*]]) ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] ; CHECK: if.then: ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[U]], 1 ; CHECK-NEXT: br label [[RETURN:%.*]] ; CHECK: if.else: ; CHECK-NEXT: br label [[RETURN]] ; CHECK: return: ; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 1, [[IF_ELSE]] ] ; CHECK-NEXT: ret i32 [[RETVAL_0]] ; entry: %cmp = icmp sgt i32 %u, -1 br i1 %cmp, label %if.then, label %if.else if.then: ; preds = %entry %add = add nuw nsw i32 %u, 1 br label %return if.else: ; preds = %entry br label %return return: ; preds = %if.else, %if.then %retval.0 = phi i32 [ %add, %if.then ], [ 1, %if.else ] ret i32 %retval.0 } define dso_local i32 @test4-g2(i32 %u) { ; CHECK-LABEL: define {{[^@]+}}@test4-g2 ; CHECK-SAME: (i32 [[U:%.*]]) ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) ; CHECK-NEXT: ret i32 [[CALL]] ; ; FIXME: %call should have range [1, inf] entry: %call = tail call i32 @test4-f2(i32 %u) ret i32 %call } define dso_local i32 @test-5() { ; CHECK-LABEL: define {{[^@]+}}@test-5() ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CALL:%.*]] = call i32 @rec(i32 0), !range !3 ; CHECK-NEXT: ret i32 [[CALL]] ; entry: %call = call i32 @rec(i32 0) ret i32 %call } define internal i32 @rec(i32 %depth) { ; CHECK-LABEL: define {{[^@]+}}@rec ; CHECK-SAME: (i32 [[DEPTH:%.*]]) ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo(i32 [[DEPTH]]) ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[CALL]], 0 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] ; CHECK: if.then: ; CHECK-NEXT: br label [[RETURN:%.*]] ; CHECK: if.end: ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[DEPTH]], 10 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END3:%.*]] ; CHECK: if.then1: ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[DEPTH]], 1 ; CHECK-NEXT: [[CALL2:%.*]] = call i32 @rec(i32 [[ADD]]) ; CHECK-NEXT: br label [[IF_END3]] ; CHECK: if.end3: ; CHECK-NEXT: br label [[RETURN]] ; CHECK: return: ; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 0, [[IF_THEN]] ], [ 1, [[IF_END3]] ] ; CHECK-NEXT: ret i32 [[RETVAL_0]] ; entry: %call = call i32 @foo(i32 %depth) %tobool = icmp ne i32 %call, 0 br i1 %tobool, label %if.then, label %if.end if.then: ; preds = %entry br label %return if.end: ; preds = %entry %cmp = icmp slt i32 %depth, 10 br i1 %cmp, label %if.then1, label %if.end3 if.then1: ; preds = %if.end %add = add nsw i32 %depth, 1 %call2 = call i32 @rec(i32 %add) br label %if.end3 if.end3: ; preds = %if.then1, %if.end br label %return return: ; preds = %if.end3, %if.then %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.end3 ] ret i32 %retval.0 } declare dso_local i32 @foo(i32) !0 = !{i32 0, i32 10} !1 = !{i32 10, i32 100} ;CHECK: !0 = !{i32 0, i32 10} ;CHECK-NEXT: !1 = !{i32 10, i32 100} ;CHECK-NEXT: !2 = !{i32 200, i32 1091}