On Wed, Oct 16, 2019 at 05:51:11PM +0100, Jozef Lawrynowicz wrote: > We call expand_expr_real_2 from expand_mul_overflow (internal-fn.c:1604). > When we process the arguments to: > __builtin_umul_overflow ((unsigned int) (-1), y, &r); > at expr.c:8952, they go through a few transformations. > > First we generate the rtx for ((unsigned int) -1) in the HImode context > (msp430 > has 16-bit int), which generates (const_int -1). OK. > Then it gets widened in a SImode context, but since it is unsigned, we zero > extend and the rtx becomes (const_int 65535). OK. > When we call expand_mult_highpart_adjust, we are back in HImode, but using > operands which have been widened in a SImode context. This is when we > generate our problematic insns using (const_int 65535) with HImode > operands.
So, what exactly calls expand_mult_highpart_adjust, with what exact arguments (I see 3 callers). E.g. the one in expr.c already has: if (TREE_CODE (treeop1) == INTEGER_CST) op1 = convert_modes (mode, word_mode, op1, TYPE_UNSIGNED (TREE_TYPE (treeop1))); and should thus take care of op1. It doesn't have the same for op0, assumes that if only one operand is INTEGER_CST, it must be the (canonical) second one. So perhaps the bug is that something doesn't canonicalize the order of arguments? Jakub