Hi! In r10-1938-g460bf043c8266dd080308f4783137aee0d0f862c *testdi_1 has been changed, so that if the mask has upper 32-bits 0 and then at least one bit set, it requires CCZmode rather than CCNOmode, because in that case it uses testl instruction rather than testq and so the SF flag wouldn't respect the state of the 64-bit result. The *testqi_ext_3 define_insn_and_split needs to match that though, otherwise it can create an RTL pattern that used to match *testdi_1 but doesn't anymore and we'd ICE due to an unrecognizable insn.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2020-03-10 Jakub Jelinek <ja...@redhat.com> PR target/94088 * config/i386/i386.md (*testqi_ext_3): Call ix86_match_ccmode with CCZmode instead of CCNOmode if operands[2] has DImode and pos + len is 32. * gcc.target/i386/pr94088.c: New test. --- gcc/config/i386/i386.md.jj 2020-03-06 11:35:46.279074931 +0100 +++ gcc/config/i386/i386.md 2020-03-09 13:25:47.045165188 +0100 @@ -8826,18 +8826,23 @@ (define_insn_and_split "*testqi_ext_3" (match_operand 3 "const_int_operand" "n") (match_operand 4 "const_int_operand" "n")) (const_int 0)]))] - "ix86_match_ccmode (insn, CCNOmode) - && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode) - || GET_MODE (operands[2]) == SImode - || GET_MODE (operands[2]) == HImode - || GET_MODE (operands[2]) == QImode) + "((TARGET_64BIT && GET_MODE (operands[2]) == DImode) + || GET_MODE (operands[2]) == SImode + || GET_MODE (operands[2]) == HImode + || GET_MODE (operands[2]) == QImode) /* Ensure that resulting mask is zero or sign extended operand. */ && INTVAL (operands[4]) >= 0 && ((INTVAL (operands[3]) > 0 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32) || (<MODE>mode == DImode && INTVAL (operands[3]) > 32 - && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))" + && INTVAL (operands[3]) + INTVAL (operands[4]) == 64)) + && ix86_match_ccmode (insn, + /* *testdi_1 requires CCZmode if the mask has bit + 31 set and all bits above it clear. */ + GET_MODE (operands[2]) == DImode + && INTVAL (operands[3]) + INTVAL (operands[4]) == 32 + ? CCZmode : CCNOmode)" "#" "&& 1" [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))] --- gcc/testsuite/gcc.target/i386/pr94088.c.jj 2020-03-09 13:23:56.485796409 +0100 +++ gcc/testsuite/gcc.target/i386/pr94088.c 2020-03-09 13:23:21.627310722 +0100 @@ -0,0 +1,9 @@ +/* PR target/94088 */ +/* { dg-do compile } */ +/* { dg-options "-mtbm -O1 -fira-loop-pressure -fno-dce" } */ + +double +foo (int x) +{ + return x / (4294950402U % -65472 + 161); +} Jakub