1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs 2; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s 3 4; Here we have multiple exits, but the different sources, same outputs are 5; needed, this checks that they are compressed, and moved into the appropriate 6; output blocks. 7 8define void @outline_outputs1() #0 { 9entry: 10 %output = alloca i32, align 4 11 %result = alloca i32, align 4 12 %output2 = alloca i32, align 4 13 %result2 = alloca i32, align 4 14 %a = alloca i32, align 4 15 %b = alloca i32, align 4 16 br label %block_2 17block_1: 18 %a2 = alloca i32, align 4 19 %b2 = alloca i32, align 4 20 br label %block_2 21block_2: 22 %a2val = load i32, ptr %a 23 %b2val = load i32, ptr %b 24 %add2 = add i32 2, %a2val 25 %mul2 = mul i32 2, %b2val 26 br label %block_5 27block_3: 28 %aval = load i32, ptr %a 29 %bval = load i32, ptr %b 30 %add = add i32 2, %aval 31 %mul = mul i32 2, %bval 32 br label %block_4 33block_4: 34 store i32 %add, ptr %output, align 4 35 store i32 %mul, ptr %result, align 4 36 br label %block_6 37block_5: 38 store i32 %add2, ptr %output, align 4 39 store i32 %mul2, ptr %result, align 4 40 br label %block_6 41dummy: 42 ret void 43block_6: 44 %diff = phi i32 [%aval, %block_4], [%a2val, %block_5] 45 ret void 46} 47 48define void @outline_outputs2() #0 { 49entry: 50 %output = alloca i32, align 4 51 %result = alloca i32, align 4 52 %output2 = alloca i32, align 4 53 %result2 = alloca i32, align 4 54 %a = alloca i32, align 4 55 %b = alloca i32, align 4 56 br label %block_2 57block_1: 58 %a2 = alloca i32, align 4 59 %b2 = alloca i32, align 4 60 br label %block_2 61block_2: 62 %a2val = load i32, ptr %a 63 %b2val = load i32, ptr %b 64 %add2 = add i32 2, %a2val 65 %mul2 = mul i32 2, %b2val 66 br label %block_5 67block_3: 68 %aval = load i32, ptr %a 69 %bval = load i32, ptr %b 70 %add = add i32 2, %aval 71 %mul = mul i32 2, %bval 72 br label %block_4 73block_4: 74 store i32 %add, ptr %output, align 4 75 store i32 %mul, ptr %result, align 4 76 br label %block_6 77block_5: 78 store i32 %add2, ptr %output, align 4 79 store i32 %mul2, ptr %result, align 4 80 br label %block_6 81dummy: 82 ret void 83block_6: 84 %diff = phi i32 [%aval, %block_4], [%a2val, %block_5] 85 ret void 86} 87 88; CHECK-LABEL: @outline_outputs1( 89; CHECK-NEXT: entry: 90; CHECK-NEXT: [[DIFF_CE_LOC:%.*]] = alloca i32, align 4 91; CHECK-NEXT: [[OUTPUT:%.*]] = alloca i32, align 4 92; CHECK-NEXT: [[RESULT:%.*]] = alloca i32, align 4 93; CHECK-NEXT: [[OUTPUT2:%.*]] = alloca i32, align 4 94; CHECK-NEXT: [[RESULT2:%.*]] = alloca i32, align 4 95; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 96; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4 97; CHECK-NEXT: br label [[BLOCK_2:%.*]] 98; CHECK: block_1: 99; CHECK-NEXT: [[A2:%.*]] = alloca i32, align 4 100; CHECK-NEXT: [[B2:%.*]] = alloca i32, align 4 101; CHECK-NEXT: br label [[BLOCK_2]] 102; CHECK: block_2: 103; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 -1, ptr [[DIFF_CE_LOC]]) 104; CHECK-NEXT: call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[RESULT]], ptr [[DIFF_CE_LOC]]) 105; CHECK-NEXT: [[DIFF_CE_RELOAD:%.*]] = load i32, ptr [[DIFF_CE_LOC]], align 4 106; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 -1, ptr [[DIFF_CE_LOC]]) 107; CHECK-NEXT: br label [[BLOCK_6:%.*]] 108; CHECK: dummy: 109; CHECK-NEXT: ret void 110; CHECK: block_6: 111; CHECK-NEXT: [[DIFF:%.*]] = phi i32 [ [[DIFF_CE_RELOAD]], [[BLOCK_2]] ] 112; CHECK-NEXT: ret void 113; 114; 115; CHECK-LABEL: @outline_outputs2( 116; CHECK-NEXT: entry: 117; CHECK-NEXT: [[DIFF_CE_LOC:%.*]] = alloca i32, align 4 118; CHECK-NEXT: [[OUTPUT:%.*]] = alloca i32, align 4 119; CHECK-NEXT: [[RESULT:%.*]] = alloca i32, align 4 120; CHECK-NEXT: [[OUTPUT2:%.*]] = alloca i32, align 4 121; CHECK-NEXT: [[RESULT2:%.*]] = alloca i32, align 4 122; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 123; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4 124; CHECK-NEXT: br label [[BLOCK_2:%.*]] 125; CHECK: block_1: 126; CHECK-NEXT: [[A2:%.*]] = alloca i32, align 4 127; CHECK-NEXT: [[B2:%.*]] = alloca i32, align 4 128; CHECK-NEXT: br label [[BLOCK_2]] 129; CHECK: block_2: 130; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 -1, ptr [[DIFF_CE_LOC]]) 131; CHECK-NEXT: call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[RESULT]], ptr [[DIFF_CE_LOC]]) 132; CHECK-NEXT: [[DIFF_CE_RELOAD:%.*]] = load i32, ptr [[DIFF_CE_LOC]], align 4 133; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 -1, ptr [[DIFF_CE_LOC]]) 134; CHECK-NEXT: br label [[BLOCK_6:%.*]] 135; CHECK: dummy: 136; CHECK-NEXT: ret void 137; CHECK: block_6: 138; CHECK-NEXT: [[DIFF:%.*]] = phi i32 [ [[DIFF_CE_RELOAD]], [[BLOCK_2]] ] 139; CHECK-NEXT: ret void 140; 141; 142; CHECK: define internal void @outlined_ir_func_0( 143; CHECK-NEXT: newFuncRoot: 144; CHECK-NEXT: br label [[BLOCK_2_TO_OUTLINE:%.*]] 145; CHECK: block_2_to_outline: 146; CHECK-NEXT: [[A2VAL:%.*]] = load i32, ptr [[TMP0:%.*]], align 4 147; CHECK-NEXT: [[B2VAL:%.*]] = load i32, ptr [[TMP1:%.*]], align 4 148; CHECK-NEXT: [[ADD2:%.*]] = add i32 2, [[A2VAL]] 149; CHECK-NEXT: [[MUL2:%.*]] = mul i32 2, [[B2VAL]] 150; CHECK-NEXT: br label [[BLOCK_5:%.*]] 151; CHECK: block_3: 152; CHECK-NEXT: [[AVAL:%.*]] = load i32, ptr [[TMP0]], align 4 153; CHECK-NEXT: [[BVAL:%.*]] = load i32, ptr [[TMP1]], align 4 154; CHECK-NEXT: [[ADD:%.*]] = add i32 2, [[AVAL]] 155; CHECK-NEXT: [[MUL:%.*]] = mul i32 2, [[BVAL]] 156; CHECK-NEXT: br label [[BLOCK_4:%.*]] 157; CHECK: block_4: 158; CHECK-NEXT: store i32 [[ADD]], ptr [[TMP2:%.*]], align 4 159; CHECK-NEXT: store i32 [[MUL]], ptr [[TMP3:%.*]], align 4 160; CHECK-NEXT: br label [[BLOCK_6_SPLIT:%.*]] 161; CHECK: block_5: 162; CHECK-NEXT: store i32 [[ADD2]], ptr [[TMP2]], align 4 163; CHECK-NEXT: store i32 [[MUL2]], ptr [[TMP3]], align 4 164; CHECK-NEXT: br label [[BLOCK_6_SPLIT]] 165; CHECK: block_6.split: 166; CHECK-NEXT: [[DIFF_CE:%.*]] = phi i32 [ [[AVAL]], [[BLOCK_4]] ], [ [[A2VAL]], [[BLOCK_5]] ] 167; CHECK-NEXT: br label [[BLOCK_6_EXITSTUB:%.*]] 168; CHECK: block_6.exitStub: 169; CHECK-NEXT: store i32 [[DIFF_CE]], ptr [[TMP4:%.*]], align 4 170; CHECK-NEXT: ret void 171; 172