diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 298e4b3..fd30c57 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -1510,7 +1510,7 @@ (define_insn_and_split "*cmp_doubleword" [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_operand: 0 "nonimmediate_operand") - (match_operand: 1 "x86_64_hilo_general_operand")))] + (match_operand: 1 "general_operand")))] "ix86_pre_reload_split ()" "#" "&& 1" @@ -1544,7 +1544,12 @@ else if (operands[0] == constm1_rtx) emit_insn (gen_one_cmpl2 (operands[4], operands[1])); else - emit_insn (gen_xor3 (operands[4], operands[0], operands[1])); + { + if (CONST_SCALAR_INT_P (operands[1]) + && !x86_64_immediate_operand (operands[1], mode)) + operands[1] = force_reg (mode, operands[1]); + emit_insn (gen_xor3 (operands[4], operands[0], operands[1])); + } if (operands[3] == const0_rtx) operands[5] = operands[2]; @@ -1558,7 +1563,12 @@ else if (operands[2] == constm1_rtx) emit_insn (gen_one_cmpl2 (operands[5], operands[3])); else - emit_insn (gen_xor3 (operands[5], operands[2], operands[3])); + { + if (CONST_SCALAR_INT_P (operands[3]) + && !x86_64_immediate_operand (operands[3], mode)) + operands[3] = force_reg (mode, operands[3]); + emit_insn (gen_xor3 (operands[5], operands[2], operands[3])); + } } }) diff --git a/gcc/testsuite/gcc.target/i386/cmpti1.c b/gcc/testsuite/gcc.target/i386/cmpti1.c new file mode 100644 index 0000000..1c5f121 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cmpti1.c @@ -0,0 +1,8 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2" } */ +int eq(__int128 x, __int128 y) { return x == y; } +int ne(__int128 x, __int128 y) { return x != y; } +/* { dg-final { scan-assembler-times "xorq" 4 } } */ +/* { dg-final { scan-assembler-times "setne" 1 } } */ +/* { dg-final { scan-assembler-times "sete" 1 } } */ + diff --git a/gcc/testsuite/gcc.target/i386/cmpti2.c b/gcc/testsuite/gcc.target/i386/cmpti2.c new file mode 100644 index 0000000..ad95729 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cmpti2.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2" } */ + +__int128 x; +__int128 y; + +int eq() { return x == y; } +int ne() { return x != y; } + +/* { dg-final { scan-assembler-times "xorq" 4 } } */ +/* { dg-final { scan-assembler-times "setne" 1 } } */ +/* { dg-final { scan-assembler-times "sete" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/cmpti3.c b/gcc/testsuite/gcc.target/i386/cmpti3.c new file mode 100644 index 0000000..302efd2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cmpti3.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2" } */ + +__int128 x; +int foo() +{ + __int128 t = 0x1234567890abcdefLL; + return x == t; +} + +/* { dg-final { scan-assembler-times "movabsq" 1 } } */ +/* { dg-final { scan-assembler-times "xorq" 1 } } */ +/* { dg-final { scan-assembler-not "xorl" } } */