https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80210

Peter Bergner <bergner at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|CLOSED                      |ASSIGNED
                 CC|                            |schwab at gcc dot gnu.org
         Resolution|FIXED                       |---

--- Comment #15 from Peter Bergner <bergner at gcc dot gnu.org> ---
David and Andreas have reported that they are seeing ICEs on powerpc-aix and
powerpc-linux (32-bit) with the test case added as part of the fix for this
bug.  I didn't see this on my BE builds, because my build scripts were using
the --with-cpu=... configure command and using any -mcpu=... option will work
around the bug.  The bug isn't due to my earlier, since the ICE existed before
my patch, we just didn't have the test case to notice before.  

The problem they are seeing is due to a mismatch between TARGET_DEFAULT, which
contains MASK_PPC_GPOPT and the ISA flags for the default "powerpc64" cpu,
which does not contain MASK_PPC_GPOPT and how rs6000_option_override_internal()
decides which one to use.  The failure scenario is:

Early on, we call init_all_optabs() which setups up a table which describes
which patterns that generate some HW insns are "valid".  Before we call
init_all_optabs(), rs6000_option_override_internal() gets called with
global_init_p arg set to "true" and we basically set rs6000_isa_flags to
TARGET_DEFAULT.  This is because we do not have a -mcpu= value nor do we have
an "implicit_cpu", which forces us to use TARGET_DEFAULT.  With this,
init_all_optabs() thinks we can generate a HW sqrt, so it enables generating
its pattern.

Later, after we've scanned the entire file, we go to expand our function into
RTL and we reset our compiler options and we end up calling
rs6000_option_override_internal() again, but with global_init_p arg now false
and we encounter this code:

  struct cl_target_option *main_target_opt
    = ((global_init_p || target_option_default_node == NULL)
       ? NULL : TREE_TARGET_OPTION (target_option_default_node));

This ends up setting main_target_opt to a non-NULL value, then:

  ...
  else if (main_target_opt != NULL && main_target_opt->x_rs6000_cpu_index >= 0)
    {
      rs6000_cpu_index = cpu_index = main_target_opt->x_rs6000_cpu_index;
      have_cpu = true;
    }

So now we act as if the user explicitly passed in a -mcpu= option, then:

  ...
  /* If we have a cpu, either through an explicit -mcpu=<xxx> or if the
     compiler was configured with --with-cpu=<xxx>, replace all of the ISA bits
     with those from the cpu, except for options that were explicitly set.  If
     we don't have a cpu, do not override the target bits set in
     TARGET_DEFAULT.  */
  if (have_cpu)
    {
      rs6000_isa_flags &= ~set_masks;
      rs6000_isa_flags |= (processor_target_table[cpu_index].target_enable
                           & set_masks);
    }
  else
    {
      /* If no -mcpu=<xxx>, inherit any default options that were cleared via
         POWERPC_MASKS.  Originally, TARGET_DEFAULT was used to initialize
         target_flags via the TARGET_DEFAULT_TARGET_FLAGS hook.  When we
switched
         to using rs6000_isa_flags, we need to do the initialization here.

         If there is a TARGET_DEFAULT, use that.  Otherwise fall back to using
         -mcpu=powerpc, -mcpu=powerpc64, or -mcpu=powerpc64le defaults.  */
      HOST_WIDE_INT flags = ((TARGET_DEFAULT) ? TARGET_DEFAULT
                             :
processor_target_table[cpu_index].target_enable);
      rs6000_isa_flags |= (flags & ~rs6000_isa_flags_explicit);
    }

So the first time through here with global_init_p == true, have_cpu is set to
false and we get TARGET_DEFAULT.  The next time we come here, global_init_p ==
false and we set have_cpu to true because main_target_opt is non-NULL and the
cpu_index value is set to "powerpc64" (for -m64 compiles) or "powerpc" (for
-m32 compiles).  This causes us to now grab the ISA flags from:

  processor_target_table[cpu_index].target_enable

...instead of from TARGET_DEFAULT and neither "powerpc64" nor "powerpc" contain
the MASK_PPC_GPOPT flag, which leads us to ICE because the optabs allows us to
generate the HW sqrt pattern, but our ISA flags don't allow it.

This doesn't affect LE builds, because it has a TARGET_DEFAULT value that
matches the "powerpc64le" default masks.  We also enforce passing a
-mcpu=power8 option when the user doesn't explicitly use one, so again, not a
problem.

This also doesn't affect --target=powerpc-linux builds or
--target=powerpc64-linux builds that default to 32-bit binaries, because we use
a value of TARGET_DEFAULT == 0 (for both -m32 and -m64), so the first time
through rs6000_option_override_internal(), we end up using
processor_target_table[cpu_index].target_enable right from the beginning.

Reply via email to