http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55876



--- Comment #1 from vries at gcc dot gnu.org 2013-01-04 15:23:25 UTC ---

while expanding the xor, we try to widen an DImode reg from QImode to SImode:

...

#6  0x085d7da5 in widen_operand (op=0xf7cd2ec0, mode=SImode, oldmode=QImode,

unsignedp=1, no_extend=1) at src/gcc-mainline/gcc/optabs.c:333

333         return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);

(gdb) l

328         return convert_modes (mode, oldmode, op, unsignedp);

329

330       /* If MODE is no wider than a single word, we return a paradoxical

331          SUBREG.  */

332       if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)

333         return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);

334

335       /* Otherwise, get an object of MODE, clobber it, and set the

low-order

336          part to OP.  */

337

(gdb) call debug_rtx (op)

(reg:DI 222 [ used+-7 ])

...



Just before expand, the representation looks like:

...

foo ()

{

  unsigned charD.13 usedD.1407;

  charD.2 _7;

  unsigned charD.13 _13;

  charD.2 _19;

  charD.2 _28;

  charD.2 _37;



;;   basic block 2, loop depth 0

;;    pred:       ENTRY

  # VUSE <.MEM_1(D)>

  _19 = MEM[(const charD.2 *)&bufferD.1387];

  used_20 = _19 != 70 ? 1 : 0;

  # VUSE <.MEM_1(D)>

  _28 = MEM[(const charD.2 *)&bufferD.1387 + 1B];

  used_29 = _28 == 70 ? used_20 : 1;

  # VUSE <.MEM_1(D)>

  _37 = MEM[(const charD.2 *)&bufferD.1387 + 2B];

  used_38 = _37 == 70 ? used_29 : 1;

  # VUSE <.MEM_1(D)>

  _7 = MEM[(const charD.2 *)&bufferD.1387 + 3B];

  used_10 = _7 == 70 ? used_38 : 1;

  _13 = used_10 ^ 1;

  # VUSE <.MEM_1(D)>

  return _13;

;;    succ:       EXIT



}

...



The reason that used_10 is in a DImode reg is because

  used_10 = _7 == 70 ? used_38 : 1

and the all the other conditional moves before are promoted by

expand_cond_expr_using_cmove.

Reply via email to