diff options
author | Manolis Tsamis <manolis.tsamis@vrull.eu> | 2024-08-13 10:17:49 +0200 |
---|---|---|
committer | Philipp Tomsich <philipp.tomsich@vrull.eu> | 2024-08-13 21:52:18 +0200 |
commit | cc00a737e840986f4916918759ba214a95ae6888 (patch) | |
tree | e7ef5b06eae5c5994e417e0ecfeed068910c0395 | |
parent | 9988d7e004796ab531df7bcda45788a7aa9276d7 (diff) | |
download | gcc-cc00a737e840986f4916918759ba214a95ae6888.zip gcc-cc00a737e840986f4916918759ba214a95ae6888.tar.gz gcc-cc00a737e840986f4916918759ba214a95ae6888.tar.bz2 |
ifcvt: Fix force_operand ICE in noce_convert_multiple_sets [PR116353]
Now that more operations are allowed for noce_convert_multiple_sets,
we need to check noce_can_force_operand on the sequence before calling
try_emit_cmove_seq. Otherwise an inappropriate argument may be given
to copy_to_mode_reg and result in an ICE.
PR tree-optimization/116353
gcc/ChangeLog:
* ifcvt.cc (bb_ok_for_noce_convert_multiple_sets): Check
noce_can_force_operand.
gcc/testsuite/ChangeLog:
* gcc.target/i386/pr116353.c: New test.
-rw-r--r-- | gcc/ifcvt.cc | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr116353.c | 55 |
2 files changed, 59 insertions, 2 deletions
diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc index 3e25f30..da59c90 100644 --- a/gcc/ifcvt.cc +++ b/gcc/ifcvt.cc @@ -3938,8 +3938,10 @@ bb_ok_for_noce_convert_multiple_sets (basic_block test_bb, unsigned *cost) rtx src = SET_SRC (set); /* Do not handle anything involving memory loads/stores since it might - violate data-race-freedom guarantees. */ - if (!REG_P (dest) || contains_mem_rtx_p (src)) + violate data-race-freedom guarantees. Make sure we can force SRC + to a register as that may be needed in try_emit_cmove_seq. */ + if (!REG_P (dest) || contains_mem_rtx_p (src) + || !noce_can_force_operand (src)) return false; /* Destination and source must be appropriate. */ diff --git a/gcc/testsuite/gcc.target/i386/pr116353.c b/gcc/testsuite/gcc.target/i386/pr116353.c new file mode 100644 index 0000000..8e25465 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr116353.c @@ -0,0 +1,55 @@ +/* PR tree-optimization/116353 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +enum desmode { C }; +struct { + unsigned char des_ivec[]; +} _des_crypt_desp; +int des_SPtrans_6_0, des_SPtrans_4_0, des_encrypt_encrypt, des_encrypt_i; +long des_encrypt_s_0, _des_crypt_tin1, _des_crypt_tout0, _des_crypt_tout1, + _des_crypt_tin0; +enum desmode _des_crypt_desp_0; +unsigned long _des_crypt_tbuf[2]; +char _des_crypt_out; +void des_encrypt(unsigned long *buf) { + long l, r, t; + l = buf[0]; + r = buf[1]; + t = r; + r ^= l ^= t < 6; + if (des_encrypt_encrypt) + for (;; des_encrypt_i += 4) + des_encrypt_s_0 ^= des_SPtrans_4_0 | des_SPtrans_6_0; + buf[1] = r; +} +void _des_crypt() { + long xor0, xor1; + unsigned char *in; + int cbc_mode = _des_crypt_desp_0; + in = _des_crypt_desp.des_ivec; + xor0 = xor1 = 0; + for (;;) { + _des_crypt_tin0 = *in++; + _des_crypt_tin0 |= *in++ << 8; + _des_crypt_tin0 |= *in++ << 16; + _des_crypt_tin0 |= (long)*in << 24; + _des_crypt_tin1 = *in++; + _des_crypt_tin1 |= *in++ << 8; + _des_crypt_tin1 |= *in++ << 16; + _des_crypt_tin1 |= (long)*in << 24; + _des_crypt_tbuf[0] = _des_crypt_tin0; + _des_crypt_tbuf[1] = _des_crypt_tin1; + des_encrypt(_des_crypt_tbuf); + if (cbc_mode) { + _des_crypt_tout0 = xor0; + _des_crypt_tout1 = _des_crypt_tbuf[1] ^ xor1; + xor0 = _des_crypt_tin0; + xor1 = _des_crypt_tin1; + } else { + _des_crypt_tout0 = _des_crypt_tbuf[0]; + _des_crypt_tout1 = _des_crypt_tbuf[1]; + } + _des_crypt_out = _des_crypt_tout0 * _des_crypt_tout1; + } +} |