[Bug rtl-optimization/52060] Incorrect mask/and (ARM "bic") instruction generated for shifted expression parameter, triggered by -O2 -finline-functions

rearnsha at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Mon Feb 6 14:28:00 GMT 2012


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

Richard Earnshaw <rearnsha at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|2012-02-03 00:00:00         |2012-02-06 0:00
          Component|target                      |rtl-optimization

--- Comment #5 from Richard Earnshaw <rearnsha at gcc dot gnu.org> 2012-02-06 14:28:20 UTC ---
Looks like a combine bug to me.  We have the following three insns passed to
combine:

i3 = (insn 49 48 50 5 (set (reg:SI 192)
        (lshiftrt:SI (reg/v:SI 155 [ linear ])
            (const_int 13 [0xd]))) bug.c:47 125 {*arm_shiftsi3}
     (nil))

i2 = (insn 46 72 48 5 (set (reg/v:SI 155 [ linear ])
        (and:SI (reg:SI 154 [ iftmp.1 ])
            (reg:SI 176 [ prephitmp.29 ]))) bug.c:24 75 {*arm_andsi3_insn}
     (expr_list:REG_DEAD (reg:SI 176 [ prephitmp.29 ])
        (expr_list:REG_DEAD (reg:SI 154 [ iftmp.1 ])
            (nil))))

i1 = (insn 72 41 46 5 (set (reg:SI 154 [ iftmp.1 ])
        (if_then_else:SI (eq (reg:CC_NOOV 24 cc)
                (const_int 0 [0]))
            (const_int -2 [0xfffffffffffffffe])
            (const_int -1 [0xffffffffffffffff]))) bug.c:23 234 {*movsicc_insn}
     (expr_list:REG_DEAD (reg:CC 24 cc)
        (nil)))

Note that the result of i2 does not die in i3.  Nevertheless, we simplify this
expression to the form

(parallel [
        (set (reg:SI 192)
            (lshiftrt:SI (and:SI (if_then_else:SI (eq (reg:CC_NOOV 24 cc)
                            (const_int 0 [0]))
                        (const_int -8192 [0xffffffffffffe000])
                        (const_int -8192 [0xffffffffffffe000]))
                    (reg:SI 176 [ prephitmp.29 ]))
                (const_int 13 [0xd])))
        (set (reg/v:SI 155 [ linear ])
            (and:SI (if_then_else:SI (eq (reg:CC_NOOV 24 cc)
                        (const_int 0 [0]))
                    (const_int -8192 [0xffffffffffffe000])
                    (const_int -8192 [0xffffffffffffe000]))
                (reg:SI 176 [ prephitmp.29 ])))
    ])

The choice of -8192 for the constant in the if-then-else expressions seems to
come from the fact that i3 will shift the result right by 13 (ie 0x1fff) and
that therefore we can exclude those bits from the and operation (which will
ultimately collapse the if-then-else into a single constant).  However, that is
only true in the first of the two operations in the parallel above.  It's not
true for the second operation.

Over to the combine experts.



More information about the Gcc-bugs mailing list