From patchwork Sun Dec 19 20:06:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 49100 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 24A943858410 for ; Sun, 19 Dec 2021 20:07:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 24A943858410 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1639944426; bh=VrkA5478+o10VxgXU0aRyf831eQRtmV5DiqKu7l89ME=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=NQ2cvuBc9fwmfizHd4ut+H0jT5vBEkDETWxEFiJvp5ALg6cmhJ+EKnwuIAlh9kOEY oriRdaPlDN3F1+gmFgw1NGO9UZ5ZKLKTOBfi1ZL5ukvT2ZVAtMwonl7v6zmCNUfs2q mZnhcVv8FYNZpb2B9C9ftizxZtPfCb00W1KKi3Rc= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pf1-x42a.google.com (mail-pf1-x42a.google.com [IPv6:2607:f8b0:4864:20::42a]) by sourceware.org (Postfix) with ESMTPS id 495CC3858400 for ; Sun, 19 Dec 2021 20:06:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 495CC3858400 Received: by mail-pf1-x42a.google.com with SMTP id t123so5527667pfc.13 for ; Sun, 19 Dec 2021 12:06:34 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=VrkA5478+o10VxgXU0aRyf831eQRtmV5DiqKu7l89ME=; b=vMzMoIlvHhyXeLat/DhzO8U09X2+bcweUbsf5Zc9eG4Ejmjp2KidqZHTOOVon9osPR 5VkQW9Clezi59fvZe1/40R5Bi6Qg0fXbnRMMWaOwjAKqxonDwed8iCpJKwcVtF9qKPEp SmXfVkqMIWdwA8vaFa8XeuGBCZf88BEvrmIPxhksZH2NEgxf1U9Ztu9rafN2SRVJwUch +0YjgXq01qRcUfgqbgWfESskdKFz12HQRIl1OoorniEPQxRMaQ9Vn5qHn0BUZJ2SjEeH nyLapIWkMhGJi7MyUBPkgRyMbF4bV1LG/SEy39fkriXBrH3JTrxGBO2fhINr/AiF2/vL d17A== X-Gm-Message-State: AOAM531CE+T+eOw7PG/fhFezuVWOqb3HXWFTsn0pNYEDCQIHXs6gKupc HH43PpWHNix0n5Ws/7Daj1dkJyvmRDs= X-Google-Smtp-Source: ABdhPJwebJSSmkRokXsRb/Kz4zI0E+5YtmvwcKolkCn7W+oEXvDfMbr584jpPc//4xDMXUZKJZljXw== X-Received: by 2002:a05:6a00:1946:b0:44d:8136:a4a4 with SMTP id s6-20020a056a00194600b0044d8136a4a4mr13021402pfk.46.1639944392639; Sun, 19 Dec 2021 12:06:32 -0800 (PST) Received: from gnu-tgl-3.localdomain ([172.58.35.133]) by smtp.gmail.com with ESMTPSA id ng7sm2268417pjb.41.2021.12.19.12.06.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Dec 2021 12:06:32 -0800 (PST) Received: from gnu-tgl-3.. (localhost [IPv6:::1]) by gnu-tgl-3.localdomain (Postfix) with ESMTP id 0320DC061B; Sun, 19 Dec 2021 12:06:30 -0800 (PST) To: gcc-patches@gcc.gnu.org Subject: [PATCH] ix86: Don't match the 'm' constraint on x86_64_general_operand Date: Sun, 19 Dec 2021 12:06:30 -0800 Message-Id: <20211219200630.2325031-1-hjl.tools@gmail.com> X-Mailer: git-send-email 2.33.1 MIME-Version: 1.0 X-Spam-Status: No, score=-3029.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_LOTSOFHASH, KAM_SHORT, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: "H.J. Lu via Gcc-patches" From: "H.J. Lu" Reply-To: "H.J. Lu" Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" x86_64_general_operand is different from general_operand for 64-bit target. To avoid LRA selecting a memory operand which doesn't satisfy x86_64_general_operand for 64-bit target: 1. Add a 'BM' constraint which is similar to the 'm' constraint, but checks x86_64_general_operand for integers > 16 bits. 2. Replace the 'm' constraint on x86_64_general_operand with the 'BM' constraint. gcc/ PR target/103762 * config/i386/constraints.md (BM): New constraint. * config/i386/i386.md: Replace the 'm' constraint on x86_64_general_operand with the 'BM' constraint. * config/i386/predicates.md (ix86_memory_operand): New predicate. gcc/testsuite/ * gcc.target/i386/pr103762-1a.c: New test. * gcc.target/i386/pr103762-1b.c: Likewise. * gcc.target/i386/pr103762-1c.c: Likewise. --- gcc/config/i386/constraints.md | 5 + gcc/config/i386/i386.md | 64 +- gcc/config/i386/predicates.md | 6 + gcc/testsuite/gcc.target/i386/pr103762-1a.c | 647 ++++++++++++++++++++ gcc/testsuite/gcc.target/i386/pr103762-1b.c | 7 + gcc/testsuite/gcc.target/i386/pr103762-1c.c | 7 + 6 files changed, 704 insertions(+), 32 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr103762-1a.c create mode 100644 gcc/testsuite/gcc.target/i386/pr103762-1b.c create mode 100644 gcc/testsuite/gcc.target/i386/pr103762-1c.c diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md index 6b291a02d88..6677285e518 100644 --- a/gcc/config/i386/constraints.md +++ b/gcc/config/i386/constraints.md @@ -168,6 +168,7 @@ ;; z Constant call address operand. ;; C Integer SSE constant with all bits set operand. ;; F Floating-point SSE constant with all bits set operand. +;; M ix86 memory operand. (define_constraint "Bf" "@internal Flags register operand." @@ -232,6 +233,10 @@ (and (match_test "TARGET_SSE") (match_operand 0 "float_vector_all_ones_operand"))) +(define_constraint "BM" + "@internal ix86 memory operand." + (match_operand 0 "ix86_memory_operand")) + ;; Integer constant constraints. (define_constraint "Wb" "Integer constant in the range 0 @dots{} 7, for 8-bit shifts." diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index d25453fe574..4f30819a1d9 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -1385,7 +1385,7 @@ (define_insn "*cmp_1" [(set (reg FLAGS_REG) (compare (match_operand:SWI 0 "nonimmediate_operand" "m,") - (match_operand:SWI 1 "" ",m")))] + (match_operand:SWI 1 "" ",BM")))] "ix86_match_ccmode (insn, CCmode)" "cmp{}\t{%1, %0|%0, %1}" [(set_attr "type" "icmp") @@ -1395,7 +1395,7 @@ [(set (reg FLAGS_REG) (compare (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "m,") - (match_operand:SWI 1 "" ",m")) + (match_operand:SWI 1 "" ",BM")) (const_int 0)))] "ix86_match_ccmode (insn, CCGOCmode)" "cmp{}\t{%1, %0|%0, %1}" @@ -5653,7 +5653,7 @@ [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r") (plus:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r") - (match_operand:SWI48 2 "x86_64_general_operand" "re,m,0,le"))) + (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (PLUS, mode, operands)" { @@ -5709,7 +5709,7 @@ [(set (match_operand:DI 0 "register_operand" "=r,r,r") (zero_extend:DI (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r") - (match_operand:SI 2 "x86_64_general_operand" "rme,0,le")))) + (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" { @@ -5967,7 +5967,7 @@ (compare (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0,0,") - (match_operand:SWI 2 "" ",m,0")) + (match_operand:SWI 2 "" ",BM,0")) (const_int 0))) (set (match_operand:SWI 0 "nonimmediate_operand" "=m,,") (plus:SWI (match_dup 1) (match_dup 2)))] @@ -6012,7 +6012,7 @@ [(set (reg FLAGS_REG) (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r") - (match_operand:SI 2 "x86_64_general_operand" "rme,0")) + (match_operand:SI 2 "x86_64_general_operand" "rBMe,0")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r,r") (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] @@ -6097,7 +6097,7 @@ (define_insn "*addsi_3_zext" [(set (reg FLAGS_REG) (compare - (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0")) + (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0")) (match_operand:SI 1 "nonimmediate_operand" "%0,r"))) (set (match_operand:DI 0 "register_operand" "=r,r") (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] @@ -6801,7 +6801,7 @@ [(set (match_operand:SWI 0 "nonimmediate_operand" "=m,") (minus:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,0") - (match_operand:SWI 2 "" ",m"))) + (match_operand:SWI 2 "" ",BM"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (MINUS, mode, operands)" "sub{}\t{%2, %0|%0, %2}" @@ -6812,7 +6812,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "x86_64_general_operand" "rme")))) + (match_operand:SI 2 "x86_64_general_operand" "rBMe")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" "sub{l}\t{%2, %k0|%k0, %2}" @@ -6844,7 +6844,7 @@ (compare (minus:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,0") - (match_operand:SWI 2 "" ",m")) + (match_operand:SWI 2 "" ",BM")) (const_int 0))) (set (match_operand:SWI 0 "nonimmediate_operand" "=m,") (minus:SWI (match_dup 1) (match_dup 2)))] @@ -6858,7 +6858,7 @@ [(set (reg FLAGS_REG) (compare (minus:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "x86_64_general_operand" "rme")) + (match_operand:SI 2 "x86_64_general_operand" "rBMe")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI @@ -7111,7 +7111,7 @@ (define_insn "*sub_3" [(set (reg FLAGS_REG) (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0") - (match_operand:SWI 2 "" ",m"))) + (match_operand:SWI 2 "" ",BM"))) (set (match_operand:SWI 0 "nonimmediate_operand" "=m,") (minus:SWI (match_dup 1) (match_dup 2)))] "ix86_match_ccmode (insn, CCmode) @@ -7187,7 +7187,7 @@ (define_insn "*subsi_3_zext" [(set (reg FLAGS_REG) (compare (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "x86_64_general_operand" "rme"))) + (match_operand:SI 2 "x86_64_general_operand" "rBMe"))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (minus:SI (match_dup 1) @@ -7207,7 +7207,7 @@ (match_operator:SWI 4 "ix86_carry_flag_operator" [(match_operand 3 "flags_reg_operand") (const_int 0)]) (match_operand:SWI 1 "nonimmediate_operand" "%0,0")) - (match_operand:SWI 2 "" ",m"))) + (match_operand:SWI 2 "" ",BM"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (PLUS, mode, operands)" "adc{}\t{%2, %0|%0, %2}" @@ -7251,7 +7251,7 @@ (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator" [(reg FLAGS_REG) (const_int 0)]) (match_operand:SI 1 "register_operand" "%0")) - (match_operand:SI 2 "x86_64_general_operand" "rme")))) + (match_operand:SI 2 "x86_64_general_operand" "rBMe")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" "adc{l}\t{%2, %k0|%k0, %2}" @@ -7377,7 +7377,7 @@ (match_operand:SWI 1 "nonimmediate_operand" "0,0") (match_operator:SWI 4 "ix86_carry_flag_operator" [(match_operand 3 "flags_reg_operand") (const_int 0)])) - (match_operand:SWI 2 "" ",m"))) + (match_operand:SWI 2 "" ",BM"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (MINUS, mode, operands)" "sbb{}\t{%2, %0|%0, %2}" @@ -7422,7 +7422,7 @@ (match_operand:SI 1 "register_operand" "0") (match_operator:SI 3 "ix86_carry_flag_operator" [(reg FLAGS_REG) (const_int 0)])) - (match_operand:SI 2 "x86_64_general_operand" "rme")))) + (match_operand:SI 2 "x86_64_general_operand" "rBMe")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" "sbb{l}\t{%2, %k0|%k0, %2}" @@ -7498,7 +7498,7 @@ (define_insn "@sub3_carry_ccgz" [(set (reg:CCGZ FLAGS_REG) (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0") - (match_operand:DWIH 2 "x86_64_general_operand" "rme") + (match_operand:DWIH 2 "x86_64_general_operand" "rBMe") (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))] UNSPEC_SBB)) (clobber (match_scratch:DWIH 0 "=r"))] @@ -7585,7 +7585,7 @@ (compare:CCC (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0,0") - (match_operand:SWI 2 "" ",m")) + (match_operand:SWI 2 "" ",BM")) (match_dup 1))) (set (match_operand:SWI 0 "nonimmediate_operand" "=m,") (plus:SWI (match_dup 1) (match_dup 2)))] @@ -7616,7 +7616,7 @@ (compare:CCC (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "x86_64_general_operand" "rme")) + (match_operand:SI 2 "x86_64_general_operand" "rBMe")) (match_dup 1))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] @@ -7643,7 +7643,7 @@ (compare:CCC (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0,0") - (match_operand:SWI 2 "" ",m")) + (match_operand:SWI 2 "" ",BM")) (match_dup 2))) (set (match_operand:SWI 0 "nonimmediate_operand" "=m,") (plus:SWI (match_dup 1) (match_dup 2)))] @@ -7657,7 +7657,7 @@ (compare:CCC (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "x86_64_general_operand" "rme")) + (match_operand:SI 2 "x86_64_general_operand" "rBMe")) (match_dup 2))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] @@ -8001,7 +8001,7 @@ [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r") (mult:SWIM248 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0") - (match_operand:SWIM248 2 "" "K,,mr"))) + (match_operand:SWIM248 2 "" "K,,BMr"))) (clobber (reg:CC FLAGS_REG))] "!(MEM_P (operands[1]) && MEM_P (operands[2]))" "@ @@ -8037,7 +8037,7 @@ [(set (match_operand:DI 0 "register_operand" "=r,r,r") (zero_extend:DI (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") - (match_operand:SI 2 "x86_64_general_operand" "K,e,mr")))) + (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && !(MEM_P (operands[1]) && MEM_P (operands[2]))" @@ -9711,7 +9711,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "x86_64_general_operand" "rme")))) + (match_operand:SI 2 "x86_64_general_operand" "rBMe")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)" "and{l}\t{%2, %k0|%k0, %2}" @@ -9721,7 +9721,7 @@ (define_insn "*and_1" [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,?k") (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k") - (match_operand:SWI24 2 "" "r,m,L,k"))) + (match_operand:SWI24 2 "" "r,BM,L,k"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (AND, mode, operands)" "@ @@ -9903,7 +9903,7 @@ [(set (reg FLAGS_REG) (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "x86_64_general_operand" "rme")) + (match_operand:SI 2 "x86_64_general_operand" "rBMe")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] @@ -9946,7 +9946,7 @@ [(set (reg FLAGS_REG) (compare (and:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0") - (match_operand:SWI124 2 "" ",m")) + (match_operand:SWI124 2 "" ",BM")) (const_int 0))) (set (match_operand:SWI124 0 "nonimmediate_operand" "=m,") (and:SWI124 (match_dup 1) (match_dup 2)))] @@ -10260,7 +10260,7 @@ [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k") (any_or:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k") - (match_operand:SWI248 2 "" "r,m,k"))) + (match_operand:SWI248 2 "" "r,BM,k"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (, mode, operands)" "@ @@ -10328,7 +10328,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "x86_64_general_operand" "rme")))) + (match_operand:SI 2 "x86_64_general_operand" "rBMe")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (, SImode, operands)" "{l}\t{%2, %k0|%k0, %2}" @@ -10431,7 +10431,7 @@ [(set (reg FLAGS_REG) (compare (any_or:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0,0") - (match_operand:SWI 2 "" ",m")) + (match_operand:SWI 2 "" ",BM")) (const_int 0))) (set (match_operand:SWI 0 "nonimmediate_operand" "=m,") (any_or:SWI (match_dup 1) (match_dup 2)))] @@ -10446,7 +10446,7 @@ (define_insn "*si_2_zext" [(set (reg FLAGS_REG) (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "x86_64_general_operand" "rme")) + (match_operand:SI 2 "x86_64_general_operand" "rBMe")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))] diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 770e2f0c0dd..cfc0a50e239 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -1199,6 +1199,12 @@ (and (match_operand 0 "memory_operand") (not (match_test "x86_extended_reg_mentioned_p (op)")))) +;; Return true if OP is a memory operand representable on ix86. +(define_predicate "ix86_memory_operand" + (and (match_operand 0 "memory_operand") + (ior (match_test "mode == QImode || mode == HImode") + (match_operand 0 "x86_64_general_operand")))) + ;; Return true for RTX codes that force SImode address. (define_predicate "SImode_address_operand" (match_code "subreg,zero_extend,and")) diff --git a/gcc/testsuite/gcc.target/i386/pr103762-1a.c b/gcc/testsuite/gcc.target/i386/pr103762-1a.c new file mode 100644 index 00000000000..c9e75bc12d8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr103762-1a.c @@ -0,0 +1,647 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -std=gnu11 -fgnu89-inline" } */ +/* { dg-final { scan-assembler-not ".quad\[\\t \]+tunable_list" { target lp64 } } } */ +/* { dg-final { scan-assembler-not ".long\[\\t \]+tunable_list" { target { ! lp64 } } } } */ + +typedef unsigned long int size_t; +typedef long long int intmax_t; +typedef unsigned long long int uintmax_t; +typedef unsigned long long int uint64_t; +typedef intmax_t tunable_num_t; +typedef union +{ + tunable_num_t numval; + const char *strval; +} tunable_val_t; +enum +{ + HWCAP_X86_SSE2 = 1 << 0, + HWCAP_X86_64 = 1 << 1, + HWCAP_X86_AVX512_1 = 1 << 2 +}; +typedef void (*tunable_callback_t) (tunable_val_t *); +extern void *__minimal_malloc (size_t n) + __attribute__ ((visibility ("hidden"))); +extern int __libc_enable_secure __attribute__ ((section (".data.rel.ro"))); +extern uint64_t _dl_strtoul (const char *, char **) + __attribute__ ((visibility ("hidden"))); +extern void _dl_fatal_printf (const char *fmt, ...) + __attribute__ ((__format__ (__printf__, 1, 2), __noreturn__)); +typedef enum +{ + glibc_rtld_nns, + glibc_elision_skip_lock_after_retries, + glibc_malloc_trim_threshold, + glibc_malloc_perturb, + glibc_cpu_x86_shared_cache_size, + glibc_pthread_rseq, + glibc_mem_tagging, + glibc_elision_tries, + glibc_elision_enable, + glibc_malloc_hugetlb, + glibc_cpu_x86_rep_movsb_threshold, + glibc_malloc_mxfast, + glibc_rtld_dynamic_sort, + glibc_elision_skip_lock_busy, + glibc_malloc_top_pad, + glibc_cpu_x86_rep_stosb_threshold, + glibc_cpu_x86_non_temporal_threshold, + glibc_cpu_x86_shstk, + glibc_pthread_stack_cache_size, + glibc_cpu_hwcap_mask, + glibc_malloc_mmap_max, + glibc_elision_skip_trylock_internal_abort, + glibc_malloc_tcache_unsorted_limit, + glibc_cpu_x86_ibt, + glibc_cpu_hwcaps, + glibc_elision_skip_lock_internal_abort, + glibc_malloc_arena_max, + glibc_malloc_mmap_threshold, + glibc_cpu_x86_data_cache_size, + glibc_malloc_tcache_count, + glibc_malloc_arena_test, + glibc_pthread_mutex_spin_count, + glibc_rtld_optional_static_tls, + glibc_malloc_tcache_max, + glibc_malloc_check, +} tunable_id_t; +typedef enum +{ + TUNABLE_TYPE_INT_32, + TUNABLE_TYPE_UINT_64, + TUNABLE_TYPE_SIZE_T, + TUNABLE_TYPE_STRING +} tunable_type_code_t; +typedef struct +{ + tunable_type_code_t type_code; + tunable_num_t min; + tunable_num_t max; +} tunable_type_t; +typedef enum +{ + TUNABLE_SECLEVEL_SXID_ERASE = 0, + TUNABLE_SECLEVEL_SXID_IGNORE = 1, + TUNABLE_SECLEVEL_NONE = 2, +} tunable_seclevel_t; +struct _tunable +{ + const char name[42]; + tunable_type_t type; + tunable_val_t val; + _Bool initialized; + tunable_seclevel_t security_level; + const char env_alias[23]; +}; +typedef struct _tunable tunable_t; +extern _Bool unsigned_tunable_type (tunable_type_code_t t); + +static tunable_t tunable_list[] __attribute__ ((section (".data.rel.ro"))) = { + { "glibc" + "." + "rtld" + "." + "nns", + { TUNABLE_TYPE_SIZE_T, 1, 16 }, + { .numval = 4 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "elision" + "." + "skip_lock_after_retries", + { TUNABLE_TYPE_INT_32, 0, (2147483647) }, + { .numval = 3 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "malloc" + "." + "trim_threshold", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_IGNORE, + "MALLOC_TRIM_THRESHOLD_" }, + { "glibc" + "." + "malloc" + "." + "perturb", + { TUNABLE_TYPE_INT_32, 0, 0xff }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_IGNORE, + "MALLOC_PERTURB_" }, + { "glibc" + "." + "cpu" + "." + "x86_shared_cache_size", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "pthread" + "." + "rseq", + { TUNABLE_TYPE_INT_32, 0, 1 }, + { .numval = 1 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "mem" + "." + "tagging", + { TUNABLE_TYPE_INT_32, 0, 255 }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_IGNORE, + { 0 } }, + { "glibc" + "." + "elision" + "." + "tries", + { TUNABLE_TYPE_INT_32, 0, (2147483647) }, + { .numval = 3 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "elision" + "." + "enable", + { TUNABLE_TYPE_INT_32, 0, 1 }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "malloc" + "." + "hugetlb", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "cpu" + "." + "x86_rep_movsb_threshold", + { TUNABLE_TYPE_SIZE_T, 1, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "malloc" + "." + "mxfast", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_IGNORE, + { 0 } }, + { "glibc" + "." + "rtld" + "." + "dynamic_sort", + { TUNABLE_TYPE_INT_32, 1, 2 }, + { .numval = 2 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "elision" + "." + "skip_lock_busy", + { TUNABLE_TYPE_INT_32, 0, (2147483647) }, + { .numval = 3 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "malloc" + "." + "top_pad", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_IGNORE, + "MALLOC_TOP_PAD_" }, + { "glibc" + "." + "cpu" + "." + "x86_rep_stosb_threshold", + { TUNABLE_TYPE_SIZE_T, 1, (18446744073709551615UL) }, + { .numval = 2048 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "cpu" + "." + "x86_non_temporal_threshold", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "cpu" + "." + "x86_shstk", + { TUNABLE_TYPE_STRING, 0, 0 }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "pthread" + "." + "stack_cache_size", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + { .numval = 41943040 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "cpu" + "." + "hwcap_mask", + { TUNABLE_TYPE_UINT_64, 0, (18446744073709551615UL) }, + { .numval = (HWCAP_X86_64 | HWCAP_X86_AVX512_1) }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + "LD_HWCAP_MASK" }, + { "glibc" + "." + "malloc" + "." + "mmap_max", + { TUNABLE_TYPE_INT_32, 0, (2147483647) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_IGNORE, + "MALLOC_MMAP_MAX_" }, + { "glibc" + "." + "elision" + "." + "skip_trylock_internal_abort", + { TUNABLE_TYPE_INT_32, 0, (2147483647) }, + { .numval = 3 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "malloc" + "." + "tcache_unsorted_limit", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "cpu" + "." + "x86_ibt", + { TUNABLE_TYPE_STRING, 0, 0 }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "cpu" + "." + "hwcaps", + { TUNABLE_TYPE_STRING, 0, 0 }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "elision" + "." + "skip_lock_internal_abort", + { TUNABLE_TYPE_INT_32, 0, (2147483647) }, + { .numval = 3 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "malloc" + "." + "arena_max", + { TUNABLE_TYPE_SIZE_T, 1, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_IGNORE, + "MALLOC_ARENA_MAX" }, + { "glibc" + "." + "malloc" + "." + "mmap_threshold", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_IGNORE, + "MALLOC_MMAP_THRESHOLD_" }, + { "glibc" + "." + "cpu" + "." + "x86_data_cache_size", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "malloc" + "." + "tcache_count", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "malloc" + "." + "arena_test", + { TUNABLE_TYPE_SIZE_T, 1, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_IGNORE, + "MALLOC_ARENA_TEST" }, + { "glibc" + "." + "pthread" + "." + "mutex_spin_count", + { TUNABLE_TYPE_INT_32, 0, 32767 }, + { .numval = 100 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "rtld" + "." + "optional_static_tls", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + { .numval = 512 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "malloc" + "." + "tcache_max", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "malloc" + "." + "check", + { TUNABLE_TYPE_INT_32, 0, 3 }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + "MALLOC_CHECK_" }, +}; +extern void __tunables_init (char **); +extern void __tunables_print (void); +extern void __tunable_get_val (tunable_id_t, void *, tunable_callback_t); +extern void __tunable_set_val (tunable_id_t, tunable_val_t *, tunable_num_t *, + tunable_num_t *); +static __inline __attribute__ ((__always_inline__)) _Bool +tunable_val_lt (tunable_num_t lhs, tunable_num_t rhs, _Bool unsigned_cmp) +{ + if (unsigned_cmp) + return (uintmax_t)lhs < (uintmax_t)rhs; + else + return lhs < rhs; +} +static __inline __attribute__ ((__always_inline__)) _Bool +tunable_val_gt (tunable_num_t lhs, tunable_num_t rhs, _Bool unsigned_cmp) +{ + if (unsigned_cmp) + return (uintmax_t)lhs > (uintmax_t)rhs; + else + return lhs > rhs; +} +static __inline __attribute__ ((__always_inline__)) _Bool +tunable_is_name (const char *orig, const char *envname) +{ + for (; *orig != '\0' && *envname != '\0'; envname++, orig++) + if (*orig != *envname) + break; + if (*orig == '\0' && *envname == '=') + return 1; + else + return 0; +} +static char * +tunables_strdup (const char *in) +{ + size_t i = 0; + while (in[i++] != '\0') + ; + char *out = __minimal_malloc (i + 1); + if (out == ((void *)0)) + _dl_fatal_printf ("failed to allocate memory to process tunables\n"); + while (i-- > 0) + out[i] = in[i]; + return out; +} +static char ** +get_next_env (char **envp, char **name, size_t *namelen, char **val, + char ***prev_envp) +{ + while (envp != ((void *)0) && *envp != ((void *)0)) + { + char **prev = envp; + char *envline = *envp++; + int len = 0; + while (envline[len] != '\0' && envline[len] != '=') + len++; + if (envline[len] == '\0') + continue; + *name = envline; + *namelen = len; + *val = &envline[len + 1]; + *prev_envp = prev; + return envp; + } + return ((void *)0); +} +static void +do_tunable_update_val (tunable_t *cur, const tunable_val_t *valp, + const tunable_num_t *minp, const tunable_num_t *maxp) +{ + tunable_num_t val, min, max; + if (cur->type.type_code == TUNABLE_TYPE_STRING) + { + cur->val.strval = valp->strval; + cur->initialized = 1; + return; + } + _Bool unsigned_cmp = unsigned_tunable_type (cur->type.type_code); + val = valp->numval; + min = minp != ((void *)0) ? *minp : cur->type.min; + max = maxp != ((void *)0) ? *maxp : cur->type.max; + if (tunable_val_lt (min, cur->type.min, unsigned_cmp)) + min = cur->type.min; + if (tunable_val_gt (max, cur->type.max, unsigned_cmp)) + max = cur->type.max; + if (tunable_val_gt (min, max, unsigned_cmp)) + { + min = cur->type.min; + max = cur->type.max; + } + if (tunable_val_lt (val, min, unsigned_cmp) + || tunable_val_lt (max, val, unsigned_cmp)) + return; + cur->val.numval = val; + cur->type.min = min; + cur->type.max = max; + cur->initialized = 1; +} +static void +tunable_initialize (tunable_t *cur, const char *strval) +{ + tunable_val_t val; + if (cur->type.type_code != TUNABLE_TYPE_STRING) + val.numval = (tunable_num_t)_dl_strtoul (strval, ((void *)0)); + else + val.strval = strval; + do_tunable_update_val (cur, &val, ((void *)0), ((void *)0)); +} +static void +parse_tunables (char *tunestr, char *valstring) +{ + if (tunestr == ((void *)0) || *tunestr == '\0') + return; + char *p = tunestr; + size_t off = 0; + while (1) + { + char *name = p; + size_t len = 0; + while (p[len] != '=' && p[len] != ':' && p[len] != '\0') + len++; + if (p[len] == '\0') + { + if (__libc_enable_secure) + tunestr[off] = '\0'; + return; + } + if (p[len] == ':') + { + p += len + 1; + continue; + } + p += len + 1; + char *value = &valstring[p - tunestr]; + len = 0; + while (p[len] != ':' && p[len] != '\0') + len++; + for (size_t i = 0; i < sizeof (tunable_list) / sizeof (tunable_t); i++) + { + tunable_t *cur = &tunable_list[i]; + if (tunable_is_name (cur->name, name)) + { + if (__libc_enable_secure) + { + if (cur->security_level != TUNABLE_SECLEVEL_SXID_ERASE) + { + if (off > 0) + tunestr[off++] = ':'; + const char *n = cur->name; + while (*n != '\0') + tunestr[off++] = *n++; + tunestr[off++] = '='; + for (size_t j = 0; j < len; j++) + tunestr[off++] = value[j]; + } + if (cur->security_level != TUNABLE_SECLEVEL_NONE) + break; + } + value[len] = '\0'; + tunable_initialize (cur, value); + break; + } + } + if (p[len] != '\0') + p += len + 1; + } +} +void +__tunables_init (char **envp) +{ + char *envname = ((void *)0); + char *envval = ((void *)0); + size_t len = 0; + char **prev_envp = envp; + while ((envp = get_next_env (envp, &envname, &len, &envval, &prev_envp)) + != ((void *)0)) + { + if (tunable_is_name ("GLIBC_TUNABLES", envname)) + { + char *new_env = tunables_strdup (envname); + if (new_env != ((void *)0)) + parse_tunables (new_env + len + 1, envval); + *prev_envp = new_env; + continue; + } + for (int i = 0; i < sizeof (tunable_list) / sizeof (tunable_t); i++) + { + tunable_t *cur = &tunable_list[i]; + const char *name = cur->env_alias; + if (tunable_is_name (name, envname)) + { + tunable_initialize (cur, envval); + break; + } + } + } +} diff --git a/gcc/testsuite/gcc.target/i386/pr103762-1b.c b/gcc/testsuite/gcc.target/i386/pr103762-1b.c new file mode 100644 index 00000000000..391f51cf7f1 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr103762-1b.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target pie } */ +/* { dg-options "-O2 -std=gnu11 -fgnu89-inline -fpie" } */ +/* { dg-final { scan-assembler-not ".quad\[\\t \]+tunable_list" { target lp64 } } } */ +/* { dg-final { scan-assembler-not ".long\[\\t \]+tunable_list" { target { ! lp64 } } } } */ + +#include "pr103762-1a.c" diff --git a/gcc/testsuite/gcc.target/i386/pr103762-1c.c b/gcc/testsuite/gcc.target/i386/pr103762-1c.c new file mode 100644 index 00000000000..4667b06c171 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr103762-1c.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target fpic } */ +/* { dg-options "-O2 -std=gnu11 -fgnu89-inline -fpic" } */ +/* { dg-final { scan-assembler-not ".quad\[\\t \]+tunable_list" { target lp64 } } } */ +/* { dg-final { scan-assembler-not ".long\[\\t \]+tunable_list" { target { ! lp64 } } } } */ + +#include "pr103762-1a.c"