From patchwork Fri Feb 17 16:51:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 58716 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp993489wrn; Fri, 17 Feb 2023 08:52:15 -0800 (PST) X-Google-Smtp-Source: AK7set9giJmnSxCA9YyuSKvHR9AZ+CaxSLxLEn0tVcWbcN4Y+4c9t/2Deg+FlJpWgnmKjHiGzf35 X-Received: by 2002:a17:907:c249:b0:8af:12d9:a4ac with SMTP id tj9-20020a170907c24900b008af12d9a4acmr6416069ejc.25.1676652735033; Fri, 17 Feb 2023 08:52:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1676652735; cv=none; d=google.com; s=arc-20160816; b=LKb/kBhbr57hItHPKnDRMya76/kKb1D6F4FkbDL5Fs5qRaCToTUErKKJisyodVqt3b G/L6/i+zkl0SUu+wxAB2Q5BPIas9Vpaj4reU8jWFJXy7b/gJvrphk0tUQkYodgJBBdhe AYkCBXIsV7kMB9o0T+7HMFFKMh8k75ULcmKKxR/VmBPgWtGNshND4qm5MThj6HNztz4O qSVP+Jn/G6Tbo0DD+wQ1fbCNBnNbIl7ytH37EFs2lWMAU0aK4U14FwFqGFAsAB/zqeBv CayJHO7kZezN/C+uGoXw8hAoFhCqkmvz4s+7mc0u3I5HQuL1URxvbGD2kXeK0ol57OwH Kgqw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:to:subject :message-id:date:mime-version:dmarc-filter:delivered-to :dkim-signature:dkim-filter; bh=MQjv0Cdbiwpk95Btqhfs5IQAuo2anogQQQijkp5SHg8=; b=ri7OOIqCz11jKoleyPuU8WqNj824aw1secSBRHVLUzKDfJyrUm0HSeuuWU8EtiJFv0 Xqx3M2grbMwyekBQdV3ekGPn4Rc98P03R9q5lvkCpQgxE4tMBLladcEAYKoAqAHXgHNP RwIAs9qzCM8kkKh3cbF6slo+K07MYLA94NOem9Km3xpK0SaPlPLt8EA3S0tTJrU2qpiN AeIckHj/TVGtctNg14UNEihR7Vs2MphPw/Ovs43kZIOOQx+rE1ecTGFez94xrrMuunz3 tmxNXixb4h04MBZXcebZJ0J/+rdE0bg0AODz8zRKRfxxEPh2pyP2WJpq5ykhPnLNBAS9 tc5Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=iUaGCm5+; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id uj20-20020a170907c99400b008b150dada27si5907943ejc.130.2023.02.17.08.52.14 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Feb 2023 08:52:15 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=iUaGCm5+; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id CF421385040B for ; Fri, 17 Feb 2023 16:52:13 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CF421385040B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1676652733; bh=MQjv0Cdbiwpk95Btqhfs5IQAuo2anogQQQijkp5SHg8=; h=Date:Subject:To:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=iUaGCm5+lLw1l8hXRhJPASqkkYkP2upqla6X4n0O8smXPx1BKe0a+hsJ/mGig92+s DzQfRrg2J+LPXFpkYZrfMR4Vnu7dRPNGvi60Da95R0LARSdmpUwv3cAsdo3wrskzAW DNJigi5an2SeeBNXpprgf7UzSe6vzHzB3vgBZNco= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-yb1-xb35.google.com (mail-yb1-xb35.google.com [IPv6:2607:f8b0:4864:20::b35]) by sourceware.org (Postfix) with ESMTPS id 1862B385781F for ; Fri, 17 Feb 2023 16:51:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1862B385781F Received: by mail-yb1-xb35.google.com with SMTP id d196so1818516ybh.12 for ; Fri, 17 Feb 2023 08:51:27 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=MQjv0Cdbiwpk95Btqhfs5IQAuo2anogQQQijkp5SHg8=; b=aXNQcig69R7VYjYfByWUdobqFDvT2qWyO8afUQZTwiZTdOGxlOSGkmFpbrGup3GwhE 1PUEcRkmKL0vZzSH81ApP8TWLRRl18bkgxjLhJOPeWfgFmM99jd25pRL1X3SSnejFhr6 7yqE9cNwMlv4UhRzgh83CAxOSR12PmNvxPlpamTbdcCK3FRal7qxoER7J2lw19pQJ06B g56lK2VvzyRMr/w6Ym7FTS/8QoWacsU2LD0zfa53ObaXeVLHDL1riNMFnMDW6dI1H1Qy UolY91P2UBtbTuKIFoke+ils7Swknk3nUVpLpO+aOCb+3uy1Hhjo3haCwSJyDWfwPFOB 9fxw== X-Gm-Message-State: AO0yUKU+v6Tb3MM0bS+FlwDQxgfvR8Z2Mlp6Y1KzA/EhcC3oyLfMiTlw XFSvcw+F6OidzHET1HyZU3AyrtAHG3C+W5iQOLULeDFWat0KWg== X-Received: by 2002:a5b:749:0:b0:8a9:b677:52a7 with SMTP id s9-20020a5b0749000000b008a9b67752a7mr173769ybq.30.1676652686048; Fri, 17 Feb 2023 08:51:26 -0800 (PST) MIME-Version: 1.0 Date: Fri, 17 Feb 2023 17:51:14 +0100 Message-ID: Subject: [PATCH] i386: Generate QImode binary ops with high-part input register [PR108831] To: "gcc-patches@gcc.gnu.org" X-Spam-Status: No, score=-7.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Uros Bizjak via Gcc-patches From: Uros Bizjak Reply-To: Uros Bizjak Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1758097818339730009?= X-GMAIL-MSGID: =?utf-8?q?1758097818339730009?= Following testcase: --cut here-- struct S { unsigned char pad1; unsigned char val; unsigned short pad2; }; unsigned char test_add (unsigned char a, struct S b) { a += b.val; return a; } --cut here-- should be compiled to something like: addb %dh, %al but is currently compiled to: movzbl %dh, %edx addl %edx, %eax The patch implements insn patterns that model QImode binary ops with high-part QImode input register. These ops can not be encoded with REX prefix, so only Q registers and constant memory output operands are allowed on x86_64 targets. 2023-02-17 Uroš Bizjak gcc/ChangeLog: PR target/108831 * config/i386/predicates.md (nonimm_x64constmem_operand): New predicate. * config/i386/i386.md (*addqi_ext_0): New insn pattern. (*subqi_ext_0): Ditto. (*andqi_ext_0): Ditto. (*qi_ext_0): Ditto. gcc/testsuite/ChangeLog: PR target/108831 * gcc.target/i386/pr108831-1.c: New test. * gcc.target/i386/pr108831-2.c: Ditto. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Pushed to master. Uros. diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 198f06e0769..55042e7ae15 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -6641,6 +6641,22 @@ (define_insn "*add_5" (const_string "*"))) (set_attr "mode" "")]) +(define_insn "*addqi_ext_0" + [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m") + (plus:QI + (subreg:QI + (zero_extract:SWI248 + (match_operand 2 "int248_register_operand" "Q,Q") + (const_int 8) + (const_int 8)) 0) + (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0"))) + (clobber (reg:CC FLAGS_REG))] + "" + "add{b}\t{%h2, %0|%0, %h2}" + [(set_attr "isa" "*,nox64") + (set_attr "type" "alu") + (set_attr "mode" "QI")]) + (define_expand "addqi_ext_1" [(parallel [(set (zero_extract:HI (match_operand:HI 0 "register_operand") @@ -7265,6 +7281,22 @@ (define_insn "*subsi_2_zext" [(set_attr "type" "alu") (set_attr "mode" "SI")]) +(define_insn "*subqi_ext_0" + [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m") + (minus:QI + (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0") + (subreg:QI + (zero_extract:SWI248 + (match_operand 2 "int248_register_operand" "Q,Q") + (const_int 8) + (const_int 8)) 0))) + (clobber (reg:CC FLAGS_REG))] + "" + "sub{b}\t{%h2, %0|%0, %h2}" + [(set_attr "isa" "*,nox64") + (set_attr "type" "alu") + (set_attr "mode" "QI")]) + (define_insn "*subqi_ext_2" [(set (zero_extract:SWI248 (match_operand 0 "int248_register_operand" "+Q") @@ -10528,6 +10560,22 @@ (define_insn "*and_2" [(set_attr "type" "alu") (set_attr "mode" "")]) +(define_insn "*andqi_ext_0" + [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m") + (and:QI + (subreg:QI + (zero_extract:SWI248 + (match_operand 2 "int248_register_operand" "Q,Q") + (const_int 8) + (const_int 8)) 0) + (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0"))) + (clobber (reg:CC FLAGS_REG))] + "" + "and{b}\t{%h2, %0|%0, %h2}" + [(set_attr "isa" "*,nox64") + (set_attr "type" "alu") + (set_attr "mode" "QI")]) + (define_expand "andqi_ext_1" [(parallel [(set (zero_extract:HI (match_operand:HI 0 "register_operand") @@ -11269,6 +11317,22 @@ (define_insn "*_3" [(set_attr "type" "alu") (set_attr "mode" "")]) +(define_insn "*qi_ext_0" + [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m") + (any_or:QI + (subreg:QI + (zero_extract:SWI248 + (match_operand 2 "int248_register_operand" "Q,Q") + (const_int 8) + (const_int 8)) 0) + (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0"))) + (clobber (reg:CC FLAGS_REG))] + "" + "{b}\t{%h2, %0|%0, %h2}" + [(set_attr "isa" "*,nox64") + (set_attr "type" "alu") + (set_attr "mode" "QI")]) + (define_insn "*qi_ext_1" [(set (zero_extract:SWI248 (match_operand 0 "int248_register_operand" "+Q,Q") diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 2f079a6fad8..7b3db0cc851 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -109,6 +109,13 @@ (define_special_predicate "int_nonimmediate_operand" (match_test "GET_MODE (op) == HImode") (match_test "GET_MODE (op) == QImode")))) +;; Match nonimmediate operand, but exclude non-constant addresses for x86_64. +(define_predicate "nonimm_x64constmem_operand" + (ior (match_operand 0 "register_operand") + (and (match_operand 0 "memory_operand") + (ior (not (match_test "TARGET_64BIT")) + (match_test "constant_address_p (XEXP (op, 0))"))))) + ;; Match register operands, but include memory operands for TARGET_SSE_MATH. (define_predicate "register_ssemem_operand" (if_then_else diff --git a/gcc/testsuite/gcc.target/i386/pr108831-1.c b/gcc/testsuite/gcc.target/i386/pr108831-1.c new file mode 100644 index 00000000000..3499b187cbe --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr108831-1.c @@ -0,0 +1,63 @@ +/* PR target/108831 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -masm=att" } */ +/* { dg-additional-options "-mregparm=3" { target ia32 } } */ +/* { dg-final { scan-assembler-not "movzbl" } } */ +/* { dg-final { scan-assembler-not "movb" } } */ + +struct S +{ + unsigned char pad1; + unsigned char val; + unsigned short pad2; +}; + +unsigned char +test_and (unsigned char a, struct S b) +{ + a &= b.val; + + return a; +} + +/* { dg-final { scan-assembler "\[ \t\]andb" } } */ + +unsigned char +test_or (unsigned char a, struct S b) +{ + a |= b.val; + + return a; +} + +/* { dg-final { scan-assembler "\[ \t\]orb" } } */ + +unsigned char +test_xor (unsigned char a, struct S b) +{ + a ^= b.val; + + return a; +} + +/* { dg-final { scan-assembler "\[ \t\]xorb" } } */ + +unsigned char +test_add (unsigned char a, struct S b) +{ + a += b.val; + + return a; +} + +/* { dg-final { scan-assembler "\[ \t\]addb" } } */ + +unsigned char +test_sub (unsigned char a, struct S b) +{ + a -= b.val; + + return a; +} + +/* { dg-final { scan-assembler "\[ \t\]subb" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr108831-2.c b/gcc/testsuite/gcc.target/i386/pr108831-2.c new file mode 100644 index 00000000000..a415391f69d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr108831-2.c @@ -0,0 +1,55 @@ +/* PR target/108831 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -masm=att" } */ +/* { dg-additional-options "-mregparm=3" { target ia32 } } */ +/* { dg-final { scan-assembler-not "movzbl" } } */ +/* { dg-final { scan-assembler-not "movb" } } */ + +struct S +{ + unsigned char pad1; + unsigned char val; + unsigned short pad2; +}; + +unsigned char a; + +void +test_and (struct S b) +{ + a &= b.val; +} + +/* { dg-final { scan-assembler "\[ \t\]andb" } } */ + +void +test_or (struct S b) +{ + a |= b.val; +} + +/* { dg-final { scan-assembler "\[ \t\]orb" } } */ + +void +test_xor (struct S b) +{ + a ^= b.val; +} + +/* { dg-final { scan-assembler "\[ \t\]xorb" } } */ + +void +test_add (struct S b) +{ + a += b.val; +} + +/* { dg-final { scan-assembler "\[ \t\]addb" } } */ + +void +test_sub (struct S b) +{ + a -= b.val; +} + +/* { dg-final { scan-assembler "\[ \t\]subb" } } */