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

--- Comment #2 from Kazumoto Kojima <kkojima at gcc dot gnu.org> ---
Created attachment 59366
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=59366&action=edit
a reduced test case (-m4 -mlra -O2 -ftrace)

qemu-sh4-static failed with

Unhandled trap: 0x1a0
pc=0x004004f4 sr=0x00000001 pr=0x004004f0 fpscr=0x00080000
spc=0x00000000 ssr=0x00000000 gbr=0x3ffbd1e0 vbr=0x00000000
sgr=0x00000000 dbr=0x00000000 delayed_pc=0x0040055e fpul=0x00000000
r0=0x00000000 r1=0x00000001 r2=0x00000002 r3=0x00000000
r4=0x407ffda0 r5=0x407ffdb4 r6=0x407ffebc r7=0x00000000
r8=0x407ffdec r9=0x407ffdf0 r10=0x407ffde0 r11=0x407ffddc
r12=0x00400ca4 r13=0x3ffffa40 r14=0x00000000 r15=0x407ffdd4
r16=0x00000000 r17=0x00000000 r18=0x00000000 r19=0x00000000
r20=0x00000000 r21=0x00000000 r22=0x00000000 r23=0x00000000
in conditional delay slot (delayed_pc=0x0040055e)

It turned out that fldi1 was executed when fpscr == 0x80001 unexpectedly.  It
seems qemu fails with the unhandled trap for that situation.

The fldi1 insn in problem is generated with
lra-constraints.cc:curr_insn_transform.  The LRA dump says

Changing pseudo 408 in operand 1 of insn 406 on equiv 1.0e+0
         Considering alt=0 of insn 406:   (0) =f  (1) f
            1 Non-pseudo reload: reject+=2
            1 Non input pseudo reload: reject++
          overall=9,losers=1,rld_nregs=1
         Considering alt=1 of insn 406:   (0) r  (1) r
            0 Non input pseudo reload: reject++
            1 Non-pseudo reload: reject+=2
            1 Non input pseudo reload: reject++
            overall=16,losers=2 -- refuse
         Considering alt=2 of insn 406:   (0) f  (1) G
            Bad operand -- refuse
         Considering alt=3 of insn 406:   (0) f  (1) H
          overall=0,losers=0,rld_nregs=0
      Choosing alt 3 in insn 406:  (0) f  (1) H {movsf_ie_ra}

Looks LRA tries to substitute a reg-reg move into a constant load when the
source pseudo reg is equivalent to a constant.  Unfortunately this is unsafe on
SH.  If the constant is the SFmode 0.0 or 1.0, then that constant load will end
up with fldi0/1 which is usable only with single precision mode.  We have
already cannot_substitute_mem_equiv_p target hook to avoid similar
transformations when the source pseudo reg is equivalent to a memory.  I'm
trying to add cannot_substitute_const_equiv_p target hook to avoid that
substitution to fldi0/1.

Reply via email to