public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* gcc 3.2.3 x64 negative indexes
@ 2024-02-07 15:02 Paul Edwards
  2024-02-07 15:12 ` Jakub Jelinek
  0 siblings, 1 reply; 8+ messages in thread
From: Paul Edwards @ 2024-02-07 15:02 UTC (permalink / raw)
  To: GCC Development

[-- Attachment #1: Type: text/plain, Size: 475 bytes --]

Hi.

I am using a slightly modified gcc 3.2.3 for x86_64 and for this code:

int fff(char *x)
{
return (x[-1]);
}


It is generating:

.globl fff
fff:
.LFB2:
        movl    $4294967295, %eax
        movsbl  (%rax,%rcx),%eax
        ret


My understanding is that that move of -1 into eax
does NOT sign-extend, and thus results in a very
high index, which causes a crash.

I may have stuffed something up myself.

Anyone know which code governs this behavior?

Thanks. Paul.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: gcc 3.2.3 x64 negative indexes
  2024-02-07 15:02 gcc 3.2.3 x64 negative indexes Paul Edwards
@ 2024-02-07 15:12 ` Jakub Jelinek
  2024-02-09 21:34   ` Paul Edwards
  0 siblings, 1 reply; 8+ messages in thread
From: Jakub Jelinek @ 2024-02-07 15:12 UTC (permalink / raw)
  To: Paul Edwards; +Cc: GCC Development

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.

> 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.

	Jakub


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: gcc 3.2.3 x64 negative indexes
  2024-02-07 15:12 ` Jakub Jelinek
@ 2024-02-09 21:34   ` Paul Edwards
  2024-02-09 21:38     ` Paul Edwards
  0 siblings, 1 reply; 8+ messages in thread
From: Paul Edwards @ 2024-02-09 21:34 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: GCC Development

[-- Attachment #1: Type: text/plain, Size: 3783 bytes --]

On Wed, 7 Feb 2024 at 23:12, Jakub Jelinek <jakub@redhat.com> 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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: gcc 3.2.3 x64 negative indexes
  2024-02-09 21:34   ` Paul Edwards
@ 2024-02-09 21:38     ` Paul Edwards
  2024-02-10 13:41       ` Paul Edwards
  0 siblings, 1 reply; 8+ messages in thread
From: Paul Edwards @ 2024-02-09 21:38 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: GCC Development

[-- Attachment #1: Type: text/plain, Size: 4372 bytes --]

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 <mutazilah@gmail.com> wrote:

> On Wed, 7 Feb 2024 at 23:12, Jakub Jelinek <jakub@redhat.com> 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
>
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: gcc 3.2.3 x64 negative indexes
  2024-02-09 21:38     ` Paul Edwards
@ 2024-02-10 13:41       ` Paul Edwards
  2024-02-10 17:42         ` Joe Monk
                           ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Paul Edwards @ 2024-02-10 13:41 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: GCC Development

[-- Attachment #1: Type: text/plain, Size: 7420 bytes --]

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 <mutazilah@gmail.com> 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 <mutazilah@gmail.com> wrote:
>
>> On Wed, 7 Feb 2024 at 23:12, Jakub Jelinek <jakub@redhat.com> 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
>>
>>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: gcc 3.2.3 x64 negative indexes
  2024-02-10 13:41       ` Paul Edwards
@ 2024-02-10 17:42         ` Joe Monk
  2024-02-10 19:48         ` Paul Edwards
  2024-02-11  0:03         ` Paul Edwards
  2 siblings, 0 replies; 8+ messages in thread
From: Joe Monk @ 2024-02-10 17:42 UTC (permalink / raw)
  To: GCC Development

[-- Attachment #1: Type: text/plain, Size: 9820 bytes --]

It appears that this is not an issue that this version of GCC is
architected to be able to solve.

The first 64-bit PC processor, the AMD opteron series, was launched on
April 22, 2003.

GCC 3.2.3 was released on April 25, 2003.

"*Opteron* is AMD <https://en.wikipedia.org/wiki/Advanced_Micro_Devices>'s
x86 <https://en.wikipedia.org/wiki/X86> former server and workstation
processor <https://en.wikipedia.org/wiki/Microprocessor> line, and was the
first processor which supported the AMD64
<https://en.wikipedia.org/wiki/AMD64> instruction set architecture
<https://en.wikipedia.org/wiki/Instruction_set_architecture> (known
generically as x86-64 <https://en.wikipedia.org/wiki/X86-64>). It was
released on April 22, 2003, with the *SledgeHammer* core (K8) and was
intended to compete in the server
<https://en.wikipedia.org/wiki/Server_(computing)> and workstation
<https://en.wikipedia.org/wiki/Workstation> markets, particularly in the
same segment as the Intel Xeon <https://en.wikipedia.org/wiki/Xeon>
processor."

"The first processor to implement Intel 64 was the multi-socket processor
Xeon <https://en.wikipedia.org/wiki/Xeon> code-named *Nocona
<https://en.wikipedia.org/wiki/Xeon#Nocona_and_Irwindale>* in June 2004."

Accordingly, it is pretty difficult to solve a compiler problem for a
platform that was not publicly available when the compiler was released,
and therefore, could not have been included in the release of the compiler.

Joe

On Sat, Feb 10, 2024 at 7:42 AM Paul Edwards via Gcc <gcc@gcc.gnu.org>
wrote:

> 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 <mutazilah@gmail.com> 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 <mutazilah@gmail.com> wrote:
> >
> >> On Wed, 7 Feb 2024 at 23:12, Jakub Jelinek <jakub@redhat.com> 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
> >>
> >>
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: gcc 3.2.3 x64 negative indexes
  2024-02-10 13:41       ` Paul Edwards
  2024-02-10 17:42         ` Joe Monk
@ 2024-02-10 19:48         ` Paul Edwards
  2024-02-11  0:03         ` Paul Edwards
  2 siblings, 0 replies; 8+ messages in thread
From: Paul Edwards @ 2024-02-10 19:48 UTC (permalink / raw)
  To: GCC Development

[-- Attachment #1: Type: text/plain, Size: 715 bytes --]

(replying to Joe Monk)

> It appears that this is not an issue that this version of GCC is
> architected to be able to solve.

> The first 64-bit PC processor, the AMD opteron series, was launched on
> April 22, 2003.

> GCC 3.2.3 was released on April 25, 2003.

Jakub has already shown correct x64 code being generated
by gcc 3.2.3. Maybe they used an emulator or something.

And I already have it running myself - with small modifications
for MSABI - on Windows 10 64-bit - for my pdptest test program.

The only thing not working for me at the moment that I know
about is negative indexes. And that is something specific to my
derivative (or more likely the way I built it), not standard gcc 3.2.3.

BFN. Paul.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: gcc 3.2.3 x64 negative indexes
  2024-02-10 13:41       ` Paul Edwards
  2024-02-10 17:42         ` Joe Monk
  2024-02-10 19:48         ` Paul Edwards
@ 2024-02-11  0:03         ` Paul Edwards
  2 siblings, 0 replies; 8+ messages in thread
From: Paul Edwards @ 2024-02-11  0:03 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: GCC Development

[-- Attachment #1: Type: text/plain, Size: 8399 bytes --]

Problem solved.

I didn't have this:

#define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int")

because I wasn't including x86_64.h.

This is the first time I have attempted to go to 64-bit pointers
so I wasn't aware this even existed.

So here it is doing Win64 ABI:

D:\devel\gcc\gcc>gcc-new -O2 -S foo.c

D:\devel\gcc\gcc>type foo.s
        .file   "foo.c"
        .text
        .p2align 2,,3
.globl foo
foo:
.LFB1:
        movsbl  -1(%rcx),%eax
        ret
.LFE1:

D:\devel\gcc\gcc>


Thanks for your help.

BFN. Paul.




On Sat, 10 Feb 2024 at 21:41, Paul Edwards <mutazilah@gmail.com> wrote:

> 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 <mutazilah@gmail.com> 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 <mutazilah@gmail.com> wrote:
>>
>>> On Wed, 7 Feb 2024 at 23:12, Jakub Jelinek <jakub@redhat.com> 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
>>>
>>>

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-02-11  0:03 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-07 15:02 gcc 3.2.3 x64 negative indexes Paul Edwards
2024-02-07 15:12 ` Jakub Jelinek
2024-02-09 21:34   ` Paul Edwards
2024-02-09 21:38     ` Paul Edwards
2024-02-10 13:41       ` Paul Edwards
2024-02-10 17:42         ` Joe Monk
2024-02-10 19:48         ` Paul Edwards
2024-02-11  0:03         ` Paul Edwards

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).