139 lines · plain
1; RUN: opt -S -passes=objc-arc < %s | FileCheck %s2 3declare ptr @llvm.objc.loadWeak(ptr)4declare ptr @llvm.objc.loadWeakRetained(ptr)5declare ptr @llvm.objc.storeWeak(ptr, ptr)6declare ptr @llvm.objc.initWeak(ptr, ptr)7declare void @use_pointer(ptr)8declare void @callee()9 10; Basic redundant @llvm.objc.loadWeak elimination.11 12; CHECK: define void @test0(ptr %p) {13; CHECK-NEXT: %y = call ptr @llvm.objc.loadWeak(ptr %p)14; CHECK-NEXT: call void @use_pointer(ptr %y)15; CHECK-NEXT: ret void16; CHECK-NEXT: }17define void @test0(ptr %p) {18 %x = call ptr @llvm.objc.loadWeak(ptr %p)19 %y = call ptr @llvm.objc.loadWeak(ptr %p)20 call void @use_pointer(ptr %y)21 ret void22}23 24; DCE the @llvm.objc.loadWeak.25 26; CHECK: define void @test1(ptr %p) {27; CHECK-NEXT: %y = call ptr @llvm.objc.loadWeakRetained(ptr %p)28; CHECK-NEXT: call void @use_pointer(ptr %y)29; CHECK-NEXT: ret void30; CHECK-NEXT: }31define void @test1(ptr %p) {32 %x = call ptr @llvm.objc.loadWeak(ptr %p)33 %y = call ptr @llvm.objc.loadWeakRetained(ptr %p)34 call void @use_pointer(ptr %y)35 ret void36}37 38; Basic redundant @llvm.objc.loadWeakRetained elimination.39 40; CHECK: define void @test2(ptr %p) {41; CHECK-NEXT: %x = call ptr @llvm.objc.loadWeak(ptr %p)42; CHECK-NEXT: store i8 3, ptr %x43; CHECK-NEXT: %1 = tail call ptr @llvm.objc.retain(ptr %x)44; CHECK-NEXT: call void @use_pointer(ptr %x)45; CHECK-NEXT: ret void46; CHECK-NEXT: }47define void @test2(ptr %p) {48 %x = call ptr @llvm.objc.loadWeak(ptr %p)49 store i8 3, ptr %x50 %y = call ptr @llvm.objc.loadWeakRetained(ptr %p)51 call void @use_pointer(ptr %y)52 ret void53}54 55; Basic redundant @llvm.objc.loadWeakRetained elimination, this time56; with a readonly call instead of a store.57 58; CHECK: define void @test3(ptr %p) {59; CHECK-NEXT: %x = call ptr @llvm.objc.loadWeak(ptr %p)60; CHECK-NEXT: call void @use_pointer(ptr %x) [[RO:#[0-9]+]]61; CHECK-NEXT: %1 = tail call ptr @llvm.objc.retain(ptr %x)62; CHECK-NEXT: call void @use_pointer(ptr %x)63; CHECK-NEXT: ret void64; CHECK-NEXT: }65define void @test3(ptr %p) {66 %x = call ptr @llvm.objc.loadWeak(ptr %p)67 call void @use_pointer(ptr %x) readonly68 %y = call ptr @llvm.objc.loadWeakRetained(ptr %p)69 call void @use_pointer(ptr %y)70 ret void71}72 73; A regular call blocks redundant weak load elimination.74 75; CHECK: define void @test4(ptr %p) {76; CHECK-NEXT: %x = call ptr @llvm.objc.loadWeak(ptr %p)77; CHECK-NEXT: call void @use_pointer(ptr %x) [[RO]]78; CHECK-NEXT: call void @callee()79; CHECK-NEXT: %y = call ptr @llvm.objc.loadWeak(ptr %p)80; CHECK-NEXT: call void @use_pointer(ptr %y)81; CHECK-NEXT: ret void82; CHECK-NEXT: }83define void @test4(ptr %p) {84 %x = call ptr @llvm.objc.loadWeak(ptr %p)85 call void @use_pointer(ptr %x) readonly86 call void @callee()87 %y = call ptr @llvm.objc.loadWeak(ptr %p)88 call void @use_pointer(ptr %y)89 ret void90}91 92; Store to load forwarding.93 94; CHECK: define void @test5(ptr %p, ptr %n) {95; CHECK-NEXT: %1 = call ptr @llvm.objc.storeWeak(ptr %p, ptr %n)96; CHECK-NEXT: call void @use_pointer(ptr %n)97; CHECK-NEXT: ret void98; CHECK-NEXT: }99define void @test5(ptr %p, ptr %n) {100 call ptr @llvm.objc.storeWeak(ptr %p, ptr %n)101 %y = call ptr @llvm.objc.loadWeak(ptr %p)102 call void @use_pointer(ptr %y)103 ret void104}105 106; Store to load forwarding with objc_initWeak.107 108; CHECK: define void @test6(ptr %p, ptr %n) {109; CHECK-NEXT: %1 = call ptr @llvm.objc.initWeak(ptr %p, ptr %n)110; CHECK-NEXT: call void @use_pointer(ptr %n)111; CHECK-NEXT: ret void112; CHECK-NEXT: }113define void @test6(ptr %p, ptr %n) {114 call ptr @llvm.objc.initWeak(ptr %p, ptr %n)115 %y = call ptr @llvm.objc.loadWeak(ptr %p)116 call void @use_pointer(ptr %y)117 ret void118}119 120; Don't forward if there's a may-alias store in the way.121 122; CHECK: define void @test7(ptr %p, ptr %n, ptr %q, ptr %m) {123; CHECK-NEXT: call ptr @llvm.objc.initWeak(ptr %p, ptr %n)124; CHECK-NEXT: call ptr @llvm.objc.storeWeak(ptr %q, ptr %m)125; CHECK-NEXT: %y = call ptr @llvm.objc.loadWeak(ptr %p)126; CHECK-NEXT: call void @use_pointer(ptr %y)127; CHECK-NEXT: ret void128; CHECK-NEXT: }129define void @test7(ptr %p, ptr %n, ptr %q, ptr %m) {130 call ptr @llvm.objc.initWeak(ptr %p, ptr %n)131 call ptr @llvm.objc.storeWeak(ptr %q, ptr %m)132 %y = call ptr @llvm.objc.loadWeak(ptr %p)133 call void @use_pointer(ptr %y)134 ret void135}136 137; CHECK: attributes #0 = { nounwind }138; CHECK: attributes [[RO]] = { memory(read) }139