@@ -266,9 +266,6 @@ S_adjust_index(pTHX_ AV *av, const MAGIC *mg, SSize_t *keyp)
266266SV * *
267267Perl_av_fetch (pTHX_ AV * av , SSize_t key , I32 lval )
268268{
269- SSize_t neg ;
270- SSize_t size ;
271-
272269 PERL_ARGS_ASSERT_AV_FETCH ;
273270
274271 if (UNLIKELY (SvRMAGICAL (av ))) {
@@ -291,24 +288,23 @@ Perl_av_fetch(pTHX_ AV *av, SSize_t key, I32 lval)
291288 }
292289 }
293290
294- neg = (key < 0 );
295- size = AvFILLp (av ) + 1 ;
296- key += neg * size ; /* handle negative index without using branch */
291+ /* recalculating key early helps branch prediction */
292+ SSize_t neg = key < 0 ;
293+ SSize_t size = AvFILLp (av ) + 1 ;
294+ key += neg * size ;
297295
298296 /* the cast from SSize_t to Size_t allows both (key < 0) and (key >= size)
299297 * to be tested as a single condition */
300- if ((Size_t )key >= (Size_t )size ) {
301- if (UNLIKELY (neg ))
302- return NULL ;
303- goto emptiness ;
304- }
305-
306- if (!AvARRAY (av )[key ]) {
307- emptiness :
308- return lval ? av_store (av ,key ,newSV_type (SVt_NULL )) : NULL ;
309- }
310-
311- return & AvARRAY (av )[key ];
298+ if ((Size_t )key >= (Size_t )size )
299+ /* Only non-negative out of bounds keys are eligible for lvalue
300+ * treatment, so adjust lval by setting value to 0 if the key was
301+ * negative */
302+ lval *= !neg ;
303+ else if (AvARRAY (av )[key ])
304+ return & AvARRAY (av )[key ];
305+
306+ /* value does not exist in the array */
307+ return lval ? av_store (av , key , newSV_type (SVt_NULL )) : NULL ;
312308}
313309
314310/*
0 commit comments