libcall CSE, simplify_unary_operation, and (zero_extend (const_int))

Ulrich Weigand Ulrich.Weigand@de.ibm.com
Mon Jan 7 11:58:00 GMT 2002


Hello,

I'm getting failures on S/390 that appear to be caused by
simplify_unary_operation making incorrect assumptions when
passed an rtx of the form (zero_extend (const_int ...)),
which in turn happens during CSE of a libcall.

What happens is that an SI-mode register is set to -1,
and this value is subsequently zero-extended into a DI-mode
register, using a no-conflict block.  Before CSE, the RTL looks
like this:

(insn 12 7 15 (set (reg/v:SI 44)
        (const_int -1 [0xffffffffffffffff])) -1 (nil)
    (nil))

[...]

(insn 25 76 23 (clobber (reg:DI 45)) -1 (nil)
    (insn_list:REG_LIBCALL 27 (nil)))

(insn 23 25 24 (set (subreg:SI (reg:DI 45) 0)
        (reg/v:SI 44)) -1 (nil)
    (expr_list:REG_NO_CONFLICT (reg/v:SI 44)
        (nil)))

(insn 24 23 27 (parallel[
            (set (reg:DI 45)
                (lshiftrt:DI (reg:DI 45)
                    (const_int 32 [0x20])))
            (clobber (reg:CC 33 %cc))
        ] ) -1 (nil)
    (expr_list:REG_NO_CONFLICT (reg/v:SI 44)
        (nil)))

(insn 27 24 29 (set (reg:DI 45)
        (reg:DI 45)) -1 (nil)
    (insn_list:REG_RETVAL 25 (expr_list:REG_EQUAL (zero_extend:DI (reg/v:SI
44))
            (nil))))

However, after CSE, the no-conflict block is replaced by:

(insn 27 76 30 (set (reg:DI 45)
        (const_int -1 [0xffffffffffffffff])) 52 {*movdi_31} (nil)
    (expr_list:REG_EQUAL (zero_extend:DI (const_int -1
[0xffffffffffffffff]))
        (nil)))

which is obviously broken.

Now, I'm not quite sure who's at fault here.  The REG_EQUAL note itself
looks already broken; this was created by cse_insn (line 5531) simply
substituting the const_int for reg 44 inside the libcall notes, without
any special case that would recognize (zero_extend (const_int)).

However, this is then even further broken by simplify_unary_operation,
which 'simplifies' (zero_extend:DI (const_int -1)) to (const_int -1).
This is because it assumes that the const_int was meant to be in the
same mode as the outer mode in any case ...


Any ideas how this could be fixed?



Mit freundlichen Gruessen / Best Regards

Ulrich Weigand

--
  Dr. Ulrich Weigand
  Linux for S/390 Design & Development
  IBM Deutschland Entwicklung GmbH, Schoenaicher Str. 220, 71032 Boeblingen
  Phone: +49-7031/16-3727   ---   Email: Ulrich.Weigand@de.ibm.com



More information about the Gcc mailing list