1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=ipsccp -S | FileCheck %s 3 4; Test for PR39772 5 6%struct.Node = type { ptr, ptr, i32 } 7 8define i32 @check(ptr %node) { 9; CHECK-LABEL: @check( 10; CHECK-NEXT: entry: 11; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[NODE:%.*]], null 12; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 13; CHECK: if.then: 14; CHECK-NEXT: br label [[CLEANUP:%.*]] 15; CHECK: if.end: 16; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[NODE]], align 8 17; CHECK-NEXT: [[CALL:%.*]] = call i32 @check(ptr [[TMP0]]) 18; CHECK-NEXT: [[RIGHT:%.*]] = getelementptr inbounds nuw [[STRUCT_NODE:%.*]], ptr [[NODE]], i32 0, i32 1 19; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[RIGHT]], align 8 20; CHECK-NEXT: [[CALL1:%.*]] = call i32 @check(ptr [[TMP1]]) 21; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[RIGHT]], align 8 22; CHECK-NEXT: [[HEIGHT:%.*]] = getelementptr inbounds nuw [[STRUCT_NODE]], ptr [[TMP2]], i32 0, i32 2 23; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[HEIGHT]], align 4 24; CHECK-NEXT: [[CMP3:%.*]] = icmp ne i32 [[TMP3]], [[CALL1]] 25; CHECK-NEXT: br i1 [[CMP3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]] 26; CHECK: if.then4: 27; CHECK-NEXT: unreachable 28; CHECK: if.end5: 29; CHECK-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[CALL]], [[CALL1]] 30; CHECK-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_ELSE:%.*]] 31; CHECK: if.then7: 32; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], 1 33; CHECK-NEXT: br label [[CLEANUP]] 34; CHECK: if.else: 35; CHECK-NEXT: [[ADD8:%.*]] = add nsw i32 [[CALL1]], 1 36; CHECK-NEXT: br label [[CLEANUP]] 37; CHECK: cleanup: 38; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 0, [[IF_THEN]] ], [ [[ADD]], [[IF_THEN7]] ], [ [[ADD8]], [[IF_ELSE]] ] 39; CHECK-NEXT: ret i32 [[RETVAL_0]] 40; 41entry: 42 %cmp = icmp eq ptr %node, null 43 br i1 %cmp, label %if.then, label %if.end 44 45if.then: ; preds = %entry 46 br label %cleanup 47 48if.end: ; preds = %entry 49 %0 = load ptr, ptr %node 50 %call = call i32 @check(ptr %0) 51 %right = getelementptr inbounds %struct.Node, ptr %node, i32 0, i32 1 52 %1 = load ptr, ptr %right 53 %call1 = call i32 @check(ptr %1) 54 %2 = load ptr, ptr %right 55 %height = getelementptr inbounds %struct.Node, ptr %2, i32 0, i32 2 56 %3 = load i32, ptr %height 57 %cmp3 = icmp ne i32 %3, %call1 58 br i1 %cmp3, label %if.then4, label %if.end5 59 60if.then4: ; preds = %if.end 61 unreachable 62 63if.end5: ; preds = %if.end 64 %cmp6 = icmp sgt i32 %call, %call1 65 br i1 %cmp6, label %if.then7, label %if.else 66 67if.then7: ; preds = %if.end5 68 %add = add nsw i32 %call, 1 69 br label %cleanup 70 71if.else: ; preds = %if.end5 72 %add8 = add nsw i32 %call1, 1 73 br label %cleanup 74 75cleanup: ; preds = %if.else, %if.then7, %if.then 76 %retval.0 = phi i32 [ 0, %if.then ], [ %add, %if.then7 ], [ %add8, %if.else ] 77 ret i32 %retval.0 78} 79 80declare ptr @test2_callee(i32, i32) 81 82define void @test2() { 83; CHECK-LABEL: @test2( 84; CHECK-NEXT: entry: 85; CHECK-NEXT: br label [[FOR_COND:%.*]] 86; CHECK: for.cond: 87; CHECK-NEXT: br label [[FOR_BODY:%.*]] 88; CHECK: for.body: 89; CHECK-NEXT: br label [[IF_ELSE33:%.*]] 90; CHECK: if.else33: 91; CHECK-NEXT: br label [[IF_THEN38:%.*]] 92; CHECK: if.then38: 93; CHECK-NEXT: [[CALL42:%.*]] = call ptr @test2_callee(i32 0, i32 0) 94; CHECK-NEXT: unreachable 95; 96entry: 97 br label %for.cond 98 99for.cond: ; preds = %for.inc46, %entry 100 %op.0 = phi i32 [ 0, %entry ], [ 0, %for.inc46 ] 101 br label %for.body 102 103for.body: ; preds = %for.cond 104 %cmp24 = icmp eq i32 %op.0, 38 105 br i1 %cmp24, label %if.then26, label %if.else33 106 107if.then26: ; preds = %for.body 108 unreachable 109 110if.else33: ; preds = %for.body 111 %cmp34 = icmp ne i32 %op.0, 80 112 %cmp36 = icmp ne i32 %op.0, 81 113 %or.cond = and i1 %cmp34, %cmp36 114 br i1 %or.cond, label %if.then38, label %for.inc46 115 116if.then38: ; preds = %if.else33 117 %call42 = call ptr @test2_callee(i32 %op.0, i32 0) 118 unreachable 119 120for.inc46: ; preds = %if.else33 121 br label %for.cond 122} 123