"Robin Dapp" <[email protected]> writes:
>> That doesn't look right.  The CONCATNs are generated by the pass 
>> itself
>> and can't be left as-is.  The failure path for !resolve_subreg_p is
>> also different from the failure path for !simplify_subreg_concatn.
>>
>> So it feels like the problem is elsewhere to me.
>
> Yes, agreed.
>
> What we're decomposing is
>
> (insn 4 3 5 2 (set (subreg:DI (reg:TI 137) 0)
>         (subreg:DI (reg:TI 138) 0)) "pr44136.c":20:1 275 {*movdi_64bit}
>      (nil))
> (insn 5 4 39 2 (set (subreg:DI (reg:TI 137) 8)
>         (subreg:DI (reg:TI 138) 8)) "pr44136.c":20:1 275 {*movdi_64bit}
>      (nil))
> (debug_insn 39 5 38 2 (var_location:V4SF D#4 (subreg:V4SF (reg:TI 137) 0)) -1
>      (nil))
>
> Neither (subreg:V4SF (reg:TI)) nor (subreg:V4SF (concatn [(reg:DI) 
> (reg:DI)])) look harmful from a regmode-natural-size point of view.
>
> Therefore, I wonder if the interesting_mode_p checks in 
> simplify_subreg_concatn aren't over-eager now that we restricted them 
> further.  simplify_subreg_concatn doesn't even try splitting but just 
> builds a new subreg for which we only need to verify that the mode sizes 
> are constant.
>
> As we filter out the problematic cases before, my try would be to just 
> return NULL like:
>
> @@ -649,16 +666,19 @@ decompose_register (unsigned int regno)
>  static rtx
>  simplify_subreg_concatn (machine_mode outermode, rtx op, poly_uint64 
> orig_byte)
>  {
> -  unsigned int outer_size, outer_words, inner_size, inner_words;
> +  unsigned int outer_size, inner_size;
>    machine_mode innermode, partmode;
>    rtx part;
>    unsigned int final_offset;
>    unsigned int byte;
>  
>    innermode = GET_MODE (op);
> -  if (!interesting_mode_p (outermode, &outer_size, &outer_words)
> -      || !interesting_mode_p (innermode, &inner_size, &inner_words))
> -    gcc_unreachable ();
> +
> +  if (!GET_MODE_SIZE (innermode).is_constant (&inner_size))
> +    return NULL_RTX;
> +  if (!GET_MODE_SIZE (outermode).is_constant (&outer_size)
> +      || !orig_byte.is_constant ())
> +    return NULL_RTX;

I think the inner_size part does still make sense as:

  if (!interesting_mode_p (innermode, &inner_size, &inner_words))
    gcc_unreachable ();

But I agree that it's now the wrong check for the outer_size check
(and I suppose was always a false abstraction).

If outermode is constant size then orig_byte must be too.

The comment in:

  /* Must be constant if interesting_mode_p passes.  */
  byte = orig_byte.to_constant ();

would need to be updated.  So I guess that makes it:

  if (!interesting_mode_p (innermode, &inner_size, &inner_words))
    gcc_unreachable ();

  if (!GET_MODE_SIZE (outermode).is_constant (&outer_size))
    return NULL_RTX;

  /* Must be constant if outer_size is.  */
  byte = orig_byte.to_constant ();

LGTM with that variation.

Thanks,
Richard

Reply via email to