combiner bug and fix
Denis Chertykov
denisc@overta.ru
Thu Jun 19 16:07:00 GMT 2003
I have analyzed the bug# 11181 and founded that it's a combiner bug.
Combiner tries to combine the foolowing insns:
(insn 13 11 14 1 (set (reg:QI 42)
(xor:QI (reg:QI 24 r24)
(reg:QI 43))) 54 {xorqi3} (insn_list 10 (nil))
(expr_list:REG_DEAD (reg:QI 24 r24)
(nil)))
(note 14 13 15 1 NOTE_INSN_DELETED)
(note 15 14 16 1 NOTE_INSN_DELETED)
(note 16 15 17 1 NOTE_INSN_DELETED)
(jump_insn 17 16 22 1 (set (pc)
(if_then_else (eq (zero_extract:HI (reg:QI 42)
(const_int 1 [0x1])
(const_int 0 [0x0]))
(const_int 0 [0x0]))
(label_ref 9)
(pc))) 97 {*sbrx_branch} (insn_list 13 (nil))
(expr_list:REG_DEAD (reg:QI 42)
(expr_list:REG_BR_PROB (const_int 8900 [0x22c4])
(nil))))
In process of combining it builds the following rtl:
(zero_extract:HI (xor:QI (reg:QI 24 r24)
(reg:QI 43))
(const_int 1 [0x1])
(const_int 0 [0x0]))
And tries to simplify it by combine_simplify_rtx -> simplify_shift_const.
simplify_shift_const have the following fragment:
/* If we can't do that, try to simplify the shift in each arm of the
logical expression, make a new logical expression, and apply
the inverse distributive law. */
{
rtx lhs = simplify_shift_const (NULL_RTX, code, shift_mode,
XEXP (varop, 0), count);
rtx rhs = simplify_shift_const (NULL_RTX, code, shift_mode,
XEXP (varop, 1), count);
varop = gen_binary (GET_CODE (varop), shift_mode, lhs, rhs);
varop = apply_distributive_law (varop);
count = 0;
}
break;
----------------------------------------------------
IMHO: it's buggy because lhs and/or rhs can be (clobber (const_int 0))
and building of varop are wrong because builded rtl seems like:
(xor:HI (clobber:QI (const_int 0 [0x0]))
(clobber:QI (const_int 0 [0x0])))
It's a wrong rtl which must be rejected by combiner, but it have a
code XOR which is valid and this rtl will be processed. It is a
problem because the new rtl
(zero_extract:HI (xor:HI (clobber:QI (const_int 0 [0x0]))
(clobber:QI (const_int 0 [0x0])))
(const_int 1 [0x1])
(const_int 0 [0x0]))
will be simplified to (const_int 1).
The fix.
2003-6-19 Denis Chertykov <denisc@overta.ru>
* combine.c (simplify_shift_const): Handle the CLOBBER rtx and
don't build a binary operation with it.
Index: combine.c
===================================================================
RCS file: /cvsroot/gcc/egcs/gcc/combine.c,v
retrieving revision 1.363
diff -c -3 -p -r1.363 combine.c
*** combine.c 13 Jun 2003 22:13:07 -0000 1.363
--- combine.c 19 Jun 2003 07:13:44 -0000
*************** simplify_shift_const (rtx x, enum rtx_co
*** 9670,9683 ****
logical expression, make a new logical expression, and apply
the inverse distributive law. */
{
rtx lhs = simplify_shift_const (NULL_RTX, code, shift_mode,
XEXP (varop, 0), count);
! rtx rhs = simplify_shift_const (NULL_RTX, code, shift_mode,
XEXP (varop, 1), count);
!
! varop = gen_binary (GET_CODE (varop), shift_mode, lhs, rhs);
! varop = apply_distributive_law (varop);
!
count = 0;
}
break;
--- 9670,9693 ----
logical expression, make a new logical expression, and apply
the inverse distributive law. */
{
+ rtx rhs;
rtx lhs = simplify_shift_const (NULL_RTX, code, shift_mode,
XEXP (varop, 0), count);
! if (GET_CODE (lhs) != CLOBBER)
! {
! rhs = simplify_shift_const (NULL_RTX, code, shift_mode,
XEXP (varop, 1), count);
! if (GET_CODE (rhs) != CLOBBER)
! {
! varop = gen_binary (GET_CODE (varop), shift_mode,
! lhs, rhs);
! varop = apply_distributive_law (varop);
! }
! else
! varop = rhs;
! }
! else
! varop = lhs;
count = 0;
}
break;
More information about the Gcc-patches
mailing list