Hello! -march=i586 activates TARGET_ZERO_EXTEND_WITH_AND, which disables movz instructions. These targets have to use and instructions, and when flags are not allowed to be clobbered a sequence of register clear + movstrict.
2016-01-27 Uros Bizjak <ubiz...@gmail.com> PR target/69512 * config/i386/i386.md (*zext<mode>_doubleword_and): New pattern. (*zext<mode>_doubleword): Disable for TARGET_ZERO_EXTEND_WITH_AND. testsuite/ChangeLog: 2016-01-27 Uros Bizjak <ubiz...@gmail.com> PR target/69512 * gcc.target/i386/pr69512.c: New test. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Committed to mainline SVN. Uros.
Index: config/i386/i386.md =================================================================== --- config/i386/i386.md (revision 232878) +++ config/i386/i386.md (working copy) @@ -3874,10 +3874,29 @@ [(set_attr "type" "imovx") (set_attr "mode" "SI")]) +(define_insn_and_split "*zext<mode>_doubleword_and" + [(set (match_operand:DI 0 "register_operand" "=&<r>") + (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))] + "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 + && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" + "#" + "&& reload_completed && GENERAL_REG_P (operands[0])" + [(set (match_dup 2) (const_int 0))] +{ + split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]); + + emit_move_insn (operands[0], const0_rtx); + + gcc_assert (!TARGET_PARTIAL_REG_STALL); + emit_insn (gen_movstrict<mode> + (gen_lowpart (<MODE>mode, operands[0]), operands[1])); +}) + (define_insn_and_split "*zext<mode>_doubleword" [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))] - "!TARGET_64BIT && TARGET_STV && TARGET_SSE2" + "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 + && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))" "#" "&& reload_completed && GENERAL_REG_P (operands[0])" [(set (match_dup 0) (zero_extend:SI (match_dup 1))) Index: testsuite/gcc.target/i386/pr69512.c =================================================================== --- testsuite/gcc.target/i386/pr69512.c (nonexistent) +++ testsuite/gcc.target/i386/pr69512.c (working copy) @@ -0,0 +1,14 @@ +/* { dg-do compile { target ia32 } } */ +/* { dg-options "-march=i586 -mavx -O2" } */ + +extern double s1[]; +extern double s2[]; +extern long long e[]; + +void test (void) +{ + int i; + + for (i = 0; i < 2; i++) + e[i] = !__builtin_isunordered(s1[i], s2[i]) && s1[i] != s2[i] ? -1 : 0; +}