Autovivification requires an lvalue "context". Just reading a value won't autovivify it. Both defined and exists are known to Perl to be read-only and so won't autovivify the last level of dereferencing.
Just testing a hash also won't autovivify (the last level). So I disagree with tobyink's "this would make the defined keyword kinda useless" because it hints that defined is somehow preventing autovivification. That's particularly problematic because that is actually a common misconception. Just testing defined or exists has no different behavior with regard to autovivification than directly testing the hash entry does.
And even when some function "would be passed the contents of the *value* slot of [an] entry", that isn't always enough to cause autovivification. Perl is (sometimes) smart enough to make the autovivification dependent on whether the function actually makes a modification.
my %hash;
sub list { print join( ' ', sort keys %hash ), $/ }
for( $hash{for} ) {
# Don't do a single thing to $_
}
list(); # 'for' entry autovivified unconditionally
sub maybeset { for( $_[0] ) { $_ = $_[1] if 1 < @_ }; list() }
maybeset( $hash{maybe} ); # no 'maybe', despite the for() in th
+e sub
maybeset( $hash{set}, 'hello' ); # now 'for set'