1f564299fSAndrew Litteken; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs 29dd9575cSRoman Lebedev; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s 305b1a15fSAndrew Litteken 405b1a15fSAndrew Litteken; This test ensures that an extra output is not added when there is a bitcast 505b1a15fSAndrew Litteken; that is relocated to outside of the extraction due to a starting lifetime 605b1a15fSAndrew Litteken; instruction outside of the extracted region. 705b1a15fSAndrew Litteken 805b1a15fSAndrew Litteken; Additionally, we check that the newly added bitcast instruction is excluded in 905b1a15fSAndrew Litteken; further extractions. 1005b1a15fSAndrew Litteken 11*f4b925eeSMatt Arsenaultdeclare void @llvm.lifetime.start.p0(i64, ptr nocapture) 12*f4b925eeSMatt Arsenaultdeclare void @llvm.lifetime.end.p0(i64, ptr nocapture) 1305b1a15fSAndrew Litteken 1405b1a15fSAndrew Littekendefine void @outline_bitcast_base() { 1505b1a15fSAndrew Littekenentry: 1605b1a15fSAndrew Litteken %a = alloca i32, align 4 1705b1a15fSAndrew Litteken %b = alloca i32, align 4 1805b1a15fSAndrew Litteken %c = alloca i32, align 4 1905b1a15fSAndrew Litteken %d = alloca i32, align 4 20*f4b925eeSMatt Arsenault store i32 2, ptr %a, align 4 21*f4b925eeSMatt Arsenault store i32 3, ptr %b, align 4 22*f4b925eeSMatt Arsenault store i32 4, ptr %c, align 4 23*f4b925eeSMatt Arsenault %al = load i32, ptr %a 24*f4b925eeSMatt Arsenault %bl = load i32, ptr %b 25*f4b925eeSMatt Arsenault %cl = load i32, ptr %c 2605b1a15fSAndrew Litteken ret void 2705b1a15fSAndrew Litteken} 2805b1a15fSAndrew Litteken 2905b1a15fSAndrew Littekendefine void @outline_bitcast_removed() { 3005b1a15fSAndrew Littekenentry: 3105b1a15fSAndrew Litteken %a = alloca i32, align 4 3205b1a15fSAndrew Litteken %b = alloca i32, align 4 3305b1a15fSAndrew Litteken %c = alloca i32, align 4 3405b1a15fSAndrew Litteken %d = alloca i32, align 4 35*f4b925eeSMatt Arsenault store i32 2, ptr %a, align 4 36*f4b925eeSMatt Arsenault store i32 3, ptr %b, align 4 37*f4b925eeSMatt Arsenault store i32 4, ptr %c, align 4 38*f4b925eeSMatt Arsenault %al = load i32, ptr %a 39*f4b925eeSMatt Arsenault %bl = load i32, ptr %b 40*f4b925eeSMatt Arsenault %cl = load i32, ptr %c 41*f4b925eeSMatt Arsenault call void @llvm.lifetime.start.p0(i64 -1, ptr %d) 42*f4b925eeSMatt Arsenault %am = load i32, ptr %b 43*f4b925eeSMatt Arsenault %bm = load i32, ptr %a 44*f4b925eeSMatt Arsenault %cm = load i32, ptr %c 45*f4b925eeSMatt Arsenault call void @llvm.lifetime.end.p0(i64 -1, ptr %d) 4605b1a15fSAndrew Litteken ret void 4705b1a15fSAndrew Litteken} 4805b1a15fSAndrew Litteken 49f564299fSAndrew Litteken; The first bitcast is moved down to lifetime start, and, since the original 50f564299fSAndrew Litteken; endpoint does not match the new endpoint, we cannot extract and outline the 51f564299fSAndrew Litteken; second bitcast and set of adds. Outlining only occurs in this case due to 52f564299fSAndrew Litteken; the lack of a cost model, as denoted by the debug command line argument. 53f564299fSAndrew Litteken 5405b1a15fSAndrew Littekendefine void @outline_bitcast_base2(i32 %a, i32 %b, i32 %c) { 5505b1a15fSAndrew Littekenentry: 56f564299fSAndrew Litteken %d = alloca i32, align 4 5705b1a15fSAndrew Litteken %al = add i32 %a, %b 5805b1a15fSAndrew Litteken %bl = add i32 %b, %a 5905b1a15fSAndrew Litteken %cl = add i32 %b, %c 60f564299fSAndrew Litteken %buffer = mul i32 %a, %b 61f564299fSAndrew Litteken %am = add i32 %a, %b 62f564299fSAndrew Litteken %bm = add i32 %b, %a 63f564299fSAndrew Litteken %cm = add i32 %b, %c 64*f4b925eeSMatt Arsenault call void @llvm.lifetime.start.p0(i64 -1, ptr %d) 65*f4b925eeSMatt Arsenault call void @llvm.lifetime.end.p0(i64 -1, ptr %d) 6605b1a15fSAndrew Litteken ret void 6705b1a15fSAndrew Litteken} 6805b1a15fSAndrew Litteken 69f564299fSAndrew Litteken; CHECK-LABEL: @outline_bitcast_base( 70f564299fSAndrew Litteken; CHECK-NEXT: entry: 71f564299fSAndrew Litteken; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 72f564299fSAndrew Litteken; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4 73f564299fSAndrew Litteken; CHECK-NEXT: [[C:%.*]] = alloca i32, align 4 74f564299fSAndrew Litteken; CHECK-NEXT: [[D:%.*]] = alloca i32, align 4 75*f4b925eeSMatt Arsenault; CHECK-NEXT: call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]]) 76f564299fSAndrew Litteken; CHECK-NEXT: ret void 77f564299fSAndrew Litteken; 78f564299fSAndrew Litteken; 79f564299fSAndrew Litteken; CHECK-LABEL: @outline_bitcast_removed( 80f564299fSAndrew Litteken; CHECK-NEXT: entry: 81f564299fSAndrew Litteken; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 82f564299fSAndrew Litteken; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4 83f564299fSAndrew Litteken; CHECK-NEXT: [[C:%.*]] = alloca i32, align 4 84*f4b925eeSMatt Arsenault; CHECK-NEXT: call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]]) 85*f4b925eeSMatt Arsenault; CHECK-NEXT: [[AM:%.*]] = load i32, ptr [[B]], align 4 86*f4b925eeSMatt Arsenault; CHECK-NEXT: [[BM:%.*]] = load i32, ptr [[A]], align 4 87*f4b925eeSMatt Arsenault; CHECK-NEXT: [[CM:%.*]] = load i32, ptr [[C]], align 4 88f564299fSAndrew Litteken; CHECK-NEXT: ret void 89f564299fSAndrew Litteken; 90f564299fSAndrew Litteken; 91f564299fSAndrew Litteken; CHECK-LABEL: @outline_bitcast_base2( 92f564299fSAndrew Litteken; CHECK-NEXT: entry: 93*f4b925eeSMatt Arsenault; CHECK-NEXT: call void @outlined_ir_func_1(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) 94f564299fSAndrew Litteken; CHECK-NEXT: [[BUFFER:%.*]] = mul i32 [[A]], [[B]] 95*f4b925eeSMatt Arsenault; CHECK-NEXT: call void @outlined_ir_func_1(i32 [[A]], i32 [[B]], i32 [[C]]) 96f564299fSAndrew Litteken; CHECK-NEXT: ret void 97f564299fSAndrew Litteken; 98f564299fSAndrew Litteken; 99c58d4c4bSAndrew Litteken; CHECK-LABEL: @outlined_ir_func_0( 100c58d4c4bSAndrew Litteken; CHECK-NEXT: newFuncRoot: 101c58d4c4bSAndrew Litteken; CHECK-NEXT: br label [[ENTRY_TO_OUTLINE:%.*]] 10205b1a15fSAndrew Litteken; CHECK: entry_to_outline: 103*f4b925eeSMatt Arsenault; CHECK-NEXT: store i32 2, ptr [[TMP0:%.*]], align 4 104*f4b925eeSMatt Arsenault; CHECK-NEXT: store i32 3, ptr [[TMP1:%.*]], align 4 105*f4b925eeSMatt Arsenault; CHECK-NEXT: store i32 4, ptr [[TMP2:%.*]], align 4 106*f4b925eeSMatt Arsenault; CHECK-NEXT: [[AL:%.*]] = load i32, ptr [[TMP0]], align 4 107*f4b925eeSMatt Arsenault; CHECK-NEXT: [[BL:%.*]] = load i32, ptr [[TMP1]], align 4 108*f4b925eeSMatt Arsenault; CHECK-NEXT: [[CL:%.*]] = load i32, ptr [[TMP2]], align 4 109f564299fSAndrew Litteken; CHECK-NEXT: br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]] 110c58d4c4bSAndrew Litteken; CHECK: entry_after_outline.exitStub: 111c58d4c4bSAndrew Litteken; CHECK-NEXT: ret void 112*f4b925eeSMatt Arsenault; 113*f4b925eeSMatt Arsenault; 114*f4b925eeSMatt Arsenault; CHECK-LABEL: @outlined_ir_func_1( 115*f4b925eeSMatt Arsenault; CHECK-NEXT: newFuncRoot: 116*f4b925eeSMatt Arsenault; CHECK-NEXT: [[D:%.*]] = alloca i32, align 4 117*f4b925eeSMatt Arsenault; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 -1, ptr [[D]]) 118*f4b925eeSMatt Arsenault; CHECK-NEXT: br label [[ENTRY_TO_OUTLINE:%.*]] 119*f4b925eeSMatt Arsenault; CHECK: entry_to_outline: 120*f4b925eeSMatt Arsenault; CHECK-NEXT: [[AL:%.*]] = add i32 [[TMP0:%.*]], [[TMP1:%.*]] 121*f4b925eeSMatt Arsenault; CHECK-NEXT: [[BL:%.*]] = add i32 [[TMP1]], [[TMP0]] 122*f4b925eeSMatt Arsenault; CHECK-NEXT: [[CL:%.*]] = add i32 [[TMP1]], [[TMP2:%.*]] 123*f4b925eeSMatt Arsenault; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 -1, ptr [[D]]) 124*f4b925eeSMatt Arsenault; CHECK-NEXT: br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]] 125*f4b925eeSMatt Arsenault; CHECK: entry_after_outline.exitStub: 126*f4b925eeSMatt Arsenault; CHECK-NEXT: ret void 127*f4b925eeSMatt Arsenault; 128