On 11/12/24 11:31 AM, Alexey Merzlyakov wrote:
Hi, Jeff,

Oops... It looks like I've made a reply to Alex at the same time when
you sent an e-mail update.

So, moving the testcase to the gcc.dg/torture directory.

On Tue, Nov 12, 2024 at 10:56:13AM -0700, Jeff Law wrote:
I think it might be better to put the test in gcc.c-torture/execute,
then it will automatically get run with the various torture options
and you should be able to drop both the dejagnu directives.
Actually, gcc.dg/torture is better.

jeff

Next version of patch is below:

-- >8 --

gcc/ChangeLog:

        * simplify-rtx.cc (simplify_context::simplify_unary_operation_1):
        Fix subreg mode check during zero_extend(not) -> xor optimization.

gcc/testsuite/ChangeLog:

        * gcc.dg/torture/pr117476.c: New test. From Zhendong Su.
I think we've still got a problem in this code. If we take this test from Zdenek, we completely optimize away foo() during combine.

unsigned __int128 g;

void
foo ()
{
  g += __builtin_add_overflow_p (~g, 0, 0ul);
}

int
main ()
{
  foo();
  if (!g)
    __builtin_abort();
}
$ x86_64-pc-linux-gnu-gcc -O1 testcase.c -Wall -W && ./a.out
Aborted

I think the problem is the mask we generate when the optimization applies -- and you're about to be exposed to a bit of GCC quirkyness.

We've got a TImode ZERO_EXTEND of this object:

(gdb) p debug_rtx (op)
(subreg:DI (not:TI (reg:TI 100 [ g.0_2 ])) 0)


So precisely the kind of case you're trying to handle. This is equivalent to a (xor:TI (reg:TI 100) (const_int 0xffffffffffffffff))

So we end up calling simplify_gen_binary, and our constant is:

(gdb) p debug_rtx (op1)
(const_int -1 [0xffffffffffffffff])


Note constants in GCC do not have a mode. So that (const_int -1) when interpreted in TImode is 0xffffffffffffffffffffffffffffffff, clearly not what we want. We ultimately return:

(gdb) finish
Run till exit from #0 simplify_context::simplify_unary_operation_1 (this=0x7fffffffd928, code=ZERO_EXTEND, mode=E_TImode, op=0x7ffff77e5b40) at /home/jlaw/test/gcc/gcc/simplify-rtx.cc:1861 simplify_context::simplify_unary_operation (this=0x7fffffffd928, code=ZERO_EXTEND, mode=E_TImode, op=0x7ffff77e5b40, op_mode=E_DImode) at /home/jlaw/test/gcc/gcc/simplify-rtx.cc:893
893       return simplify_unary_operation_1 (code, mode, op);
Value returned is $20 = (rtx_def *) 0x7ffff77c1e20
(gdb) p debug_rtx ($20)
(not:TI (reg:TI 100 [ g.0_2 ]))


Which is not the same as:

(zero_extend:TI (subreg:DI (not:TI (reg:TI 100 [ g.0_2 ])) 0))

Anyway, that the beginning of that function into:

(insn 8 6 15 2 (set (reg:TI 107)
(not:TI (reg:TI 100 [ g.0_2 ]))) "j.c":6:8 1029 {*one_cmplti2_doubleword}
     (nil))

(insn 15 8 35 2 (set (reg:TI 108)
        (not:TI (reg:TI 100 [ g.0_2 ]))) "j.c":6:8 174 {zero_extendditi2}
     (nil))

(insn 35 15 36 2 (set (reg:CCZ 17 flags)
        (compare:CCZ (reg:TI 107)
            (reg:TI 108))) "j.c":6:8 34 {*cmpti_doubleword}
     (expr_list:REG_DEAD (reg:TI 108)
        (expr_list:REG_DEAD (reg:TI 107)
            (nil))))

Naturally things go downhill after that since the condition has a known result, eventually leading to the whole function optimizing away and returning random garbage.


So the natural question is how to fix. First I would recommend changing the type of "mask" to a HOST_WIDE_INT. In an of itself that won't fix this problem, but it's the right thing to do.

I think what you want is to test HWI_COMPUTABLE_MODE_P. That will verify whether or not the given scalar integer mode can fit into a HOST_WIDE_INT, which should return false for TI or larger modes.

Jeff







Reply via email to