brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.8 KiB · 9009b98 Raw
207 lines · plain
1; RUN: opt -passes=objc-arc -S < %s 2>&1 | FileCheck %s '--implicit-check-not=ignoring invalid debug'2 3declare void @alterRefCount()4declare void @use(ptr)5declare void @readOnlyFunc(ptr, ptr)6 7@g0 = global ptr null, align 88 9; Check that ARC optimizer doesn't reverse the order of the retain call and the10; release call when there are debug instructions.11 12; CHECK: call ptr @llvm.objc.retain(ptr %x)13; CHECK: call void @llvm.objc.release(ptr %x)14 15define i32 @test(ptr %x, ptr %y, i8 %z, i32 %i) {16  %i.addr = alloca i32, align 417  store i32 %i, ptr %i.addr, align 418  %v1 = tail call ptr @llvm.objc.retain(ptr %x)19  store i8 %z, ptr %x20  call void @llvm.dbg.declare(metadata ptr %i.addr, metadata !11, metadata !DIExpression()), !dbg !1021  call void @alterRefCount()22  tail call void @llvm.objc.release(ptr %x)23  ret i32 %i24}25 26; ARC optimizer shouldn't move the release call, which is a precise release call27; past the call to @alterRefCount.28 29; CHECK-LABEL: define void @test2(30; CHECK: call void @alterRefCount(31; CHECK: call void @llvm.objc.release(32 33define void @test2() {34  %v0 = load ptr, ptr @g0, align 835  %v1 = tail call ptr @llvm.objc.retain(ptr %v0)36  tail call void @use(ptr %v0)37  tail call void @alterRefCount()38  tail call void @llvm.objc.release(ptr %v0)39  ret void40}41 42; Check that code motion is disabled in @test3 and @test4.43; Previously, ARC optimizer would move the release past the retain.44 45; if.then:46;   call void @readOnlyFunc(ptr %obj, ptr null)47;   call void @llvm.objc.release(ptr %obj) #1, !clang.imprecise_release !248;   %1 = add i32 1, 249;   %2 = tail call ptr @llvm.objc.retain(ptr %obj)50;51; Ideally, the retain/release pairs in BB if.then should be removed.52 53define void @test3(ptr %obj, i1 %cond) {54; CHECK-LABEL: @test3(55; CHECK-NEXT:    [[TMP2:%.*]] = tail call ptr @llvm.objc.retain(ptr [[OBJ:%.*]])56; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]57; CHECK:       if.then:58; CHECK-NEXT:    call void @readOnlyFunc(ptr [[OBJ]], ptr null)59; CHECK-NEXT:    [[TMP1:%.*]] = add i32 1, 260; CHECK-NEXT:    call void @alterRefCount()61; CHECK-NEXT:    br label [[JOIN:%.*]]62; CHECK:       if.else:63; CHECK-NEXT:    call void @alterRefCount()64; CHECK-NEXT:    call void @use(ptr [[OBJ]])65; CHECK-NEXT:    br label [[JOIN]]66; CHECK:       join:67; CHECK-NEXT:    call void @llvm.objc.release(ptr [[OBJ]]) {{.*}}, !clang.imprecise_release ![[EMPTYMETA:[0-9]+]]68; CHECK-NEXT:    ret void69;70  %v0 = call ptr @llvm.objc.retain(ptr %obj)71  br i1 %cond, label %if.then, label %if.else72 73if.then:74  call void @readOnlyFunc(ptr %obj, ptr null) #075  add i32 1, 276  call void @alterRefCount()77  br label %join78 79if.else:80  call void @alterRefCount()81  call void @use(ptr %obj)82  br label %join83 84join:85  call void @llvm.objc.release(ptr %obj), !clang.imprecise_release !986  ret void87}88 89define void @test4(ptr %obj0, ptr %obj1, i1 %cond) {90; CHECK-LABEL: @test4(91; CHECK-NEXT:    [[TMP3:%.*]] = tail call ptr @llvm.objc.retain(ptr [[OBJ0:%.*]])92; CHECK-NEXT:    [[TMP2:%.*]] = tail call ptr @llvm.objc.retain(ptr [[OBJ1:%.*]])93; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]94; CHECK:       if.then:95; CHECK-NEXT:    call void @readOnlyFunc(ptr [[OBJ0]], ptr [[OBJ1]])96; CHECK-NEXT:    [[TMP1:%.*]] = add i32 1, 297; CHECK-NEXT:    call void @alterRefCount()98; CHECK-NEXT:    br label [[JOIN:%.*]]99; CHECK:       if.else:100; CHECK-NEXT:    call void @alterRefCount()101; CHECK-NEXT:    call void @use(ptr [[OBJ0]])102; CHECK-NEXT:    call void @use(ptr [[OBJ1]])103; CHECK-NEXT:    br label [[JOIN]]104; CHECK:       join:105; CHECK-NEXT:    call void @llvm.objc.release(ptr [[OBJ0]]) {{.*}}, !clang.imprecise_release ![[EMPTYMETA]]106; CHECK-NEXT:    call void @llvm.objc.release(ptr [[OBJ1]]) {{.*}}, !clang.imprecise_release ![[EMPTYMETA]]107; CHECK-NEXT:    ret void108;109  %v0 = call ptr @llvm.objc.retain(ptr %obj0)110  %v1 = call ptr @llvm.objc.retain(ptr %obj1)111  br i1 %cond, label %if.then, label %if.else112 113if.then:114  call void @readOnlyFunc(ptr %obj0, ptr %obj1) #0115  add i32 1, 2116  call void @alterRefCount()117  br label %join118 119if.else:120  call void @alterRefCount()121  call void @use(ptr %obj0)122  call void @use(ptr %obj1)123  br label %join124 125join:126  call void @llvm.objc.release(ptr %obj0), !clang.imprecise_release !9127  call void @llvm.objc.release(ptr %obj1), !clang.imprecise_release !9128  ret void129}130 131; In this test, insertion points for the retain and release calls that could be132; eliminated are in different blocks (bb1 and if.then).133 134define void @test5(ptr %obj, i1 %cond0, i1 %cond1) {135; CHECK-LABEL: @test5(136; CHECK-NEXT:    [[V0:%.*]] = tail call ptr @llvm.objc.retain(ptr [[OBJ:%.*]])137; CHECK-NEXT:    br i1 [[COND0:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]138; CHECK:       if.then:139; CHECK-NEXT:    call void @readOnlyFunc(ptr [[OBJ]], ptr null)140; CHECK-NEXT:    br i1 [[COND1:%.*]], label [[IF_THEN2:%.*]], label [[IF_ELSE2:%.*]]141; CHECK:       if.then2:142; CHECK-NEXT:    br label [[BB1:%.*]]143; CHECK:       if.else2:144; CHECK-NEXT:    br label [[BB1]]145; CHECK:       bb1:146; CHECK-NEXT:    [[TMP1:%.*]] = add i32 1, 2147; CHECK-NEXT:    call void @alterRefCount()148; CHECK-NEXT:    br label [[JOIN:%.*]]149; CHECK:       if.else:150; CHECK-NEXT:    call void @alterRefCount()151; CHECK-NEXT:    call void @use(ptr [[OBJ]])152; CHECK-NEXT:    br label [[JOIN]]153; CHECK:       join:154; CHECK-NEXT:    call void @llvm.objc.release(ptr [[OBJ]])155; CHECK-NEXT:    ret void156;157  %v0 = call ptr @llvm.objc.retain(ptr %obj)158  br i1 %cond0, label %if.then, label %if.else159 160if.then:161  call void @readOnlyFunc(ptr %obj, ptr null) #0162  br i1 %cond1, label %if.then2, label %if.else2163 164if.then2:165  br label %bb1166 167if.else2:168  br label %bb1169 170bb1:171  add i32 1, 2172  call void @alterRefCount()173  br label %join174 175if.else:176  call void @alterRefCount()177  call void @use(ptr %obj)178  br label %join179 180join:181  call void @llvm.objc.release(ptr %obj), !clang.imprecise_release !9182  ret void183}184 185declare void @llvm.dbg.declare(metadata, metadata, metadata)186declare ptr @llvm.objc.retain(ptr) local_unnamed_addr187declare void @llvm.objc.release(ptr) local_unnamed_addr188 189attributes #0 = { readonly }190 191!llvm.module.flags = !{!0, !1}192 193; CHECK: ![[EMPTYMETA]] = !{}194 195!0 = !{i32 2, !"Dwarf Version", i32 4}196!1 = !{i32 2, !"Debug Info Version", i32 3}197!2 = !DILocalVariable(name: "i", arg: 1, scope: !3, file: !4, line: 1, type: !7)198!3 = distinct !DISubprogram(name: "test", scope: !4, file: !4, line: 1, type: !5, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !8, retainedNodes: !9)199!4 = !DIFile(filename: "test.m", directory: "dir")200!5 = !DISubroutineType(types: !6)201!6 = !{!7, !7}202!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)203!8 = distinct !DICompileUnit(language: DW_LANG_ObjC, file: !4, isOptimized: false, runtimeVersion: 2, emissionKind: FullDebug, enums: !9, nameTableKind: None)204!9 = !{}205!10 = !DILocation(line: 1, column: 14, scope: !3)206!11 = !DILocalVariable(name: "foo", scope: !3, type: !7)207