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.