Code: @interface AClass : NSObject @end @implementation AClass { id ivar; } - (void)aMethod { ivar = @1; } - (void)test { id local = ivar; [self aMethod]; @[local, ivar]; } @end Before: We store the local into the temporary buffer on line 12, but release it on line 19 before the buffer is used on line 23. 1 define internal void @"\01-[AClass test]"(%0* %self, i8* nocapture %_cmd) #0 { 2 %1 = alloca [2 x i8*], align 8 3 %2 = load i64* @"OBJC_IVAR_$_AClass.ivar", align 8, !invariant.load !4 4 %3 = bitcast %0* %self to i8* 5 %4 = getelementptr inbounds i8* %3, i64 %2 6 %5 = bitcast i8* %4 to i8** 7 %6 = load i8** %5, align 8, !tbaa !5 8 %7 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_2", align 8, !invariant.load !4 9 %8 = tail call i8* @objc_retain(i8* %6) #3 10 call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*)*)(i8* %3, i8* %7), !clang.arc.no_objc_arc_exceptions !4 11 %9 = getelementptr inbounds [2 x i8*]* %1, i64 0, i64 0 12 store i8* %6, i8** %9, align 8 13 %10 = getelementptr inbounds [2 x i8*]* %1, i64 0, i64 1 14 %11 = load i64* @"OBJC_IVAR_$_AClass.ivar", align 8, !invariant.load !4 15 %12 = getelementptr inbounds i8* %3, i64 %11 16 %13 = bitcast i8* %12 to i8** 17 %14 = load i8** %13, align 8, !tbaa !5 18 call void @objc_release(i8* %6) #3, !clang.imprecise_release !4 19 store i8* %14, i8** %10, align 8 20 %15 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_3", align 8 21 %16 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_5", align 8, !invariant.load !4 22 %17 = bitcast %struct._class_t* %15 to i8* 23 %18 = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8**, i64)*)(i8* %17, i8* %16, i8** %9, i64 2), !clang.arc.no_objc_arc_exceptions !4 24 %19 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %18) #3 25 call void @objc_release(i8* %18) #3 26 ret void 27 } After: The release is gone, and there's an array cleanup instead. 1 define internal void @"\01-[AClass test]"(%0* %self, i8* nocapture %_cmd) #0 { 2 entry: 3 %objects = alloca [2 x i8*], align 8 4 %ivar = load i64* @"OBJC_IVAR_$_AClass.ivar", align 8, !invariant.load !4 5 %0 = bitcast %0* %self to i8* 6 %add.ptr = getelementptr inbounds i8* %0, i64 %ivar 7 %1 = bitcast i8* %add.ptr to i8** 8 %2 = load i8** %1, align 8, !tbaa !5 9 %3 = tail call i8* @objc_retain(i8* %2) #3 10 %4 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_2", align 8, !invariant.load !4 11 call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*)*)(i8* %0, i8* %4), !clang.arc.no_objc_arc_exceptions !4 12 %5 = getelementptr inbounds [2 x i8*]* %objects, i64 0, i64 0 13 %6 = tail call i8* @objc_retain(i8* %2) #3 14 store i8* %2, i8** %5, align 8 15 %7 = getelementptr inbounds [2 x i8*]* %objects, i64 0, i64 1 16 %ivar1 = load i64* @"OBJC_IVAR_$_AClass.ivar", align 8, !invariant.load !4 17 %add.ptr2 = getelementptr inbounds i8* %0, i64 %ivar1 18 %8 = bitcast i8* %add.ptr2 to i8** 19 %9 = load i8** %8, align 8, !tbaa !5 20 %10 = tail call i8* @objc_retain(i8* %9) #3 21 store i8* %9, i8** %7, align 8 22 %11 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_3", align 8 23 %12 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_5", align 8, !invariant.load !4 24 %13 = bitcast %struct._class_t* %11 to i8* 25 %call = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8**, i64)*)(i8* %13, i8* %12, i8** %5, i64 2), !clang.arc.no_objc_arc_exceptions !4 26 %14 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %call) #3 27 call void @objc_release(i8* %call) #3 28 %15 = getelementptr inbounds [2 x i8*]* %objects, i64 0, i64 2 29 br label %arraydestroy.body 30 31 arraydestroy.body: ; preds = %arraydestroy.body, %entry 32 %arraydestroy.elementPast = phi i8** [ %15, %entry ], [ %arraydestroy.element, %arraydestroy.body ] 33 %arraydestroy.element = getelementptr inbounds i8** %arraydestroy.elementPast, i64 -1 34 %16 = load i8** %arraydestroy.element, align 8 35 call void @objc_release(i8* %16) #3, !clang.imprecise_release !4 36 %arraydestroy.done = icmp eq i8** %arraydestroy.element, %5 37 br i1 %arraydestroy.done, label %arraydestroy.done3, label %arraydestroy.body 38 39 arraydestroy.done3: ; preds = %arraydestroy.body 40 call void @objc_release(i8* %2) #3, !clang.imprecise_release !4 41 ret void 42 }