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