https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109279

--- Comment #16 from Vineet Gupta <vineetg at gcc dot gnu.org> ---
> Which is what this produces:
> ```
> long long f(void)
> {
>   unsigned t = 16843009;
>   long long t1 = t;
>   long long t2 = ((unsigned long long )t) << 32;
>   asm("":"+r"(t1));
>   return t1 | t2;
> }
> ```
> I suspect: 0x0080402010080400ULL should be done as two 32bit with a shift/or
> added too. Will definitely improve complex constants forming too.
> 
> Right now the backend does (const<<16+const)<<16+const... which is just so
> bad.

Umm this testcase is a different problem. It used to generate the same output
but no longer after g2e886eef7f2b5a and the other related updates:
g0530254413f8 and gc104ef4b5eb1.

For the test above, the low and high words are created independently and then
stitched.

260r.dfinit

# lower word

(insn 6 2 7 2 (set (reg:DI 138)
        (const_int [0x1010000]))  {*movdi_64bit}
(insn 7 6 8 2 (set (reg:DI 137)
        (plus:DI (reg:DI 138)
            (const_int [0x101]))) {adddi3}
     (expr_list:REG_EQUAL (const_int [0x1010101]) )
(insn 5 8 9 2 (set (reg/v:DI 134 [ t1 ])
        (reg:DI 136 [ t1 ])) {*movdi_64bit}

# upper word created independently, no reuse from prior values)

(insn 9 5 10 2 (set (reg:DI 141)
        (const_int [0x1010000]))  {*movdi_64bit}
(insn 10 9 11 2 (set (reg:DI 142)
        (plus:DI (reg:DI 141)
            (const_int [0x101]))) {adddi3}
(insn 11 10 12 2 (set (reg:DI 140)
        (ashift:DI (reg:DI 142)
            (const_int 32 [0x20]))) {ashldi3}
        (expr_list:REG_EQUAL (const_int [0x101010100000000]))

# stitch them
(insn 12 11 13 2 (set (reg:DI 139)
        (ior:DI (reg/v:DI 134 [ t1 ])
            (reg:DI 140))) "const2.c":7:13 99 {iordi3}


cse1 matches the new "*mvconst_internal" pattern independently on each of them 

(insn 7 6 8 2 (set (reg:DI 137)
        (const_int [0x1010101])) {*mvconst_internal}
        (expr_list:REG_EQUAL (const_int [0x1010101])))

(insn 11 10 12 2 (set (reg:DI 140)
        (const_int [0x1010101_00000000])) {*mvconst_internal}
        (expr_list:REG_EQUAL (const_int   
                [0x1010101_00000000]) ))

This ultimately gets in the way, as otherwise it would find the equivalent reg
across the 2 snippets and reuse reg.

It is interesting that due to same pattern, split1 undoes what cse1 did so in
theory cse2 ? could redo it it. Anyhow needs to be investigated. But ATM we
have the following codegen for the aforementioned test which clearly needs more
work.

        li      a0,16842752
        addi    a0,a0,257
        li      a5,16842752
        slli    a0,a0,32
        addi    a5,a5,257
        or      a0,a5,a0
        ret

Reply via email to