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 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 wrote: > >> On Wed, 7 Feb 2024 at 23:12, Jakub Jelinek 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 >> >>