aboutsummaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2016-02-12 16:49:44 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2016-02-12 16:49:44 +0000
commitfcce1b0b4dcb9e1f0d2a4ad36a7a2baca8a2218b (patch)
tree4720e253b740575b1b04e427d1aaaddcb7eee59e /gcc/optabs.c
parent6d6092901a6c55f7e6173e6ad06deeb5df191975 (diff)
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@233381 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r--gcc/optabs.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c
index e1ba6150473..b651878b725 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);