diff options
author | Uros Bizjak <ubizjak@gmail.com> | 2022-06-17 16:22:20 +0200 |
---|---|---|
committer | Uros Bizjak <ubizjak@gmail.com> | 2022-06-17 16:23:12 +0200 |
commit | 1d6044c250e3badfa2a403fee670b295106bf4fc (patch) | |
tree | 41cd82c1adc36b5c292b657960679dba4f7ae308 /gcc | |
parent | 06a1b0418fb31b833119089ea37d5d3df372a13e (diff) | |
download | gcc-1d6044c250e3badfa2a403fee670b295106bf4fc.zip gcc-1d6044c250e3badfa2a403fee670b295106bf4fc.tar.gz gcc-1d6044c250e3badfa2a403fee670b295106bf4fc.tar.bz2 |
i386: Fix VPMOV splitter [PR105993]
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 <ubizjak@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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/i386/sse.md | 30 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr105993.c | 18 |
2 files changed, 34 insertions, 14 deletions
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 3e3d96f..64ac490 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -23875,21 +23875,23 @@ (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 0000000..79e3414 --- /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; +} |