Question about make_extraction() in combine.c

Michael Eager eager@eagerm.com
Thu Nov 15 22:40:00 GMT 2018


In combine, simplify_comparison() is being called with the following
arguments:

   code = EQ
   op0 =  (and:SI (mem:SI (reg/v/f:SI 50 [ gp ]) (const_int 4 [0x4]))
   op1 =  (const_int 0 [0])
€
After churning down through make_compound_operation() and
make_compound_operation_int(), processing gets to make_extraction().
Eventually (combine.c:7753), make_extract() decides that the best
pattern is EP_epextzv.  No instruction patterns are provided for
"extz*"; get_best_reg_extraction_insn() returns false, and
make_extraction falls through to this code [indenting modified for
email].

combine.c:7786:
       /* Be careful not to go beyond the extracted object and
          maintain the natural alignment of the memory.  */
       wanted_inner_mode = smallest_int_mode_for_size (len);
       while (pos % GET_MODE_BITSIZE (wanted_inner_mode) + len
	     > GET_MODE_BITSIZE (wanted_inner_mode))
	wanted_inner_mode = GET_MODE_WIDER_MODE
               (wanted_inner_mode).require ();

Len == 1; the result is that wanted_inner_mode == E_QImode.

No instruction patterns are provided for "extz*";
get_best_reg_extraction_insn() returns false, and make_extraction falls
through to this code

The (mem:SI) is converted to (mem:QI).

The return from make_extract() is
    (zero_extract:SI (mem:QI (reg/v/f:SI 50 [ gp ]))
       (const_int 1 [0x1])
       (const_int 2 [0x2]))

The target has an instruction pattern for zero_extract, but it matches
SI values, not QI.  So the instruction which implements a test of a bit
flag is never generated.

In an old version of GCC, a call to mode_dependent_address_p() 
controlled whether this conversion from SI to QI was done.  This would
not be useful, since QI is a valid address mode in general, just not for
the zero_extract pattern.  A kludge was added to prevent this conversion
from SI to QI.  I'd like to avoid re-implementing the kludge.



Questions:
   1.  What is make_extract() trying to do with the MEM address?
   2.  Why modify the MEM address from SI to QI?
       There's no obvious benefit that I see of
       (zero_extract:SI (mem:QI)...)  over (zero_extract:SI (mem:SI)...).
   3.  What's the best way to fix this?
         - Remove the down-sizing of MEM in make_extract()?
         - Define patterns for extz*?
         - Do something so zero_extend accepts QI?

-- 
Michael Eager    eager@eagerm.com
1960 Park Blvd., Palo Alto, CA 94306



More information about the Gcc mailing list