From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1251) id 2BEB53858298; Sun, 7 Aug 2022 07:51:16 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2BEB53858298 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Roger Sayle To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-1982] Allow any immediate constant in *cmp_doubleword splitter on x86_64. X-Act-Checkin: gcc X-Git-Author: Roger Sayle X-Git-Refname: refs/heads/master X-Git-Oldrev: 019a41a7cea5e9855c60b6825b6f2b7378c98eab X-Git-Newrev: a46bca36b7b3a8a7e15b04225fb2b4f9b1bed62c Message-Id: <20220807075116.2BEB53858298@sourceware.org> Date: Sun, 7 Aug 2022 07:51:16 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 07 Aug 2022 07:51:16 -0000 https://gcc.gnu.org/g:a46bca36b7b3a8a7e15b04225fb2b4f9b1bed62c commit r13-1982-ga46bca36b7b3a8a7e15b04225fb2b4f9b1bed62c Author: Roger Sayle Date: Sun Aug 7 08:49:48 2022 +0100 Allow any immediate constant in *cmp_doubleword splitter on x86_64. This patch tweaks i386.md's *cmp_doubleword splitter's predicate to allow general_operand, not just x86_64_hilo_general_operand, to improve code generation. As a general rule, i386.md's _doubleword splitters should be post-reload splitters that require integer immediate operands to be x86_64_hilo_int_operand, so that each part is a valid word mode immediate constant. As an exception to this rule, doubleword patterns that must be split before reload, because they require additional scratch registers, can use take advantage of this ability to create new pseudos, to accept any immediate constant, and call force_reg on the high and/or low parts if they are not suitable immediate operands in word mode. The benefit is shown in the new cmpti3.c test case below. __int128 x; int foo() { __int128 t = 0x1234567890abcdefLL; return x == t; } where GCC with -O2 currently generates: movabsq $1311768467294899695, %rax xorl %edx, %edx xorq x(%rip), %rax xorq x+8(%rip), %rdx orq %rdx, %rax sete %al movzbl %al, %eax ret but with this patch now generates: movabsq $1311768467294899695, %rax xorq x(%rip), %rax orq x+8(%rip), %rax sete %al movzbl %al, %eax ret 2022-08-07 Roger Sayle gcc/ChangeLog * config/i386/i386.md (*cmp_doubleword): Change predicate for x86_64_hilo_general_operand to general operand. Call force_reg on parts that are not x86_64_immediate_operand. gcc/testsuite/ChangeLog * gcc.target/i386/cmpti1.c: New test case. * gcc.target/i386/cmpti2.c: Likewise. * gcc.target/i386/cmpti3.c: Likewise. Diff: --- gcc/config/i386/i386.md | 16 +++++++++++++--- gcc/testsuite/gcc.target/i386/cmpti1.c | 8 ++++++++ gcc/testsuite/gcc.target/i386/cmpti2.c | 12 ++++++++++++ gcc/testsuite/gcc.target/i386/cmpti3.c | 13 +++++++++++++ 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 298e4b30348..fd30c573c27 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 00000000000..1c5f121e544 --- /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 00000000000..ad9572901ce --- /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 00000000000..302efd2ad59 --- /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" } } */