From patchwork Mon Dec 30 02:39:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guo Jie X-Patchwork-Id: 854234 Delivered-To: patch@linaro.org Received: by 2002:a5d:4888:0:b0:385:e875:8a9e with SMTP id g8csp6249421wrq; Sun, 29 Dec 2024 18:49:52 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXu/JFBiq1MTt4UUsuG3wC884j5v6etaKyQ6nsrI+myIXfajPYHDblfS3MUaNuWkh76iNYBUw==@linaro.org X-Google-Smtp-Source: AGHT+IFybOqC9NAbUiEukQ3iY5BerRMHnWTD1FiPasjqCJjxcr6McldZeW/mA5RXMcQ6YBehdFIi X-Received: by 2002:a05:622a:254:b0:467:5e61:c116 with SMTP id d75a77b69052e-46a4a8b7e6bmr530384001cf.7.1735526991976; Sun, 29 Dec 2024 18:49:51 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1735526991; cv=pass; d=google.com; s=arc-20240605; b=jmtPWZg0hxiDT/Ix1YV080YcMCgiJ8RtUFPFokxjHSoFFFY4CtZ8pxj4UszBz72WvT l3vVViuh6Lrjjr+6uwr1mufDb0j4BFaXcJNvJYFOVy2jZOUA/7LgG19XVTv66NASXC5G uhHeRP/EcGOsW1Rjbpe1jlKmbhTOsRaaAnZsvBO+wiXbykh+TVGdLTKnfm0/WIcRW5n2 MC24Z5gVnHIKVqZAADeqpJmxn7GVPMyia/D3ZBJFCXf5SuIMi1wScw2AhPYE8Egu6RyN p+oKKsHbBwKJG9JLSnQVozAOr3Fai4dejMpVrFua8KKWHclG356+EhsxNe18zKSaGzA4 Pv+g== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:message-id:date:subject:cc:to:from:dkim-filter :arc-filter:dmarc-filter:delivered-to:dkim-filter; bh=4pqyKnYtuJNM/yWmt+5XuDWFqwzbENtsuQB306opN/M=; fh=FCC/Zx3UOwReG8Kz3H/ln+uGOf+6klnWwvVPHAnfABw=; b=IpOb9YJFhkzGP9p6XWesoRcyLUonncOr/Av1ieda3OEKOwZfTkk9VGU8utOBSJjXLU C7C4QtJU8UJWzk9zR8eZgh1vFSxzN0hSpCX2AaVwfLjqniEGirXpDuyVunZ0ublErKSw xuHTfKpbx7TeNQ+6LlcQWQ/Fqqf4vv2suWRr5jY4OY2oDHUWlk4F3kBA5Jizws+KnxUz u2CLLmZTqkpxhCBw4UPLTVr8ELVE2ewt04lnsayxEjZSHYEhRvYZe4n5x/ENcm7YYWqg zd4roMpexJQLqliTp1xWyP+PgOWb69PZN9+VlvfRxpBpVUBhZr4RKnqICWIinNrX3wMy ONNg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces~patch=linaro.org@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces~patch=linaro.org@gcc.gnu.org" Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id d75a77b69052e-46a3e67c6ccsi281576701cf.86.2024.12.29.18.49.51 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Dec 2024 18:49:51 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces~patch=linaro.org@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; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces~patch=linaro.org@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces~patch=linaro.org@gcc.gnu.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5F1723858C53 for ; Mon, 30 Dec 2024 02:49:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5F1723858C53 X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id 4E5543858D34 for ; Mon, 30 Dec 2024 02:38:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4E5543858D34 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=loongson.cn ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 4E5543858D34 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1735526340; cv=none; b=PpvbNmiFXVrv5zHgi40J1fVnNhaJzVLwnoru1kIn1iUZ3NUuL/uTUALmQlNlqc4HVss7Expnqvku0NqzGqcIZNQQcbQdvw8zgAjclP/lezA1Z3lorQb8cYP5QxpHOv4C3M4fw5keH48a8IZE1PdDLBSnyVa0qZG42TYzmDHU9YY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1735526340; c=relaxed/simple; bh=gefPV6+klmE9R0vvGkeuC4Vv5vZDeBwYB6ifNVh2lHY=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=Xci6DtJSOen8VG02q8m1CbvNLgRBp/nV03HE5iS95qrqInLhaBANwIWtN+gNWV36arDJueAMpZ6Udb94COBDAd4KJV0MM5dbgcYUtMzV5sBdI02ReFAJvkpwon0lkqAOEryp9rWSu2onfjFnQe6/aTpTKxbAWx+fmjxq0HKOgFA= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4E5543858D34 Received: from loongson.cn (unknown [10.20.4.191]) by gateway (Coremail) with SMTP id _____8CxSOHBB3JnmqhbAA--.48847S3; Mon, 30 Dec 2024 10:38:57 +0800 (CST) Received: from loongson-pc.loongson.cn (unknown [10.20.4.191]) by front1 (Coremail) with SMTP id qMiowMBxReS9B3JnrVYNAA--.2408S4; Mon, 30 Dec 2024 10:38:56 +0800 (CST) From: Guo Jie To: gcc-patches@gcc.gnu.org Cc: xuchenghua@loongson.cn, chenglulu@loongson.cn, i@xen0n.name, xry111@xry111.site, Guo Jie Subject: [PATCH] LoongArch: Optimize for conditional move operations Date: Mon, 30 Dec 2024 10:39:13 +0800 Message-Id: <20241230023913.10260-1-guojie@loongson.cn> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 X-CM-TRANSID: qMiowMBxReS9B3JnrVYNAA--.2408S4 X-CM-SenderInfo: xjxryx3h6o00pqjv00gofq/ X-Coremail-Antispam: 1Uk129KBj93XoW3Wry7Cr4UKryfXw1kZF4fWFX_yoW3JF45p3 y3Cr1rtF48XFZ3Ww1ktay0qF1akrs3Gw42v3sIyr40yw43Jr9Yqa48KFyavFy5Xa12qrW7 ZF4FvF1j9Fs8Z3gCm3ZEXasCq-sJn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUkYb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Xr0_Ar1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr0_Cr1l84ACjcxK6I8E87Iv67AKxVWxJVW8Jr1l84ACjcxK6I8E87Iv6xkF7I0E14v2 6r4j6r4UJwAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2zVCFFI0UMc 02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWUtVWrXwAv7VC2z280aVAF wI0_Gr0_Cr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JMxAIw28IcxkI7V AKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCj r7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42IY6x IIjxv20xvE14v26r4j6ryUMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI42IY6xAI w20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Gr0_Cr1lIxAIcVC2z280aVCY1x 0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa7IU84xRDUUUUU== X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patch=linaro.org@gcc.gnu.org The optimization example is as follows. From: if (condition) dest += 1 << 16; To: dest += (condition ? 1 : 0) << 16; It does not use maskeqz and masknez, thus reducing the number of instructions. gcc/ChangeLog: * config/loongarch/loongarch.cc (loongarch_expand_conditional_move): Add some optimization implementations based on noce_try_cmove_arith. gcc/testsuite/ChangeLog: * gcc.target/loongarch/conditional-move-opt-1.c: New test. * gcc.target/loongarch/conditional-move-opt-2.c: New test. --- gcc/config/loongarch/loongarch.cc | 103 +++++++++++++++++- .../loongarch/conditional-move-opt-1.c | 58 ++++++++++ .../loongarch/conditional-move-opt-2.c | 42 +++++++ 3 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/loongarch/conditional-move-opt-1.c create mode 100644 gcc/testsuite/gcc.target/loongarch/conditional-move-opt-2.c diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index 2d4290bc2d1..32fd1697813 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -5294,6 +5294,81 @@ loongarch_expand_conditional_move (rtx *operands) loongarch_emit_float_compare (&code, &op0, &op1); else { + /* Optimize to reduce the number of instructions for ternary operations. + Mainly implemented based on noce_try_cmove_arith. + For dest = (condition) ? value_if_true : value_if_false; + the optimization requires: + a. value_if_false = var; + b. value_if_true = var OP C (a positive integer power of 2). + + Situations similar to the following: + if (condition) + dest += 1 << imm; + to: + dest += (condition ? 1 : 0) << imm; */ + + rtx_insn *insn; + HOST_WIDE_INT val = 0; /* The value of rtx C. */ + /* INSN with operands[2] as the output. */ + rtx_insn *value_if_true_insn = NULL; + /* INSN with operands[3] as the output. */ + rtx_insn *value_if_false_insn = NULL; + rtx value_if_true_insn_src = NULL_RTX; + /* Common operand var in value_if_true and value_if_false. */ + rtx comm_var = NULL_RTX; + bool can_be_optimized = false; + + /* Search value_if_true_insn and value_if_false_insn. */ + struct sequence_stack *seq = get_current_sequence ()->next; + for (insn = seq->last; insn; insn = PREV_INSN (insn)) + { + if (single_set (insn)) + { + rtx set_dest = SET_DEST (single_set (insn)); + if (rtx_equal_p (set_dest, operands[2])) + value_if_true_insn = insn; + else if (rtx_equal_p (set_dest, operands[3])) + value_if_false_insn = insn; + if (value_if_true_insn && value_if_false_insn) + break; + } + } + + /* Check if the optimization conditions are met. */ + if (value_if_true_insn + && value_if_false_insn + /* Make sure that value_if_false and var are the same. */ + && BINARY_P (value_if_true_insn_src + = SET_SRC (single_set (value_if_true_insn))) + /* Make sure that both value_if_true and value_if_false + has the same var. */ + && rtx_equal_p (XEXP (value_if_true_insn_src, 0), + SET_SRC (single_set (value_if_false_insn)))) + { + comm_var = SET_SRC (single_set (value_if_false_insn)); + rtx src = XEXP (value_if_true_insn_src, 1); + rtx imm = NULL_RTX; + if (CONST_INT_P (src)) + imm = src; + else + for (insn = seq->last; insn; insn = PREV_INSN (insn)) + { + rtx set = single_set (insn); + if (set && rtx_equal_p (SET_DEST (set), src)) + { + imm = SET_SRC (set); + break; + } + } + if (imm && CONST_INT_P (imm)) + { + val = INTVAL (imm); + /* Make sure that imm is a positive integer power of 2. */ + if (val > 0 && !(val & (val - 1))) + can_be_optimized = true; + } + } + if (GET_MODE_SIZE (GET_MODE (op0)) < UNITS_PER_WORD) { promote_op[0] = (REG_P (op0) && REG_P (operands[2]) && @@ -5314,22 +5389,48 @@ loongarch_expand_conditional_move (rtx *operands) op0_extend = op0; op1_extend = force_reg (word_mode, op1); + rtx target = gen_reg_rtx (GET_MODE (op0)); + if (code == EQ || code == NE) { op0 = loongarch_zero_if_equal (op0, op1); op1 = const0_rtx; + /* For EQ, set target to 1 if op0 and op1 are the same, + otherwise set to 0. + For NE, set target to 0 if op0 and op1 are the same, + otherwise set to 1. */ + if (can_be_optimized) + loongarch_emit_binary (code, target, op0, const0_rtx); } else { /* The comparison needs a separate scc instruction. Store the result of the scc in *OP0 and compare it against zero. */ bool invert = false; - rtx target = gen_reg_rtx (GET_MODE (op0)); loongarch_emit_int_order_test (code, &invert, target, op0, op1); + if (can_be_optimized && invert) + loongarch_emit_binary (EQ, target, target, const0_rtx); code = invert ? EQ : NE; op0 = target; op1 = const0_rtx; } + + if (can_be_optimized) + { + /* Perform (condition ? 1 : 0) << log2 (C). */ + loongarch_emit_binary (ASHIFT, target, target, + GEN_INT (exact_log2 (val))); + /* Shift-related insn patterns only support SImode operands[2]. */ + enum rtx_code opcode = GET_CODE (value_if_true_insn_src); + if (opcode == ASHIFT || opcode == ASHIFTRT || opcode == LSHIFTRT + || opcode == ROTATE || opcode == ROTATERT) + target = gen_lowpart (SImode, target); + /* Perform target = target OP ((condition ? 1 : 0) << log2 (C)). */ + loongarch_emit_binary (opcode, operands[0], + force_reg (GET_MODE (operands[3]), comm_var), + target); + return; + } } rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); diff --git a/gcc/testsuite/gcc.target/loongarch/conditional-move-opt-1.c b/gcc/testsuite/gcc.target/loongarch/conditional-move-opt-1.c new file mode 100644 index 00000000000..ed13471aa90 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/conditional-move-opt-1.c @@ -0,0 +1,58 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-not "maskeqz" } } */ +/* { dg-final { scan-assembler-not "masknez" } } */ + +extern long lm, ln, lr; + +void +test_ne () +{ + if (lm != ln) + lr += (1 << 16); + lr += lm; +} + +void +test_eq () +{ + if (lm == ln) + lr = lm + (1 << 16); + else + lr = lm; + lr += lm; +} + +void +test_lt () +{ + if (lm < ln) + lr *= (1 << 16); + lr += lm; +} + +void +test_le () +{ + if (lm <= ln) + lr = lm * ((long)1 << 32); + else + lr = lm; + lr += lm; +} + +void +test_nez () +{ + if (lm != 0) + lr <<= (1 << 4); + lr += lm; +} + +void +test_eqz () +{ + if (lm == 0) + lr >>= (1 << 2); + lr += lm; +} diff --git a/gcc/testsuite/gcc.target/loongarch/conditional-move-opt-2.c b/gcc/testsuite/gcc.target/loongarch/conditional-move-opt-2.c new file mode 100644 index 00000000000..ac72d4d933a --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/conditional-move-opt-2.c @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 --param max-rtl-if-conversion-insns=1" } */ +/* { dg-final { scan-assembler-not "maskeqz" } } */ +/* { dg-final { scan-assembler-not "masknez" } } */ + +/* The relevant optimization is currently only based on noce_try_cmove_arith, + so it bypasses noce_convert_multiple_sets by + --param max-rtl-if-conversion-insns=1 to execute noce_try_cmove_arith. */ + +extern long lm, ln, lr; + +void +test_ge () +{ + if (lm >= ln) + lr += ((long)1 << 32); + lr += lm; +} + +void +test_ltz () +{ + if (lm < 0) + lr |= (1 << 16); + lr += lm; +} + +void +test_lez () +{ + if (lm <= 0) + lr &= (1 << 16); + lr += lm; +} + +void +test_gez () +{ + if (lm >= 0) + lr ^= (1 << 16); + lr += lm; +}