From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2078) id B83E63858D33; Tue, 17 Oct 2023 11:14:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B83E63858D33 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1697541243; bh=9Dze9wTjT9YqhXZqBjw86BkqhqpVNvIPaAo9phU1PrA=; h=From:To:Subject:Date:From; b=FszXGXzgMcsNlLmHZ+NFZ44tiF2KHBB0UTuR5ivuRH1XUDFVCsGRm/Dw7kDfmchlA QHepOG2xvkUG4WWLMhUHM1+fhEHpfILK8zSNE4hUMqXkxHKuxOfU6nuNHKoDtIv3ST NLf5YtjXtgaxZspWskXAjTzWMtuOtAEmY9JoIUrA= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: hongtao Liu To: gcc-cvs@gcc.gnu.org Subject: [gcc r11-11065] Disparage slightly for the alternative which move DFmode between SSE_REGS and GENERAL_REGS. X-Act-Checkin: gcc X-Git-Author: liuhongt X-Git-Refname: refs/heads/releases/gcc-11 X-Git-Oldrev: af14e930244ccc9bbaa5e4efa495c2e79192dea7 X-Git-Newrev: 0d005deb6c8a956b4f7ccb6e70e8e7830a40fed9 Message-Id: <20231017111403.B83E63858D33@sourceware.org> Date: Tue, 17 Oct 2023 11:14:03 +0000 (GMT) List-Id: https://gcc.gnu.org/g:0d005deb6c8a956b4f7ccb6e70e8e7830a40fed9 commit r11-11065-g0d005deb6c8a956b4f7ccb6e70e8e7830a40fed9 Author: liuhongt Date: Wed Jul 5 13:45:11 2023 +0800 Disparage slightly for the alternative which move DFmode between SSE_REGS and GENERAL_REGS. For testcase void __cond_swap(double* __x, double* __y) { bool __r = (*__x < *__y); auto __tmp = __r ? *__x : *__y; *__y = __r ? *__y : *__x; *__x = __tmp; } GCC-14 with -O2 and -march=x86-64 options generates the following code: __cond_swap(double*, double*): movsd xmm1, QWORD PTR [rdi] movsd xmm0, QWORD PTR [rsi] comisd xmm0, xmm1 jbe .L2 movq rax, xmm1 movapd xmm1, xmm0 movq xmm0, rax .L2: movsd QWORD PTR [rsi], xmm1 movsd QWORD PTR [rdi], xmm0 ret rax is used to save and restore DFmode value. In RA both GENERAL_REGS and SSE_REGS cost zero since we didn't disparage the alternative in movdf_internal pattern, according to register allocation order, GENERAL_REGS is allocated. The patch add ? for alternative (r,v) and (v,r) just like we did for movsf/hf/bf_internal pattern, after that we get optimal RA. __cond_swap: .LFB0: .cfi_startproc movsd (%rdi), %xmm1 movsd (%rsi), %xmm0 comisd %xmm1, %xmm0 jbe .L2 movapd %xmm1, %xmm2 movapd %xmm0, %xmm1 movapd %xmm2, %xmm0 .L2: movsd %xmm1, (%rsi) movsd %xmm0, (%rdi) ret gcc/ChangeLog: PR target/110170 * config/i386/i386.md (movdf_internal): Disparage slightly for 2 alternatives (r,v) and (v,r) by adding constraint modifier '?'. gcc/testsuite/ChangeLog: * gcc.target/i386/pr110170-3.c: New test. (cherry picked from commit 37a231cc7594d12ba0822077018aad751a6fb94e) Diff: --- gcc/config/i386/i386.md | 4 ++-- gcc/testsuite/gcc.target/i386/pr110170-3.c | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 238ce09672e7..39b048610644 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -3361,9 +3361,9 @@ ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7. (define_insn "*movdf_internal" [(set (match_operand:DF 0 "nonimmediate_operand" - "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,v,r ,o ,r ,m") + "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,?r,?v,r ,o ,r ,m") (match_operand:DF 1 "general_operand" - "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,v,r ,roF,rF,rmF,rC"))] + "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x, v, r,roF,rF,rmF,rC"))] "!(MEM_P (operands[0]) && MEM_P (operands[1])) && (lra_in_progress || reload_completed || !CONST_DOUBLE_P (operands[1]) diff --git a/gcc/testsuite/gcc.target/i386/pr110170-3.c b/gcc/testsuite/gcc.target/i386/pr110170-3.c new file mode 100644 index 000000000000..70daa89e9aae --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr110170-3.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -fno-if-conversion -fno-if-conversion2" } */ +/* { dg-final { scan-assembler-not {(?n)movq.*r} } } */ + +void __cond_swap(double* __x, double* __y) { + _Bool __r = (*__x < *__y); + double __tmp = __r ? *__x : *__y; + *__y = __r ? *__y : *__x; + *__x = __tmp; +} +