https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69459
--- Comment #7 from Uroš Bizjak <ubizjak at gmail dot com> --- (In reply to Jakub Jelinek from comment #6) > (In reply to Uroš Bizjak from comment #5) > > (In reply to Jakub Jelinek from comment #4) > > > > > I'd say the i386 backend just should add a new constraint for CONST0_RTX > > > only and use it wherever the all ones is not allowed. As "C" is > > > documented, > > > probably the new "BC" constraint should be const0/CONST0_RTX only, and I > > > think at least the vector_move_operand, reg_or_0_operand and likely the > > > const_int_operand cases too should be changed to "BC". At least that way > > > the RA and other spots will not try to satisfy it with something that > > > can't > > > match. > > > > Yes, let's go this way. > > Ok, will work on it tomorrow. Heh, it looks we can change "C" constraint to mean only zero. Please consider following testcase: --cut here-- typedef int __v4si __attribute__ ((__vector_size__ (16))); void test (void) { asm volatile ("%0" : : "C" ( (__v4si) { -1, -1, -1, -1 } )); } --cut here-- This is the only way "C" constraint can be satisfied by non-zero operand. Trying to compile this, we get: c.c: In function ‘test’: c.c:6:1: internal compiler error: in ix86_print_operand, at config/i386/i386.c:17289 17284 /* We have patterns that allow zero sets of memory, for instance. 17285 In 64-bit mode, we should probably support all 8-byte vectors, 17286 since we can in fact encode that into an immediate. */ 17287 if (GET_CODE (x) == CONST_VECTOR) 17288 { 17289 gcc_assert (x == CONST0_RTX (GET_MODE (x))); 17290 x = const0_rtx; 17291 } Based on this evidence, there is no way "C" constraint ca be used with non-zero immediate. So, let's change "C" constraint to: ;; This can theoretically be any mode's CONST0_RTX. (define_constraint "C" "Constant zero." (match_test "op == const0_rtx || op == CONST0_RTX (GET_MODE (op))")) and add new BC constraint (define_constraint "BC" "@internal SSE constant operand." (match_test "standard_sse_constant_p (op)")) that is used only in SSE move pattern: (define_insn "*mov<mode>_internal" [(set (match_operand:VMOVE 0 "nonimmediate_operand" "=v,v ,m") (match_operand:VMOVE 1 "nonimmediate_or_sse_const_operand" "BC,vm,v"))] "TARGET_SSE && (register_operand (operands[0], <MODE>mode) || register_operand (operands[1], <MODE>mode))"