This is the mail archive of the gcc@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]

SH: may miscompile zero extension and test


Hi,

I'm investigating the bug which is filed as a PR
<URL:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11864>.

For the source below,

int f (void);
unsigned char a[1];

void
foo (void)
{
  a[0] = f () & 255;
  if (!a[0])
    a[0] = f () & 255;
  if (!a[0])
    a[0] = 1 + (f () & 127);
}

the mainline gcc for SH generates the code like:

	jsr	@r8
	nop
	tst	r0,r0
	bf/s	.L4
	mov.b	r0,@r9

for the second call of f and if test, which is clearly wrong.
I've looked RTL dumps and found that the combiner makes an insn
including a paradoxical subreg:

--
foo.c.21.life
--
(insn 51 50 52 1 (set (reg:SI 179 [ a ])
        (zero_extend:SI (reg:QI 178 [ a ]))) 104 {*zero_extendqisi2_compact} (insn_list 50 (nil))
    (expr_list:REG_DEAD (reg:QI 178 [ a ])
        (nil)))

(insn 52 51 53 1 (set (reg:SI 147 t)
        (eq:SI (reg:SI 179 [ a ])
            (const_int 0 [0x0]))) 1 {cmpeqsi_t} (insn_list 51 (nil))
    (expr_list:REG_DEAD (reg:SI 179 [ a ])
        (nil)))
--
foo.c.22.combine
--
(note 51 50 52 1 NOTE_INSN_DELETED)

(insn 52 51 53 1 (set (reg:SI 147 t)
        (eq:SI (subreg:SI (reg:QI 178 [ a ]) 0)
            (const_int 0 [0x0]))) 1 {cmpeqsi_t} (insn_list 50 (nil))
    (expr_list:REG_DEAD (reg:QI 178 [ a ])
        (nil)))
--

It seems that the combiner combines insns only if the resulting insn
is recognizable.

Is the above

 (set (reg:SI 147 t) (eq:SI (subreg:SI (reg:QI 178 [ a ]) 0)
			    (const_int 0 [0x0])))

recognizable? It looks that there is no corresponding SH instruction
or splitter.

Regards,
	kaz


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