From patchwork Wed Apr 19 15:06:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 1770755 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=xEv1t1s4; dkim-atps=neutral Received: from sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Q1kfS5rqPz23tD for ; Thu, 20 Apr 2023 01:07:11 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E0E8E3858C20 for ; Wed, 19 Apr 2023 15:07:07 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E0E8E3858C20 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1681916827; bh=WH1wTFRBbgD3ONIiwm6EiXKtgxnplXZWT1HwE0KXV6g=; h=Date:Subject:To:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=xEv1t1s4sHcN7MhVYPiNa3E42sUKt3CUnPA7G+zD0geZnertIAA2/aqhY1+lmEqOP WEiKSyOqgKb1yi9htfFyOHmJ9+tVRbmXGAV1BngkzaKBdFmcQ1T/VOn7Fk2ZQMpwFB Ua/9ZfBLIHXVyO/l/35zEiznz5qe0Dw4zL/aLzmI= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qv1-xf2f.google.com (mail-qv1-xf2f.google.com [IPv6:2607:f8b0:4864:20::f2f]) by sourceware.org (Postfix) with ESMTPS id A78373858D33 for ; Wed, 19 Apr 2023 15:06:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A78373858D33 Received: by mail-qv1-xf2f.google.com with SMTP id me15so12638347qvb.4 for ; Wed, 19 Apr 2023 08:06:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1681916806; x=1684508806; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=WH1wTFRBbgD3ONIiwm6EiXKtgxnplXZWT1HwE0KXV6g=; b=CqKI9vHtqq+VOQG6dP3A7VmvgZRpExTwmaWrQroSoxeTjxvfGuj1YStDWCXziA8LvE zW5Vu8qrJqLhzlIjb9Hs4AN6DnhXCZUQw41+6MivurLC9/t2jxe9lC/mS58+g1iYpCxF 3DrdBlc/D+0lRGI1WPj3hHjNaD/YkWPpPdgb8Jp1T7/YBI03RMNWuaRBa01PUSKKqKqO GVkAt0T34E8eFDIFZ8S2eAthw/kdX5CNZNna+KmrwjE/ZA8AvHsoGb5v9asgJ4irmv5F sN1jBM+TNmOE+5uBjEMtAq8sVI8NK0xPoUr496I6OFYQB/Tgf0Y7kuGLlaYEGpTRBVRh blcQ== X-Gm-Message-State: AAQBX9f53W5Ds3uvO3Q5u2TksVwUhX7ZM9sISwvDXX062hA9Ml1lUeU7 ZhfDI9x8LbLhNCARIbjYgXAJYhfhg9M8tHB101JIyjjom49N1Q== X-Google-Smtp-Source: AKy350YSeLvuzYE8zND+0bBwt4nXOo+UqIswcbgr8qcG2WAavOyWZS5Qaqqz9BYSFtrm8YJ+O6+afGbEAk147Nm1uRQ= X-Received: by 2002:a05:6214:20a3:b0:5f4:357c:3bdd with SMTP id 3-20020a05621420a300b005f4357c3bddmr2226501qvd.14.1681916805658; Wed, 19 Apr 2023 08:06:45 -0700 (PDT) MIME-Version: 1.0 Date: Wed, 19 Apr 2023 17:06:34 +0200 Message-ID: Subject: [PATCH] i386: Emit compares between high registers and memory To: "gcc-patches@gcc.gnu.org" X-Spam-Status: No, score=-7.8 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, T_SCC_BODY_TEXT_LINE 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+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" Following code: typedef __SIZE_TYPE__ size_t; struct S1s { char pad1; char val; short pad2; }; extern char ts[256]; _Bool foo (struct S1s a, size_t i) { return (ts[i] > a.val); } compiles with -O2 to: movl %edi, %eax movsbl %ah, %edi cmpb %dil, ts(%rsi) setg %al ret the compare could use high register %ah instead of %dil: movl %edi, %eax cmpb ts(%rsi), %ah setl %al ret Use any_extract code iterator to handle signed and unsigned extracts from high register and introduce peephole2 patterns to propagate norex memory operand into the compare insn. gcc/ChangeLog: PR target/78904 PR target/78952 * config/i386/i386.md (*cmpqi_ext_1_mem_rex64): New insn pattern. (*cmpqi_ext_1): Use nonimmediate_operand predicate for operand 0. Use any_extract code iterator. (*cmpqi_ext_1 peephole2): New peephole2 pattern. (*cmpqi_ext_2): Use any_extract code iterator. (*cmpqi_ext_3_mem_rex64): New insn pattern. (*cmpqi_ext_1): Use general_operand predicate for operand 1. Use any_extract code iterator. (*cmpqi_ext_3 peephole2): New peephole2 pattern. (*cmpqi_ext_4): Use any_extract code iterator. gcc/testsuite/ChangeLog: PR target/78904 PR target/78952 * gcc.target/i386/pr78952-3.c: New test. 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 1419ea4cff3..0f95d8e8918 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -1005,6 +1005,9 @@ (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")]) ;; Mapping of extend operators (define_code_iterator any_extend [sign_extend zero_extend]) +;; Mapping of extract operators +(define_code_iterator any_extract [sign_extract zero_extract]) + ;; Mapping of highpart multiply operators (define_code_iterator any_mul_highpart [smul_highpart umul_highpart]) @@ -1454,12 +1457,27 @@ (define_insn "*cmp_minus_1" [(set_attr "type" "icmp") (set_attr "mode" "")]) +(define_insn "*cmpqi_ext_1_mem_rex64" + [(set (reg FLAGS_REG) + (compare + (match_operand:QI 0 "norex_memory_operand" "Bn") + (subreg:QI + (any_extract:SWI248 + (match_operand 1 "int248_register_operand" "Q") + (const_int 8) + (const_int 8)) 0)))] + "TARGET_64BIT && reload_completed + && ix86_match_ccmode (insn, CCmode)" + "cmp{b}\t{%h1, %0|%0, %h1}" + [(set_attr "type" "icmp") + (set_attr "mode" "QI")]) + (define_insn "*cmpqi_ext_1" [(set (reg FLAGS_REG) (compare - (match_operand:QI 0 "nonimm_x64constmem_operand" "QBc,m") + (match_operand:QI 0 "nonimmediate_operand" "QBc,m") (subreg:QI - (zero_extract:SWI248 + (any_extract:SWI248 (match_operand 1 "int248_register_operand" "Q,Q") (const_int 8) (const_int 8)) 0)))] @@ -1469,11 +1487,33 @@ (define_insn "*cmpqi_ext_1" (set_attr "type" "icmp") (set_attr "mode" "QI")]) +(define_peephole2 + [(set (match_operand:QI 0 "register_operand") + (match_operand:QI 1 "norex_memory_operand")) + (set (match_operand 3 "flags_reg_operand") + (match_operator 4 "compare_operator" + [(match_dup 0) + (subreg:QI + (any_extract:SWI248 + (match_operand 2 "int248_register_operand") + (const_int 8) + (const_int 8)) 0)]))] + "TARGET_64BIT + && peep2_reg_dead_p (2, operands[0])" + [(set (match_dup 3) + (match_op_dup 4 + [(match_dup 1) + (subreg:QI + (any_extract:SWI248 + (match_dup 2) + (const_int 8) + (const_int 8)) 0)]))]) + (define_insn "*cmpqi_ext_2" [(set (reg FLAGS_REG) (compare (subreg:QI - (zero_extract:SWI248 + (any_extract:SWI248 (match_operand 0 "int248_register_operand" "Q") (const_int 8) (const_int 8)) 0) @@ -1494,31 +1534,68 @@ (define_expand "cmpqi_ext_3" (const_int 8)) 0) (match_operand:QI 1 "const_int_operand")))]) +(define_insn "*cmpqi_ext_3_mem_rex64" + [(set (reg FLAGS_REG) + (compare + (subreg:QI + (any_extract:SWI248 + (match_operand 0 "int248_register_operand" "Q") + (const_int 8) + (const_int 8)) 0) + (match_operand:QI 1 "norex_memory_operand" "Bn")))] + "TARGET_64BIT && reload_completed + && ix86_match_ccmode (insn, CCmode)" + "cmp{b}\t{%1, %h0|%h0, %1}" + [(set_attr "type" "icmp") + (set_attr "mode" "QI")]) + (define_insn "*cmpqi_ext_3" [(set (reg FLAGS_REG) (compare (subreg:QI - (zero_extract:SWI248 + (any_extract:SWI248 (match_operand 0 "int248_register_operand" "Q,Q") (const_int 8) (const_int 8)) 0) - (match_operand:QI 1 "general_x64constmem_operand" "QnBc,m")))] + (match_operand:QI 1 "general_operand" "QnBc,m")))] "ix86_match_ccmode (insn, CCmode)" "cmp{b}\t{%1, %h0|%h0, %1}" [(set_attr "isa" "*,nox64") (set_attr "type" "icmp") (set_attr "mode" "QI")]) +(define_peephole2 + [(set (match_operand:QI 0 "register_operand") + (match_operand:QI 1 "norex_memory_operand")) + (set (match_operand 3 "flags_reg_operand") + (match_operator 4 "compare_operator" + [(subreg:QI + (any_extract:SWI248 + (match_operand 2 "int248_register_operand") + (const_int 8) + (const_int 8)) 0) + (match_dup 0)]))] + "TARGET_64BIT + && peep2_reg_dead_p (2, operands[0])" + [(set (match_dup 3) + (match_op_dup 4 + [(subreg:QI + (any_extract:SWI248 + (match_dup 2) + (const_int 8) + (const_int 8)) 0) + (match_dup 1)]))]) + (define_insn "*cmpqi_ext_4" [(set (reg FLAGS_REG) (compare (subreg:QI - (zero_extract:SWI248 + (any_extract:SWI248 (match_operand 0 "int248_register_operand" "Q") (const_int 8) (const_int 8)) 0) (subreg:QI - (zero_extract:SWI248 + (any_extract:SWI248 (match_operand 1 "int248_register_operand" "Q") (const_int 8) (const_int 8)) 0)))] @@ -3374,9 +3451,6 @@ (define_peephole2 operands[4] = gen_int_mode (tmp, mode); }) - -(define_code_iterator any_extract [sign_extract zero_extract]) - (define_insn "*insvqi_2" [(set (zero_extract:SWI248 (match_operand 0 "int248_register_operand" "+Q") diff --git a/gcc/testsuite/gcc.target/i386/pr78952-3.c b/gcc/testsuite/gcc.target/i386/pr78952-3.c new file mode 100644 index 00000000000..ab00c55b370 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr78952-3.c @@ -0,0 +1,40 @@ +/* PR target/78952 */ +/* { dg-do compile } */ +/* { dg-require-effective-target nonpic } */ +/* { dg-options "-O2 -masm=att" } */ +/* { dg-additional-options "-mregparm=1" { target ia32 } } */ +/* { dg-final { scan-assembler-not "mov\[sz]bl" } } */ + +typedef __SIZE_TYPE__ size_t; + +struct S1s +{ + char pad1; + char val; + short pad2; +}; + +extern char ts[256]; + +_Bool foo (struct S1s a, size_t i) +{ + return (ts[i] > a.val); +} + +/* { dg-final { scan-assembler "cmpb\[ \\t]+ts\[^\n]*%.h" } } */ + +struct S1u +{ + unsigned char pad1; + unsigned char val; + unsigned short pad2; +}; + +extern unsigned char tu[256]; + +_Bool bar (struct S1u a, size_t i) +{ + return (tu[i] > a.val); +} + +/* { dg-final { scan-assembler "cmpb\[ \\t]+tu\[^\n]*%.h" } } */