On Wed, Jun 20, 2018 at 8:26 PM Paul Koning <paulkon...@comcast.net> wrote:
>
> I'm running into an ICE in the GIMPLE phase, for gcc.c-torture/compile/386.c, 
> on pdp11 -mint32.  That's an oddball where int is 32 bits (due to the flag) 
> but Pmode is 16 bits (HImode).
>
> The ICE message is:
>
> ../../gcc/gcc/testsuite/gcc.c-torture/compile/386.c: In function ‘main’:
> ../../gcc/gcc/testsuite/gcc.c-torture/compile/386.c:24:1: error: invalid 
> types in nop conversion
>  }
>  ^
> int
> int *
> b_3 = (int) &i;
> during GIMPLE pass: einline
> ../../gcc/gcc/testsuite/gcc.c-torture/compile/386.c:24:1: internal compiler 
> error: verify_gimple failed
>
> The offending code snippet is (I think):
>
> main ()
> {
>   int i;
>   foobar (i, &i);
> }
>
>
> foobar (a, b)
> {
>   int c;
>
>   c = a % b;
>   a = a / b;
>   return a + b;
> }
>
> where the foobar(i, &i) call passes an int* to a (defaulted) int function 
> parameter.  Is there an assumption that sizeof (int*) >= sizeof(int)?
>
> Any idea where to look?  It only shows up with -mint32; if int is 16 bits all 
> is well.  I'm not used to my target breaking things before I even get to 
> RTL...

Inlining allows some type mismatches mainly because at callers FEs may
have done promotion while callees usually
see unpromoted PARM_DECLs.  The inliner then inserts required
conversions.  In this case we do not allow widening conversions
from pointers without intermediate conversions to integers.  The
following ICEs in a similar way on x86 (with -m32):

main ()
{
  int i;
  foobar (i, &i);
}


foobar (int a, long long b)
{
  int c;

  c = a % b;
  a = a / b;
  return a + b;
}

so the inliner should avoid inlining in this case or alternatively
simulate what the target does
(converting according to POINTERS_EXTEND_UNSIGNED).

A fix could be as simple as

diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 4568e1e2b57..8476c223e4f 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -2358,7 +2358,9 @@ fold_convertible_p (const_tree type, const_tree arg)
     case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
     case POINTER_TYPE: case REFERENCE_TYPE:
     case OFFSET_TYPE:
-      return (INTEGRAL_TYPE_P (orig) || POINTER_TYPE_P (orig)
+      return (INTEGRAL_TYPE_P (orig)
+             || (POINTER_TYPE_P (orig)
+                 && TYPE_PRECISION (type) <= TYPE_PRECISION (orig))
              || TREE_CODE (orig) == OFFSET_TYPE);

     case REAL_TYPE:

which avoids the inlining (if that is the desired solution).

Can you open a PR please?

Thanks,
Richard.

>         paul
>

Reply via email to