Re: Compare Elimination problems

2014-09-04 Thread Paul Shortis

Correction,

...compare:CC_N... (R1:HI, 0)

On 05/09/14 09:31, Paul Shortis wrote:

Thanks Richard,

I found the bug. try_eliminate_compare follows register 
definitions between the flags use and the clobbering compare by 
register number only, i.e. the register width isn't considered.


if (DF_REF_REGNO (def) == REGNO (in_a))
  break;

This caused R1:HI to follow R0:SI causing the compare:HI (R0, 
so be seen as as valid source of flags.


The following change fixes the problem while preserving the 
proper behaviour.


   x = single_set (insn);
   if (x == NULL)
return false;
+ if( GET_MODE(x) != GET_MODE(in_a))
+   return false;
   in_a = SET_SRC (x);

Cheers, Paul.

On 05/09/14 02:33, Richard Henderson wrote:

On 09/03/2014 03:14 PM, Paul Shortis wrote:

(insn 33 84 85 6 (parallel [
 (set (reg:HI 1 r1)
 (ashift:HI (reg:HI 1 r1)
 (const_int 1 [0x1])))
 (clobber (reg:CC_NOOV 7 flags))
 ]) 
../gcc/testsuite/gcc.c-torture/execute/960311-3.c:18 33 
{ashlhi3}


(insn 34 87 35 6 (set (reg:CC_NOOV 7 flags)
 (compare:CC_NOOV (reg:SI 0 r0)
 (const_int 0 [0])))
../gcc/testsuite/gcc.c-torture/execute/960311-3.c:20 39 
{*comparesi3_nov}


(jump_insn 35 34 36 6 (set (pc)
 (if_then_else (ge (reg:CC_NOOV 7 flags)

to

(insn 33 84 85 6 (parallel [
 (set (reg:HI 1 r1)
 (ashift:HI (reg:HI 1 r1)
 (const_int 1 [0x1])))
 (set (reg:CC_NOOV 7 flags)
 (compare:CC_NOOV (ashift:HI (reg:HI 1 r1)
 (const_int 1 [0x1]))
 (const_int 0 [0])))
 ]) 
../gcc/testsuite/gcc.c-torture/execute/960311-3.c:18 29 
{ashlhi3_cc}


(jump_insn 35 87 36 6 (set (pc)
 (if_then_else (ge (reg:CC_NOOV 7 flags)


(reg:HI r1) is a subreg of (reg:SI r0) however the cmpelim 
seems to be
substituting the compare of (reg:HI r1 and 0) for the compare 
of (reg:SI r0 and

0) ?
That would appear to be a bug, though I don't immediately see 
where.

The relevant test would appear to be

   if (rtx_equal_p (SET_DEST (x), in_a))

which would not be true for (reg:SI) vs (reg:HI), whatever 
their regno's.


Anyway, put your breakpoint in try_eliminate_compare to debug 
this.


While I'm here, in i386.md some of the flag setting 
operations specify a mode

and some don't . Eg

(define_expand "cmp_1"
   [(set (reg:CC FLAGS_REG)
 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")

That's a define_expand, not a define_insn.


(define_insn "*add_3"
   [(set (reg FLAGS_REG)
 (compare
The mode checks are done in the ix86_match_ccmode call inside 
the predicate.



r~








Re: Compare Elimination problems

2014-09-04 Thread Paul Shortis

Thanks Richard,

I found the bug. try_eliminate_compare follows register 
definitions between the flags use and the clobbering compare by 
register number only, i.e. the register width isn't considered.


if (DF_REF_REGNO (def) == REGNO (in_a))
  break;

This caused R1:HI to follow R0:SI causing the compare:HI (R0, so 
be seen as as valid source of flags.


The following change fixes the problem while preserving the 
proper behaviour.


   x = single_set (insn);
   if (x == NULL)
return false;
+ if( GET_MODE(x) != GET_MODE(in_a))
+   return false;
   in_a = SET_SRC (x);

Cheers, Paul.

On 05/09/14 02:33, Richard Henderson wrote:

On 09/03/2014 03:14 PM, Paul Shortis wrote:

(insn 33 84 85 6 (parallel [
 (set (reg:HI 1 r1)
 (ashift:HI (reg:HI 1 r1)
 (const_int 1 [0x1])))
 (clobber (reg:CC_NOOV 7 flags))
 ]) ../gcc/testsuite/gcc.c-torture/execute/960311-3.c:18 33 {ashlhi3}

(insn 34 87 35 6 (set (reg:CC_NOOV 7 flags)
 (compare:CC_NOOV (reg:SI 0 r0)
 (const_int 0 [0])))
../gcc/testsuite/gcc.c-torture/execute/960311-3.c:20 39 {*comparesi3_nov}

(jump_insn 35 34 36 6 (set (pc)
 (if_then_else (ge (reg:CC_NOOV 7 flags)

to

(insn 33 84 85 6 (parallel [
 (set (reg:HI 1 r1)
 (ashift:HI (reg:HI 1 r1)
 (const_int 1 [0x1])))
 (set (reg:CC_NOOV 7 flags)
 (compare:CC_NOOV (ashift:HI (reg:HI 1 r1)
 (const_int 1 [0x1]))
 (const_int 0 [0])))
 ]) ../gcc/testsuite/gcc.c-torture/execute/960311-3.c:18 29 {ashlhi3_cc}

(jump_insn 35 87 36 6 (set (pc)
 (if_then_else (ge (reg:CC_NOOV 7 flags)


(reg:HI r1) is a subreg of (reg:SI r0) however the cmpelim seems to be
substituting the compare of (reg:HI r1 and 0) for the compare of (reg:SI r0 and
0) ?

That would appear to be a bug, though I don't immediately see where.
The relevant test would appear to be

   if (rtx_equal_p (SET_DEST (x), in_a))

which would not be true for (reg:SI) vs (reg:HI), whatever their regno's.

Anyway, put your breakpoint in try_eliminate_compare to debug this.


While I'm here, in i386.md some of the flag setting operations specify a mode
and some don't . Eg

(define_expand "cmp_1"
   [(set (reg:CC FLAGS_REG)
 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")

That's a define_expand, not a define_insn.


(define_insn "*add_3"
   [(set (reg FLAGS_REG)
 (compare

The mode checks are done in the ix86_match_ccmode call inside the predicate.


r~





Re: Compare Elimination problems

2014-09-04 Thread Richard Henderson
On 09/03/2014 03:14 PM, Paul Shortis wrote:
> (insn 33 84 85 6 (parallel [
> (set (reg:HI 1 r1)
> (ashift:HI (reg:HI 1 r1)
> (const_int 1 [0x1])))
> (clobber (reg:CC_NOOV 7 flags))
> ]) ../gcc/testsuite/gcc.c-torture/execute/960311-3.c:18 33 {ashlhi3}
> 
> (insn 34 87 35 6 (set (reg:CC_NOOV 7 flags)
> (compare:CC_NOOV (reg:SI 0 r0)
> (const_int 0 [0])))
> ../gcc/testsuite/gcc.c-torture/execute/960311-3.c:20 39 {*comparesi3_nov}
> 
> (jump_insn 35 34 36 6 (set (pc)
> (if_then_else (ge (reg:CC_NOOV 7 flags)
> 
> to
> 
> (insn 33 84 85 6 (parallel [
> (set (reg:HI 1 r1)
> (ashift:HI (reg:HI 1 r1)
> (const_int 1 [0x1])))
> (set (reg:CC_NOOV 7 flags)
> (compare:CC_NOOV (ashift:HI (reg:HI 1 r1)
> (const_int 1 [0x1]))
> (const_int 0 [0])))
> ]) ../gcc/testsuite/gcc.c-torture/execute/960311-3.c:18 29 
> {ashlhi3_cc}
> 
> (jump_insn 35 87 36 6 (set (pc)
> (if_then_else (ge (reg:CC_NOOV 7 flags)
> 
> 
> (reg:HI r1) is a subreg of (reg:SI r0) however the cmpelim seems to be
> substituting the compare of (reg:HI r1 and 0) for the compare of (reg:SI r0 
> and
> 0) ?

That would appear to be a bug, though I don't immediately see where.
The relevant test would appear to be

  if (rtx_equal_p (SET_DEST (x), in_a))

which would not be true for (reg:SI) vs (reg:HI), whatever their regno's.

Anyway, put your breakpoint in try_eliminate_compare to debug this.

> While I'm here, in i386.md some of the flag setting operations specify a mode
> and some don't . Eg
> 
> (define_expand "cmp_1"
>   [(set (reg:CC FLAGS_REG)
> (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")

That's a define_expand, not a define_insn.

> (define_insn "*add_3"
>   [(set (reg FLAGS_REG)
> (compare

The mode checks are done in the ix86_match_ccmode call inside the predicate.


r~


Re: Compare Elimination problems

2014-09-03 Thread Uros Bizjak
Hello!

> While I'm here, in i386.md some of the flag setting operations specify a mode 
> and some don't . Eg
>
> (define_expand "cmp_1"
>   [(set (reg:CC FLAGS_REG)
> (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
>
>
> (define_insn "*add_3"
>   [(set (reg FLAGS_REG)
> (compare

The mode of the mode-less FLAGS_REG is checked with ix86_match_ccmode
in the insn constraint. Several modes are compatible with required
mode, also depending on input operands.

Uros.