I have it down to a deliberate conversion from signed
to unsigned:
temp.txt: bbb piss ccc 32 32
temp.txt: bbb piss ccc2 0 1
temp.txt: bbb piss ddd -2
temp.txt: bbb - in convert
temp.txt: bbb - converting to integer
temp.txt: bbb y stage1
temp.txt: bbb y stage2
temp.txt: bbb y outprec thing, inprec 32, outprec 32
temp.txt: bbb - in build1
temp.txt: bbb - build1 code 115
temp.txt: bbb - build1 - default
temp.txt: bbb - node is currently -2
temp.txt: bbb - build1 - setting constant
temp.txt: bbb in fold
temp.txt: bbb fold2
temp.txt: bbb fold2b 115
temp.txt: bbb fold2d 77 115 61
temp.txt: bbb fold4
temp.txt: bbb fold5
temp.txt: bbb -2 -1
temp.txt: bbbj 0
temp.txt: bbb piss eee 4294967294
Which then gets preserved, because HOST_WIDE_INT (long) is 64 bits.
And I see no attempt to put it back to a signed value in the below code.
I'm not sure how it is supposed to work.
I'll see if I can get further tomorrow.
Oh, I also switched the code fragment to:
D:\devel\gcc\gcc>type foo.c
int foo(long *in)
{
return in[-2];
}
So that the multiply by 8 (size of long) is more obvious (in other
debug output).
BFN. Paul.
/* Return a tree for the sum or difference (RESULTCODE says which)
of pointer PTROP and integer INTOP. */
tree
pointer_int_sum (resultcode, ptrop, intop)
enum tree_code resultcode;
tree ptrop, intop;
...
/* Convert the integer argument to a type the same size as sizetype
so the multiply won't overflow spuriously. */
if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype)
|| TREE_UNSIGNED (TREE_TYPE (intop)) != TREE_UNSIGNED (sizetype))
{
printf("bbb piss ccc %d %d\n",
(int)TYPE_PRECISION (TREE_TYPE (intop)), (int)TYPE_PRECISION (sizetype)
);
printf("bbb piss ccc2 %d %d\n",
(int)TREE_UNSIGNED (TREE_TYPE (intop)),
(int)TREE_UNSIGNED (sizetype));
printf("bbb piss ddd %ld\n", (long)TREE_INT_CST_LOW((intop)));
intop = convert (type_for_size (TYPE_PRECISION (sizetype),
TREE_UNSIGNED (sizetype)), intop);
printf("bbb piss eee %ld\n", (long)TREE_INT_CST_LOW((intop)));
}
/* Replace the integer argument with a suitable product by the object
size.
Do this multiplication as signed, then convert to the appropriate
pointer type (actually unsigned integral). */
printf("bbb piss3\n");
intop = convert (result_type,
build_binary_op (MULT_EXPR, intop,
convert (TREE_TYPE (intop), size_exp),
1));
/* Create the sum or difference. */
result = build (resultcode, result_type, ptrop, intop);
printf("bbb piss4\n");
folded = fold (result);
if (folded == result)
TREE_CONSTANT (folded) = TREE_CONSTANT (ptrop) & TREE_CONSTANT (intop);
return folded;
}
On Sat, 10 Feb 2024 at 05:38, Paul Edwards <[email protected]> wrote:
> Oh - I switched to -2 to make debugging easier:
>
> D:\devel\gcc\gcc>type foo.c
> int foo(char *in)
> {
> return in[-2];
> }
>
> D:\devel\gcc\gcc>
>
>
> Note that my flavor of gcc 3.2.3 can be found in gcc-stage*.zip
> in custom.zip at http://pdos.org
>
>
>
>
> On Sat, 10 Feb 2024 at 05:34, Paul Edwards <[email protected]> wrote:
>
>> On Wed, 7 Feb 2024 at 23:12, Jakub Jelinek <[email protected]> wrote:
>> On Wed, Feb 07, 2024 at 11:02:51PM +0800, Paul Edwards via Gcc wrote:
>>
>> >> I am using a slightly modified gcc 3.2.3 for x86_64 and for this code:
>>
>> > Don't, gcc 3.2.3 is not supported for more than 20 years already.
>>
>> And the i370 target hasn't been supported for that long
>> either - but that's a target I want too.
>>
>> And nor has any version ever run on MVS 3.8J - but
>> that's an execution platform I want too.
>>
>> And the same goes for PDOS/386 as an execution platform.
>>
>> >> int fff(char *x)
>> >> {
>> >> return (x[-1]);
>> >> }
>> >
>> >> It is generating:
>> >
>> >> .globl fff
>> >> fff:
>> >> .LFB2:
>> >> movl $4294967295, %eax
>> >> movsbl (%rax,%rcx),%eax
>>
>> > That said, I can't reproduce it and get
>> > movsbl -1(%rdi),%eax
>> > ret
>> > from 3.2.3.
>>
>> Thanks for that! So one of the "slight modifications"
>> was to switch to Win64 ABI, which is why rcx is being
>> selected instead of rdi. So that bit is expected.
>>
>> So I need to know why I'm not getting -1.
>>
>> Since your email I have been trying to explain that.
>> It is likely a problem with the C library I am using
>> (PDPCLIB) - strtol or something like that.
>>
>> I am using 64-bit longs and I can see that that large
>> value (-1 as unsigned 32-bit) is being stored in the
>> 64-bit field and being preserved.
>>
>> So far I have tracked it down to happening in the
>> early stages. fold() is called and I can see that it
>> is initially good for something, and bad later.
>>
>> I'm still working on it.
>>
>> BFN. Paul.
>>
>>
>> fold-const.c
>>
>> tree
>> fold (expr)
>> tree expr;
>> {
>> tree t = expr;
>> tree t1 = NULL_TREE;
>> tree tem;
>> tree type = TREE_TYPE (expr);
>> tree arg0 = NULL_TREE, arg1 = NULL_TREE;
>> enum tree_code code = TREE_CODE (t);
>> int kind = TREE_CODE_CLASS (code);
>> int invert;
>> /* WINS will be nonzero when the switch is done
>> if all operands are constant. */
>> int wins = 1;
>>
>> printf("bbb in fold\n");
>> /* Don't try to process an RTL_EXPR since its operands aren't trees.
>> Likewise for a SAVE_EXPR that's already been evaluated. */
>> if (code == RTL_EXPR || (code == SAVE_EXPR && SAVE_EXPR_RTL (t) != 0))
>> return t;
>>
>> /* Return right away if a constant. */
>> if (kind == 'c')
>> return t;
>>
>> printf("bbb fold2\n");
>> printf("bbb fold2b %d\n", (int)TREE_CODE(t));
>> if (TREE_CODE (t) == INTEGER_CST)
>> {
>> printf("bbb fold2c is %ld\n",
>> (long)TREE_INT_CST_LOW (t));
>> }
>>
>>
>> ...
>>
>>
>> /* If this is a commutative operation, and ARG0 is a constant, move it
>> to ARG1 to reduce the number of tests below. */
>> if ((code == PLUS_EXPR || code == MULT_EXPR || code == MIN_EXPR
>> || code == MAX_EXPR || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR
>> || code == BIT_AND_EXPR)
>> && (TREE_CODE (arg0) == INTEGER_CST || TREE_CODE (arg0) ==
>> REAL_CST))
>> {
>> printf("bbb fold3\n");
>> printf("bbb fold3b is %ld\n",
>> (long)TREE_INT_CST_LOW (arg0));
>>
>> tem = arg0; arg0 = arg1; arg1 = tem;
>>
>> tem = TREE_OPERAND (t, 0); TREE_OPERAND (t, 0) = TREE_OPERAND (t,
>> 1);
>> TREE_OPERAND (t, 1) = tem;
>> }
>>
>> printf("bbb fold4\n");
>>
>>
>>
>> temp.txt: bbb fold2
>> temp.txt: bbb fold2b 77
>> temp.txt: bbb fold4
>> temp.txt: bbb fold5
>> temp.txt: bbb -2 -1
>> temp.txt: bbbj 0
>> temp.txt: bbbs1
>> temp.txt: bbbs2
>> temp.txt: bbbs9
>> temp.txt: bbbq
>> temp.txt: bbb in fold
>> temp.txt: bbb fold2
>> temp.txt: bbb fold2b 115
>> temp.txt: bbb fold4
>> temp.txt: bbb fold5
>> temp.txt: bbb -2 -1
>> temp.txt: bbbj 0
>> temp.txt: bbb in fold
>> temp.txt: bbb fold2
>> temp.txt: bbb fold2b 115
>> temp.txt: bbb fold4
>> temp.txt: bbb fold5
>> temp.txt: bbb 1 0
>> temp.txt: bbbj 0
>> temp.txt: bbbq
>> temp.txt: bbb about to do build
>> temp.txt: bbbo
>> temp.txt: bbb done build
>> temp.txt: bbb in fold
>> temp.txt: bbb fold2
>> temp.txt: bbb fold2b 61
>> temp.txt: bbb fold3
>> temp.txt: bbb fold3b is 4294967294
>> temp.txt: bbb fold4
>> temp.txt: bbb fold5
>> temp.txt: bbb 4294967294 0
>>
>>