REGNO should not be used with register_operand before reload because subregs of registers or even subregs of memory match the predicate. The build with RTL checking enabled does not tolerate REGNO with non-reg operand. The patch splits the splitter into two related splitters and uses (match_dup ...) RTXes instead of REGNO comparisons.
2022-06-17 Uroš Bizjak <ubiz...@gmail.com> gcc/ChangeLog: PR target/105993 * config/i386/sse.md (vpmov splitter): Use (match_dup ...) instead of REGNO comparisons in combine splitter. gcc/testsuite/ChangeLog: PR target/105993 * gcc.target/i386/pr105993.c: New test. Bootstrapped and regression tested on x86_64-linux-gnu ,-m32}. Pushed to master. Uros.
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 3e3d96fe087..64ac490d272 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -23875,21 +23875,23 @@ (define_split (xor:V_128_256 (match_operand:V_128_256 1 "register_operand") (match_operand:V_128_256 2 "register_operand")) (match_operand:V_128_256 3 "nonimmediate_operand")) - (match_operand:V_128_256 4 "register_operand")))] - "TARGET_XOP - && (REGNO (operands[4]) == REGNO (operands[1]) - || REGNO (operands[4]) == REGNO (operands[2]))" + (match_dup 1)))] + "TARGET_XOP" [(set (match_dup 0) (if_then_else:V_128_256 (match_dup 3) - (match_dup 5) - (match_dup 4)))] -{ - /* To handle the commutivity of XOR, operands[4] is either operands[1] - or operands[2], we need operands[5] to be the other one. */ - if (REGNO (operands[4]) == REGNO (operands[1])) - operands[5] = operands[2]; - else - operands[5] = operands[1]; -}) + (match_dup 2) + (match_dup 1)))]) +(define_split + [(set (match_operand:V_128_256 0 "register_operand") + (xor:V_128_256 + (and:V_128_256 + (xor:V_128_256 (match_operand:V_128_256 1 "register_operand") + (match_operand:V_128_256 2 "register_operand")) + (match_operand:V_128_256 3 "nonimmediate_operand")) + (match_dup 2)))] + "TARGET_XOP" + [(set (match_dup 0) (if_then_else:V_128_256 (match_dup 3) + (match_dup 1) + (match_dup 2)))]) ;; XOP horizontal add/subtract instructions (define_insn "xop_phadd<u>bw" diff --git a/gcc/testsuite/gcc.target/i386/pr105993.c b/gcc/testsuite/gcc.target/i386/pr105993.c new file mode 100644 index 00000000000..79e3414f67b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr105993.c @@ -0,0 +1,18 @@ +/* PR target/105993 */ +/* { dg-do compile } */ +/* { dg-options "-O -mxop" } */ + +typedef unsigned short __attribute__((__vector_size__ (16))) V; +V x, y, z; + +char c; +short s; + +V +foo (void) +{ + V u = __builtin_shufflevector (z, y, 2, 1, 0, 8, 4, 1, 7, 2); + V v = ~(__builtin_bswap16 (s) & (u ^ c)); + + return v; +}