> -----Original Message-----
> From: Richard Biener <[email protected]>
> Sent: 26 January 2026 08:11
> To: Tamar Christina <[email protected]>
> Cc: [email protected]; nd <[email protected]>; [email protected]
> Subject: Re: [PATCH][vect]: distinguish between MASK_CALL and non-
> trapping calls [PR123628]
> 
> On Mon, 26 Jan 2026, Tamar Christina wrote:
> 
> > In the Fix for PR122103 an ambiguity was introduced when it comes to
> fortran
> > due to an inconsistency in libmvec headers.
> >
> > A reproducer is
> >
> > !GCC$ builtin (expf) attributes simd (notinbranch)
> > SUBROUTINE a(b)
> >    REAL, DIMENSION(:) :: b
> >    c: DO i = 1, d
> >    IF (e <= f) THEN
> >       g = EXP(h)
> >       r = g
> >       IF (r > s) THEN
> >          b(i) = t
> >       END IF
> >    END IF
> >    END DO c
> > END
> >
> > compiled with -O2 -march=armv8-a+sve, note that fortran, unlike C provides
> the
> > libmvec header math-vector-fortran.h unconditionally, which is a separate
> bug
> > PR118955 which causes the functions to become available outside of -Ofast.
> >
> > This means the cases for MASK_CALL and trapping math overlap for fortran
> at -O2.
> >
> > The new masking code shouldn't handle SIMD clones.
> >
> > Bootstrapped Regtested on aarch64-none-linux-gnu,
> > arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
> > -m32, -m64 and no issues.
> >
> > Pushed.
> 
> Thanks.  Another possibility would have been to always create
> a .MASK_CALL and leave checking/failure to the vectorizer.  Of course
> doing it in if-conversion will be better for compile time.
> 

True, I need to extend this in GCC 17 anyway to support masking arbitrary
builtins to support HVLA, so .MASK_CALL as a default fall back would be
good.  But as you say rejecting them early on e.g. (Adv. SIMD can't do masking)
can save a lot of time :).

Thanks,
Tamar

> Richard.
> 
> > Thanks,
> > Tamar
> >
> > gcc/ChangeLog:
> >
> >     PR tree-optimization/122103
> >     PR tree-optimization/123628
> >     * tree-if-conv.cc (if_convertible_simdclone_stmt_p): New.
> >     (if_convertible_stmt_p, predicate_statements): Use it.
> >
> > gcc/testsuite/ChangeLog:
> >
> >     PR tree-optimization/122103
> >     PR tree-optimization/123628
> >     * gfortran.target/aarch64/pr123628.f90: New test.
> >
> > ---
> > diff --git a/gcc/testsuite/gfortran.target/aarch64/pr123628.f90
> b/gcc/testsuite/gfortran.target/aarch64/pr123628.f90
> > new file mode 100644
> > index
> 0000000000000000000000000000000000000000..5a42434890c332c7eb
> 1619b84d9eac486fe89d86
> > --- /dev/null
> > +++ b/gcc/testsuite/gfortran.target/aarch64/pr123628.f90
> > @@ -0,0 +1,16 @@
> > +! { dg-do compile }
> > +! { dg-options "-O2 -march=armv9-a -fdump-tree-ifcvt -w" }
> > +! { dg-final { scan-tree-dump {.MASK_CALL \(__builtin_expf, } ifcvt } }
> > +!GCC$ builtin (expf) attributes simd (notinbranch)
> > +SUBROUTINE a(b)
> > +   REAL, DIMENSION(:) :: b
> > +   c: DO i = 1, d
> > +   IF (e <= f) THEN
> > +      g = EXP(h)
> > +      r = g
> > +      IF (r > s) THEN
> > +         b(i) = t
> > +      END IF
> > +   END IF
> > +   END DO c
> > +END
> > diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc
> > index
> 51fbcc128c671d749bd97dfa91f6f4b605eb8f82..d728f7c5221c66c2fd963d
> 3e3ab55b232e628cb0 100644
> > --- a/gcc/tree-if-conv.cc
> > +++ b/gcc/tree-if-conv.cc
> > @@ -1120,6 +1120,36 @@ if_convertible_switch_p (gswitch *sw)
> >    return true;
> >  }
> >
> > +/* Return true when STMT is an if-convertible SIMD clone stmts.
> > +
> > +   A SIMD clone statement is if-convertible if:
> > +    - it is an GIMPLE_CALL,
> > +    - it has a FNDECL,
> > +    - it has SIMD clones,
> > +    - it has at least one inbranch clone.  */
> > +static bool
> > +if_convertible_simdclone_stmt_p (gimple *stmt)
> > +{
> > +  if (!is_gimple_call (stmt))
> > +    return false;
> > +
> > +  tree fndecl = gimple_call_fndecl (stmt);
> > +  if (fndecl)
> > +    {
> > +      /* We can vectorize some builtins and functions with SIMD "inbranch"
> > +    clones.  */
> > +      struct cgraph_node *node = cgraph_node::get (fndecl);
> > +      if (node && node->simd_clones != NULL)
> > +   /* Ensure that at least one clone can be "inbranch".  */
> > +   for (struct cgraph_node *n = node->simd_clones; n != NULL;
> > +        n = n->simdclone->next_clone)
> > +     if (n->simdclone->inbranch)
> > +       return true;
> > +    }
> > +
> > +  return false;
> > +}
> > +
> >  /* Return true when STMT is if-convertible.
> >
> >     A statement is if-convertible if:
> > @@ -1147,22 +1177,12 @@ if_convertible_stmt_p (gimple *stmt,
> vec<data_reference_p> refs)
> >
> >      case GIMPLE_CALL:
> >        {
> > -   tree fndecl = gimple_call_fndecl (stmt);
> > -   if (fndecl)
> > +   /* Check if stmt is a simd clone first.  */
> > +   if (if_convertible_simdclone_stmt_p (stmt))
> >       {
> > -       /* We can vectorize some builtins and functions with SIMD
> > -          "inbranch" clones.  */
> > -       struct cgraph_node *node = cgraph_node::get (fndecl);
> > -       if (node && node->simd_clones != NULL)
> > -         /* Ensure that at least one clone can be "inbranch".  */
> > -         for (struct cgraph_node *n = node->simd_clones; n != NULL;
> > -              n = n->simdclone->next_clone)
> > -           if (n->simdclone->inbranch)
> > -             {
> > -               gimple_set_plf (stmt, GF_PLF_2, true);
> > -               need_to_predicate = true;
> > -               return true;
> > -             }
> > +       gimple_set_plf (stmt, GF_PLF_2, true);
> > +       need_to_predicate = true;
> > +       return true;
> >       }
> >
> >     /* Check if the call can trap and if so require predication.  */
> > @@ -3108,7 +3128,8 @@ predicate_statements (loop_p loop)
> >         }
> >       else if (gimple_plf (stmt, GF_PLF_2)
> >                && (is_gimple_assign (stmt)
> > -                  || gimple_call_builtin_p (stmt)))
> > +                  || (gimple_call_builtin_p (stmt)
> > +                      && !if_convertible_simdclone_stmt_p (stmt))))
> >         {
> >           tree lhs = gimple_get_lhs (stmt);
> >           /* ?? Assume that calls without an LHS are not data processing
> >
> >
> >
> 
> --
> Richard Biener <[email protected]>
> SUSE Software Solutions Germany GmbH,
> Frankenstrasse 146, 90461 Nuernberg, Germany;
> GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG
> Nuernberg)

Reply via email to