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; Make sure that when we merge phi nodes, we do not merge two different PHINodes 5; as the same phi node. 6 7define void @f1() { 8bb1: 9 %0 = add i32 1, 2 10 %1 = add i32 3, 4 11 %2 = add i32 5, 6 12 %3 = add i32 7, 8 13 br label %bb5 14bb2: 15 %4 = mul i32 5, 4 16 br label %bb5 17 18placeholder: 19 %a = sub i32 5, 4 20 ret void 21 22bb5: 23 %phinode = phi i32 [5, %bb1], [5, %bb2] 24 %phinode1 = phi i32 [5, %bb1], [5, %bb2] 25 ret void 26} 27 28define void @f2() { 29bb1: 30 %0 = add i32 1, 2 31 %1 = add i32 3, 4 32 %2 = add i32 5, 6 33 %3 = add i32 7, 8 34 br label %bb5 35bb2: 36 %4 = mul i32 5, 4 37 br label %bb5 38 39placeholder: 40 %a = sub i32 5, 4 41 ret void 42 43bb5: 44 %phinode = phi i32 [5, %bb1], [5, %bb2] 45 %phinode1 = phi i32 [5, %bb1], [5, %bb2] 46 ret void 47} 48; CHECK-LABEL: @f1( 49; CHECK-NEXT: bb1: 50; CHECK-NEXT: [[PHINODE1_CE_LOC:%.*]] = alloca i32, align 4 51; CHECK-NEXT: [[PHINODE_CE_LOC:%.*]] = alloca i32, align 4 52; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 -1, ptr [[PHINODE_CE_LOC]]) 53; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 -1, ptr [[PHINODE1_CE_LOC]]) 54; CHECK-NEXT: [[TARGETBLOCK:%.*]] = call i1 @outlined_ir_func_0(ptr [[PHINODE_CE_LOC]], ptr [[PHINODE1_CE_LOC]]) 55; CHECK-NEXT: [[PHINODE_CE_RELOAD:%.*]] = load i32, ptr [[PHINODE_CE_LOC]], align 4 56; CHECK-NEXT: [[PHINODE1_CE_RELOAD:%.*]] = load i32, ptr [[PHINODE1_CE_LOC]], align 4 57; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 -1, ptr [[PHINODE_CE_LOC]]) 58; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 -1, ptr [[PHINODE1_CE_LOC]]) 59; CHECK-NEXT: br i1 [[TARGETBLOCK]], label [[BB5:%.*]], label [[BB1_AFTER_OUTLINE:%.*]] 60; CHECK: bb1_after_outline: 61; CHECK-NEXT: ret void 62; CHECK: bb5: 63; CHECK-NEXT: [[PHINODE:%.*]] = phi i32 [ [[PHINODE_CE_RELOAD]], [[BB1:%.*]] ] 64; CHECK-NEXT: [[PHINODE1:%.*]] = phi i32 [ [[PHINODE1_CE_RELOAD]], [[BB1]] ] 65; CHECK-NEXT: ret void 66; 67; 68; CHECK-LABEL: @f2( 69; CHECK-NEXT: bb1: 70; CHECK-NEXT: [[PHINODE1_CE_LOC:%.*]] = alloca i32, align 4 71; CHECK-NEXT: [[PHINODE_CE_LOC:%.*]] = alloca i32, align 4 72; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 -1, ptr [[PHINODE_CE_LOC]]) 73; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 -1, ptr [[PHINODE1_CE_LOC]]) 74; CHECK-NEXT: [[TARGETBLOCK:%.*]] = call i1 @outlined_ir_func_0(ptr [[PHINODE_CE_LOC]], ptr [[PHINODE1_CE_LOC]]) 75; CHECK-NEXT: [[PHINODE_CE_RELOAD:%.*]] = load i32, ptr [[PHINODE_CE_LOC]], align 4 76; CHECK-NEXT: [[PHINODE1_CE_RELOAD:%.*]] = load i32, ptr [[PHINODE1_CE_LOC]], align 4 77; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 -1, ptr [[PHINODE_CE_LOC]]) 78; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 -1, ptr [[PHINODE1_CE_LOC]]) 79; CHECK-NEXT: br i1 [[TARGETBLOCK]], label [[BB5:%.*]], label [[BB1_AFTER_OUTLINE:%.*]] 80; CHECK: bb1_after_outline: 81; CHECK-NEXT: ret void 82; CHECK: bb5: 83; CHECK-NEXT: [[PHINODE:%.*]] = phi i32 [ [[PHINODE_CE_RELOAD]], [[BB1:%.*]] ] 84; CHECK-NEXT: [[PHINODE1:%.*]] = phi i32 [ [[PHINODE1_CE_RELOAD]], [[BB1]] ] 85; CHECK-NEXT: ret void 86; 87; 88; CHECK-LABEL: define internal i1 @outlined_ir_func_0( 89; CHECK-NEXT: newFuncRoot: 90; CHECK-NEXT: br label [[BB1_TO_OUTLINE:%.*]] 91; CHECK: bb1_to_outline: 92; CHECK-NEXT: [[TMP2:%.*]] = add i32 1, 2 93; CHECK-NEXT: [[TMP3:%.*]] = add i32 3, 4 94; CHECK-NEXT: [[TMP4:%.*]] = add i32 5, 6 95; CHECK-NEXT: [[TMP5:%.*]] = add i32 7, 8 96; CHECK-NEXT: br label [[BB5_SPLIT:%.*]] 97; CHECK: bb2: 98; CHECK-NEXT: [[TMP6:%.*]] = mul i32 5, 4 99; CHECK-NEXT: br label [[BB5_SPLIT]] 100; CHECK: placeholder: 101; CHECK-NEXT: [[A:%.*]] = sub i32 5, 4 102; CHECK-NEXT: br label [[BB1_AFTER_OUTLINE_EXITSTUB:%.*]] 103; CHECK: bb5.split: 104; CHECK-NEXT: [[PHINODE_CE:%.*]] = phi i32 [ 5, [[BB1_TO_OUTLINE]] ], [ 5, [[BB2:%.*]] ] 105; CHECK-NEXT: [[PHINODE1_CE:%.*]] = phi i32 [ 5, [[BB1_TO_OUTLINE]] ], [ 5, [[BB2]] ] 106; CHECK-NEXT: br label [[BB5_EXITSTUB:%.*]] 107; CHECK: bb5.exitStub: 108; CHECK-NEXT: store i32 [[PHINODE_CE]], ptr [[TMP0:%.*]], align 4 109; CHECK-NEXT: store i32 [[PHINODE1_CE]], ptr [[TMP1:%.*]], align 4 110; CHECK-NEXT: ret i1 true 111; CHECK: bb1_after_outline.exitStub: 112; CHECK-NEXT: ret i1 false 113; 114