diff options
author | Uros Bizjak <ubizjak@gmail.com> | 2023-11-13 22:45:55 +0100 |
---|---|---|
committer | Uros Bizjak <ubizjak@gmail.com> | 2023-11-13 22:45:55 +0100 |
commit | c75bab7274fe60fb2def8acf06ee9f4f856ce1ac (patch) | |
tree | f369565e8affa4a2a9227629582bf5c1dacf6651 /gcc | |
parent | 97e9cde758582cdb97e3af47df6f32a8413f291f (diff) | |
download | gcc-c75bab7274fe60fb2def8acf06ee9f4f856ce1ac.zip gcc-c75bab7274fe60fb2def8acf06ee9f4f856ce1ac.tar.gz gcc-c75bab7274fe60fb2def8acf06ee9f4f856ce1ac.tar.bz2 |
i386: Return CCmode from ix86_cc_mode for unknown RTX code [PR112494]
Combine wants to combine following instructions into an insn that can
perform both an (arithmetic) operation and set the condition code. During
the conversion a new RTX is created, and combine passes the RTX code of the
innermost RTX expression of the CC use insn in which CC reg is used to
SELECT_CC_MODE, to determine the new mode of the comparison:
Trying 5 -> 8:
5: r98:DI=0xd7
8: flags:CCZ=cmp(r98:DI,0)
REG_EQUAL cmp(0xd7,0)
Failed to match this instruction:
(parallel [
(set (reg:CC 17 flags)
(compare:CC (const_int 215 [0xd7])
(const_int 0 [0])))
(set (reg/v:DI 98 [ flags ])
(const_int 215 [0xd7]))
])
where:
(insn 5 2 6 2 (set (reg/v:DI 98 [ flags ])
(const_int 215 [0xd7])) "pr112494.c":8:8 84 {*movdi_internal}
(nil))
(insn 8 7 11 2 (set (reg:CCZ 17 flags)
(compare:CCZ (reg/v:DI 98 [ flags ])
(const_int 0 [0]))) "pr112494.c":11:9 8 {*cmpdi_ccno_1}
(expr_list:REG_EQUAL (compare:CCZ (const_int 215 [0xd7])
(const_int 0 [0]))
(nil)))
x86_cc_mode (AKA SELECT_CC_MODE) is not prepared to handle random RTX
codes and triggers gcc_unreachable() when SET RTX code is passed to it.
The patch removes gcc_unreachable() and returns CCmode for unknown
RTX codes, so combine can try various combinations involving CC reg
without triggering ICE.
Please note that x86 MOV instructions do not set flags, so the above
combination is not recognized as a valid x86 instruction.
PR target/112494
gcc/ChangeLog:
* config/i386/i386.cc (ix86_cc_mode) [default]: Return CCmode.
gcc/testsuite/ChangeLog:
* gcc.target/i386/pr112494.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/i386/i386.cc | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr112494.c | 17 |
2 files changed, 19 insertions, 5 deletions
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 2c80fd8..176ca65 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -16469,12 +16469,9 @@ ix86_cc_mode (enum rtx_code code, rtx op0, rtx op1) return CCNOmode; else return CCGCmode; - /* strcmp pattern do (use flags) and combine may ask us for proper - mode. */ - case USE: - return CCmode; default: - gcc_unreachable (); + /* CCmode should be used in all other cases. */ + return CCmode; } } diff --git a/gcc/testsuite/gcc.target/i386/pr112494.c b/gcc/testsuite/gcc.target/i386/pr112494.c new file mode 100644 index 0000000..e9482f5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr112494.c @@ -0,0 +1,17 @@ +/* PR target/112494 */ +/* { dg-options "-Og -fno-tree-copy-prop -fno-tree-fre -fno-tree-ccp -fno-tree-forwprop" } */ + +#include <x86intrin.h> + +int main() +{ + long flags = 0xD7; + + __writeeflags(0xD7); + flags && !__readeflags(); + + if ((flags && (!__readeflags())) != 0xD7) + ; + + return 0; +} |