On Wed, Jun 20, 2018 at 8:26 PM Paul Koning <[email protected]> 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
>