This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug inline-asm/85185] Wider-than-expected load for struct member used as operand of inline-asm with memory clobber at -Og


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

Jim Wilson <wilson at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2018-04-23
                 CC|                            |wilson at gcc dot gnu.org
     Ever confirmed|0                           |1

--- Comment #7 from Jim Wilson <wilson at gcc dot gnu.org> ---
The problem is exposed in combine, where we take two instructions

(insn 9 8 10 2 (set (reg:DI 72 [ _2 ])
        (sign_extend:DI (subreg:HI (reg:SI 75 [ SD.1554.PD.1553 ]) 0)))
"tmp.c"\
:12 92 {extendhidi2}
     (expr_list:REG_DEAD (reg:SI 75 [ SD.1554.PD.1553 ])
        (nil)))
(insn 10 9 0 2 (parallel [
            (asm_operands/v ("magic %0") ("") 0 [
                    (subreg/s/u:HI (reg:DI 72 [ _2 ]) 0)
                ]
                 [
                    (asm_input:HI ("r") tmp.c:12)
                ]
                 [] tmp.c:12)
            (clobber (mem:BLK (scratch) [0  A8]))
        ]) "tmp.c":12 -1
     (expr_list:REG_DEAD (reg:DI 72 [ _2 ])
        (nil)))

and then produce

insn 10 9 0 2 (parallel [
            (asm_operands/v ("magic %0") ("") 0 [
                    (subreg:HI (reg:SI 75 [ SD.1554.PD.1553 ]) 0)
                ]
                 [
                    (asm_input:HI ("r") tmp.c:12)
                ]
                 [] tmp.c:12)
            (clobber (mem:BLK (scratch) [0  A8]))
        ]) "tmp.c":12 -1
     (expr_list:REG_DEAD (reg:SI 75 [ SD.1554.PD.1553 ])
        (nil)))

We have now lost the truncation and sign-extension.  The value passed to the
asm has correct value for the low 16 bits, but has garbage in the high 16 bits. 

However, what combine did does not appear wrong by itself.  One could argue
that the problem started with the asm, which is taking a HImode argument, even
though this makes little sense on RISC-V, since the only instructions operating
on HImode are the 16-bit load and store instructions.  Maybe the asm should use
the sign-extended DImode value directly and assume a DImode input instead of a
HImode input?  That would prevent the truncate and sign-extend from being
optimized away, but might be wrong if someone extends the RISC-V ISA to include
instructions that operate directly on HImode values.

I can work around the problem by explicitly casting the asm input to int.
  asm("magic %0" :: "r" ((int)sub.a) : "memory");
and now the asm takes SImode input, and the truncate/sign extend can't be
optimized away.  Asking the user to change their code doesn't seem like the
right solution though.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]