patch: convert_move

Aldy Hernandez aldyh@redhat.com
Fri Jun 13 12:27:00 GMT 2003


> I wouldn't expect this to be the right place to handle this.
> Without knowing more about the actual problem, I'd expect that
> CLASS_CANNOT_CHANGE_MODE (or whatever it's current replacement)
> to be a better solution.

Upon further investigation it looks like a problem with combine.

Original code:

	__ev64_opaque__ bar;

	static inline int64_t
	__ev_convert_s64 (__ev64_opaque__ a) {
		return (int64_t) a;
	}

	foo(){
		s64 = __ev_convert_s64 ((v2si){0,0xffffffff});
	}


We're trying to combine these 2 instructions:

(insn 31 29 32 0x0 (set (reg/v:V2SI 136 [ <anonymous> ])
         (const_vector:V2SI [
                 (const_int 0 [0x0])
                 (const_int -1 [0xffffffffffffffff])
             ])) -1 (nil)
     (nil))

(insn 18 16 19 0x0 (set (subreg:V2SI (reg/v:DI 123 [ <anonymous> ]) 0)
         (reg/v:V2SI 136 [ a ])) -1 (nil)
     (nil))

Then we try the following substitution:

(subreg:DI (const_vector:V2SI [
             (const_int 0 [0x0])
             (const_int -1 [0xffffffffffffffff])
         ]) 0)

Which we try to simplify in combine_simplify_rtx:

     case SUBREG:
       if (op0_mode == VOIDmode)
         op0_mode = GET_MODE (SUBREG_REG (x));

       /* simplify_subreg can't use gen_lowpart_for_combine.  */
=>    if (CONSTANT_P (SUBREG_REG (x))
           && subreg_lowpart_offset (mode, op0_mode) == SUBREG_BYTE (x)
              /* Don't call gen_lowpart_for_combine if the inner mode
                 is VOIDmode and we cannot simplify it, as SUBREG without
                 inner mode is invalid.  */
           && (GET_MODE (SUBREG_REG (x)) != VOIDmode
               || gen_lowpart_common (mode, SUBREG_REG (x))))
         return gen_lowpart_for_combine (mode, SUBREG_REG (x));

As you may well guess, the lowpart of the vector constant is -1, which 
is perfectly representable as a DI -1.

So... looking back at the C code we started with, we end up storing 
0xffffffff into s64, instead of 0x0000ffff.

QED.

I suppose we can change the above snippet in combine_simplify_rtx into:

	if (CONSTANT_P (SUBREG_REG (x))
 >>	    && GET_CODE (SUBREG_REG (x)) != CONST_VECTOR

...and avoid this nonsense altogether, or perhaps teach 
combine_simplify_rtx to zero extend the value?

??
Aldy



More information about the Gcc-patches mailing list