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 >