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

[PATCH] generalize BLKmode op to mem in _REF rtl expansion


Hello,

This fixes an ICE on a specific case of view conversion.

The rtl expansion for _REF nodes has code to force an operand to
memory for specific cases of conversion from scalar to BLKmode
aggregate types, easy to produce at least in Ada:

  << expand_expr_real_1
      ...
      normal_inner_ref:
      {  ...
        /* Otherwise, if this object not in memory and we either have an
           offset, a BLKmode result, or a reference outside the object, put it
           there.  Such cases can occur in Ada if we have unchecked conversion
           of an expression from a scalar type to an array or record type or
           for an ARRAY_RANGE_REF whose type is BLKmode.  */
  >>

The code is slightly too specialized, as it expects and only handles
ARRAY_RANGE_REFs while we might get there for other cases, such as a
COMPONENT_REF for "To_Composite_Packet (RAW_Blob).Values" in the
testcase below:

   with System, Ada.Unchecked_Conversion; use System;

   procedure BLK is

      type Byte is range 0 .. +255;
      for  Byte'size use 8;

      type RGB is array (1 .. 3) of Byte;
      for RGB'Size use 24;

      type RAW_Packet is range 0 .. 2 ** 32 - 1;
      for  RAW_Packet'Size use 32;

      type Composite_Packet is record
	 Values : RGB;
	 Pad    : Byte;
      end record;
      for Composite_Packet use record
	 Values at 0 range 0 .. 23;
	 Pad    at 3 range 0 .. 7;
      end record;
      for Composite_Packet'Size use 32;

      function To_Composite_Packet is
	 new Ada.Unchecked_Conversion (RAW_Packet, Composite_Packet);

      RAW_Blob : RAW_Packet := 16#01020304#;
      Color : RGB := To_Composite_Packet (RAW_Blob).Values;    -- here
   begin
      null;
   end;

The initialization of Color extracts a BLKmode three bytes array from
an SImode register operand VIEW_CONVERTed to a record type.

The tree expression to expand looks like

  <component_ref
    type <array_type blk__rgb
        ... BLK
        size <integer_cst constant invariant 24>

    arg 0 <view_convert_expr
        type <record_type blk__composite_packet
        arg 0 <var_decl D.536 type <integer_type ...

    arg 1 <field_decl values type <array_type blk__rgb>

We currently crash trying to expand this, on

	/* In cases where [...], we might be extracting a BLKmode value
           from an integer-mode (e.g., SImode) object.
        ...
                    gcc_assert (MEM_P (op0)
                                && (!target || MEM_P (target))
                                && !(bitpos % BITS_PER_UNIT));

with

   (gdb) pr op0
   (reg:SI 58 [ D.536 ])

The attached patch addresses this by generalizing the aforementioned
expansion code so that it forces op0 to memory as soon as a BLKmode
extraction is required.

The patch was bootstrapped and regtested on x86_64-unknown-linux-gnu
with languages=all,ada.

Thanks in advance,

Olivier

2007-11-06  Olivier Hainque  <hainque@adacore.com>

	* expr.c (expand_expr_real_1) <normal_inner_ref>: Force op0 to
	memory if the component is to be referenced in BLKmode according
	to get_inner_reference.

	testsuite/
	* gnat.dg/blkextract_from_reg.adb: New test.






Attachment: blkextract_from_reg.dif
Description: Text document


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