diff options
author | Jakub Jelinek <jakub@redhat.com> | 2016-02-12 17:49:44 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-02-12 17:49:44 +0100 |
commit | c3090c1f521bb5fedd5e7f977bce1bf0e1fc0a8e (patch) | |
tree | 4720e253b740575b1b04e427d1aaaddcb7eee59e /gcc/optabs.c | |
parent | 8222034d0514bef24332f8d9cb848241d688d09b (diff) | |
download | gcc-c3090c1f521bb5fedd5e7f977bce1bf0e1fc0a8e.zip gcc-c3090c1f521bb5fedd5e7f977bce1bf0e1fc0a8e.tar.gz gcc-c3090c1f521bb5fedd5e7f977bce1bf0e1fc0a8e.tar.bz2 |
re PR rtl-optimization/69764 (ICE on x86_64-linux-gnu at -O0 (in decompose, at rtl.h:2107))
PR rtl-optimization/69764
PR rtl-optimization/69771
* optabs.c (expand_binop_directly): For shift_optab_p, force
convert_modes with VOIDmode if xop1 has VOIDmode.
* c-c++-common/pr69764.c: New test.
* gcc.dg/torture/pr69771.c: New test.
From-SVN: r233381
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r-- | gcc/optabs.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c index e1ba615..b651878 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -993,6 +993,7 @@ expand_binop_directly (machine_mode mode, optab binoptab, bool commutative_p; rtx_insn *pat; rtx xop0 = op0, xop1 = op1; + bool canonicalize_op1 = false; /* If it is a commutative operator and the modes would match if we would swap the operands, we can save the conversions. */ @@ -1006,6 +1007,11 @@ expand_binop_directly (machine_mode mode, optab binoptab, xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp); if (!shift_optab_p (binoptab)) xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp); + else + /* Shifts and rotates often use a different mode for op1 from op0; + for VOIDmode constants we don't know the mode, so force it + to be canonicalized using convert_modes. */ + canonicalize_op1 = true; /* In case the insn wants input operands in modes different from those of the actual operands, convert the operands. It would @@ -1020,7 +1026,8 @@ expand_binop_directly (machine_mode mode, optab binoptab, mode0 = xmode0; } - mode1 = GET_MODE (xop1) != VOIDmode ? GET_MODE (xop1) : mode; + mode1 = ((GET_MODE (xop1) != VOIDmode || canonicalize_op1) + ? GET_MODE (xop1) : mode); if (xmode1 != VOIDmode && xmode1 != mode1) { xop1 = convert_modes (xmode1, mode1, xop1, unsignedp); |