From patchwork Sun Nov 19 05:36:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Maciej W. Rozycki" X-Patchwork-Id: 80251 X-Patchwork-Delegate: jlaw@ventanamicro.com 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 D52E1385801D for ; Sun, 19 Nov 2023 05:37:16 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com [IPv6:2a00:1450:4864:20::535]) by sourceware.org (Postfix) with ESMTPS id 75EC9385C32C for ; Sun, 19 Nov 2023 05:36:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 75EC9385C32C Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=embecosm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 75EC9385C32C Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::535 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700372220; cv=none; b=LB2bWJDGFuoTc0msVjNYsDsEhDB0ntVr5TbA9XZ1vJ3gQkZpnQeC6C51LHW+DtPkvCIrKEgMR0BsLqIfJT9CQhw8lzkRq3Fwi2sPVe7mEgJZqzcWucBv08XSfgRVTl+andOReS4uS3g2hCKEKvawlg51iTiBixVyLAEJcpwZdGo= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700372220; c=relaxed/simple; bh=va/+Rn6km0lOS9NNk7Cw0R5T5npDbZF4DtaMAQ+T8H8=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=bNGIoWN+XHVkF7W8jxD3e7RAf5sm5+57MeNvUdR96Z7MJFnSUWT2fwzDSTAqCXcpdmR3UxsT/2xk537sbokrmRiEEW3QxhMU2j3Ghe5N4uT4IsUDAoOLAGwdwaNG3KCKIgWT/fJLU0olszTOZC5eCLymrXcmR9wGhHNEIGSQOxw= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-ed1-x535.google.com with SMTP id 4fb4d7f45d1cf-54394328f65so4552215a12.3 for ; Sat, 18 Nov 2023 21:36:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; t=1700372216; x=1700977016; darn=gcc.gnu.org; h=mime-version:user-agent:references:message-id:in-reply-to:subject :cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=iP43tpg2qXJYbl4dLBzTpiAEAwJehghqWOZ+kyNUyI8=; b=ShcdiMNL9pDLFa8EaCZ2KEqzh9do/RY7PzwWfVGe5kqWYc+xZh2IahDqprTwkGHDna VehexeDdx94tyysIz9BFhM3np8e4V8dDm6Gtf/b8r/q7YNZfLd+i0K6bNLv1aI68yrVQ nzuNcaNMcMTq9B7tg2/dJRxEPPyrFvSPLDhOQapuqJZVmLh+SJqsyhKbWnv3xqPlpoBe MHy+vnm4whP7txmmy8O7Jdywxo7JN66/pM7Pntq36FxQ9mSqYa/rLYijyyIvYOXuOeSF g+cJq2bhvR/r30ZrXPpuqGM1IQC1vJ8IExEy8nV8l5w/nBVwd9Pd5Uh5WKvI16Qqxl58 tKCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700372216; x=1700977016; h=mime-version:user-agent:references:message-id:in-reply-to:subject :cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=iP43tpg2qXJYbl4dLBzTpiAEAwJehghqWOZ+kyNUyI8=; b=wq5fMaff+9YhKlJgyKftXUhRLYl4lKNWoccAapBZ05/yAoD7HZr6v4W9aEXtDGiTFQ ni7hMxPOiPKtg9tlXHUV7h7QUivPXyCezDECdNUeso+DflbyspGQ9eyhauGLm9OoAS7Y ML+137Hbi9Ynh14qccjZhw18asb5H5i7VhJFMuDirLnSPRzVQrduXHjcru7zWrKWsJfs 6+LnsZzG8Xwhrh91GLA0dwNeFrF3MG+OnSmFyYKnzglH5UbVmBZu46u2tRFlttfSvUnK DAm17Mp3P/S2MpLlNL8jKOK5r5ZtqdkmeIErzW7LwArkdw0CGe3nfseUEHUfDiI55GGN hHvw== X-Gm-Message-State: AOJu0YyojtkvPJ/1A18+aiOdSUCDFLbE6Pk6YPmleXT4tdZyWph26H91 6bxUX44Iqg5mZWTma8mSHWFxlZi/DMJ6NxZwiforrw== X-Google-Smtp-Source: AGHT+IHWZQdXU0nz8fDS3f0CenKgKTWEOPqWiLGw2ahT7BsjxI3n5MiXwrYd+tT2YiclTc+eedp33A== X-Received: by 2002:a05:6402:4408:b0:543:cc90:cb8b with SMTP id y8-20020a056402440800b00543cc90cb8bmr3565308eda.2.1700372216038; Sat, 18 Nov 2023 21:36:56 -0800 (PST) Received: from [192.168.219.3] ([78.8.192.131]) by smtp.gmail.com with ESMTPSA id h11-20020a50ed8b000000b00548a3a22d66sm262522edr.41.2023.11.18.21.36.54 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 18 Nov 2023 21:36:55 -0800 (PST) Date: Sun, 19 Nov 2023 05:36:52 +0000 (GMT) From: "Maciej W. Rozycki" To: gcc-patches@gcc.gnu.org cc: Andrew Waterman , Jim Wilson , Kito Cheng , Palmer Dabbelt Subject: [PATCH 09/44] RISC-V: Rework branch costing model for if-conversion In-Reply-To: Message-ID: References: User-Agent: Alpine 2.20 (DEB 67 2015-01-07) MIME-Version: 1.0 X-Spam-Status: No, score=0.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, KAM_ASCII_DIVIDERS, KAM_SHORT, LIKELY_SPAM_BODY, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE, URIBL_BLACK autolearn=no 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.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org The generic branch costing model for if-conversion assumes a fixed cost of COSTS_N_INSNS (2) for a conditional branch, and that one half of that cost comes from a preceding condition-set instruction, such as with MODE_CC targets, and then the other half of that cost is for the actual branch instruction. This is hardcoded for `if_info.original_cost' in `noce_find_if_block' and regardless of the cost set for branches via BRANCH_COST. Then `default_max_noce_ifcvt_seq_cost' instructs if-conversion to prefer a branchless sequence as costly as high as triple the BRANCH_COST value set. This is apparently to make up for the inability to accurately guess the branch penalty. Consequently for the BRANCH_COST of 3 we commonly set for tuning, if-conversion will consider branchless sequences costing 3 * 3 - 2 = 7 instruction units more than a corresponding branch sequence. For the BRANCH_COST of 4 such as with `sifive-7-series' tuning this is even worse, at 3 * 4 - 2 = 10. Effectively it means a branchless sequence will always be chosen if available, even a very inefficient one. Rework the branch costing model to better match our architecture, observing in particular that we have no preparatory instructions for branches so that the cost of a branch is naked BRANCH_COST plus any extra overhead the processing of a branch's source RTX might incur. Provide TARGET_INSN_COST and TARGET_MAX_NOCE_IFCVT_SEQ_COST handlers than that return suitable cost based on BRANCH_COST. The latter hook usually returns a value that is lower than the cost of the corresponding branched sequence. This is because we don't really want to produce a branchless sequence that is more expensive than the original branched sequence. If this turns out too conservative for some corner case, then this choice might be revisited. Then we don't want to fiddle with `noce_find_if_block' without a lot of cross-target verification, so add TARGET_NOCE_CONVERSION_PROFITABLE_P defined such that it subtracts the fixed COSTS_N_INSNS (2) cost from the cost of the original branched sequence supplied and instead adds actual branch cost calculated from the conditional branch instruction used. It is then further tweaked according to simple analysis of the replacement branchless sequence produced so as to cancel the cost of an extraneous zero extend operation produced by `noce_try_store_flag_mask' as observed with gcc/testsuite/gcc.target/riscv/pr105314.c. Tweak the testsuite accordingly and set `-mbranch-cost=' explicitly for the relevant cases so that the expected if-conversion transformation is made regardless of the default BRANCH_COST value of tuning in effect. Some of these settings will be lowered later on as deficiencies in branchless sequence generation have been fixed that lower their cost calculated by if-conversion. gcc/ * config/riscv/riscv.cc (riscv_insn_cost): New function. (riscv_max_noce_ifcvt_seq_cost): Likewise. (riscv_noce_conversion_profitable_p): Likewise. (TARGET_INSN_COST): New macro. (TARGET_MAX_NOCE_IFCVT_SEQ_COST): New macro. (TARGET_NOCE_CONVERSION_PROFITABLE_P: New macro. gcc/testsuite/ * gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c: Explicitly set the branch cost. * gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c: Likewise. * gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c: Likewise. * gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c: Likewise. * gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c: Likewise. * gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c: Likewise. --- FWIW I don't understand why the test cases absolutely HAD to have such overlong names guaranteed to exceed our 80 column limit in any context. It's such a pain to handle. --- gcc/config/riscv/riscv.cc | 120 ++++++++++ gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c | 4 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c | 4 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c | 4 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c | 4 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c | 4 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c | 4 7 files changed, 132 insertions(+), 12 deletions(-) gcc-riscv-branch-cost.diff Index: gcc/gcc/config/riscv/riscv.cc =================================================================== --- gcc.orig/gcc/config/riscv/riscv.cc +++ gcc/gcc/config/riscv/riscv.cc @@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. #include "calls.h" #include "function.h" #include "explow.h" +#include "ifcvt.h" #include "memmodel.h" #include "emit-rtl.h" #include "reload.h" @@ -3295,6 +3296,118 @@ riscv_address_cost (rtx addr, machine_mo return riscv_address_insns (addr, mode, false); } +/* Implement TARGET_INSN_COST. We factor in the branch cost in the cost + calculation for conditional branches: one unit is considered the cost + of microarchitecture-dependent actual branch execution and therefore + multiplied by BRANCH_COST and any remaining units are considered fixed + branch overhead. */ + +static int +riscv_insn_cost (rtx_insn *insn, bool speed) +{ + rtx x = PATTERN (insn); + int cost = pattern_cost (x, speed); + + if (JUMP_P (insn) + && GET_CODE (x) == SET + && GET_CODE (SET_DEST (x)) == PC + && GET_CODE (SET_SRC (x)) == IF_THEN_ELSE) + cost += COSTS_N_INSNS (BRANCH_COST (speed, false) - 1); + return cost; +} + +/* Implement TARGET_MAX_NOCE_IFCVT_SEQ_COST. Like the default implementation, + but we consider cost units of branch instructions equal to cost units of + other instructions. */ + +static unsigned int +riscv_max_noce_ifcvt_seq_cost (edge e) +{ + bool predictable_p = predictable_edge_p (e); + + if (predictable_p) + { + if (OPTION_SET_P (param_max_rtl_if_conversion_predictable_cost)) + return param_max_rtl_if_conversion_predictable_cost; + } + else + { + if (OPTION_SET_P (param_max_rtl_if_conversion_unpredictable_cost)) + return param_max_rtl_if_conversion_unpredictable_cost; + } + + return COSTS_N_INSNS (BRANCH_COST (true, predictable_p)); +} + +/* Implement TARGET_NOCE_CONVERSION_PROFITABLE_P. We replace the cost of a + conditional branch assumed by `noce_find_if_block' at `COSTS_N_INSNS (2)' + by our actual conditional branch cost, observing that our branches test + conditions directly, so there is no preparatory extra condition-set + instruction. */ + +static bool +riscv_noce_conversion_profitable_p (rtx_insn *seq, + struct noce_if_info *if_info) +{ + struct noce_if_info riscv_if_info = *if_info; + + riscv_if_info.original_cost -= COSTS_N_INSNS (2); + riscv_if_info.original_cost += insn_cost (if_info->jump, if_info->speed_p); + + /* Hack alert! When `noce_try_store_flag_mask' uses `cstore4' + to emit a conditional set operation on DImode output it comes up + with a sequence such as: + + (insn 26 0 27 (set (reg:SI 140) + (eq:SI (reg/v:DI 137 [ c ]) + (const_int 0 [0]))) 302 {*seq_zero_disi} + (nil)) + (insn 27 26 28 (set (reg:DI 139) + (zero_extend:DI (reg:SI 140))) 116 {*zero_extendsidi2_internal} + (nil)) + + because our `cstore4' pattern expands to an insn that gives + a SImode output. The output of conditional set is 0 or 1 boolean, + so it is valid for input in any scalar integer mode and therefore + combine later folds the zero extend operation into an equivalent + conditional set operation that produces a DImode output, however + this redundant zero extend operation counts towards the cost of + the replacement sequence. Compensate for that by incrementing the + cost of the original sequence as well as the maximum sequence cost + accordingly. */ + rtx last_dest = NULL_RTX; + for (rtx_insn *insn = seq; insn; insn = NEXT_INSN (insn)) + { + if (!NONDEBUG_INSN_P (insn)) + continue; + + rtx x = PATTERN (insn); + if (NONJUMP_INSN_P (insn) + && GET_CODE (x) == SET) + { + rtx src = SET_SRC (x); + if (last_dest != NULL_RTX + && GET_CODE (src) == ZERO_EXTEND + && REG_P (XEXP (src, 0)) + && REGNO (XEXP (src, 0)) == REGNO (last_dest)) + { + riscv_if_info.original_cost += COSTS_N_INSNS (1); + riscv_if_info.max_seq_cost += COSTS_N_INSNS (1); + } + last_dest = NULL_RTX; + rtx dest = SET_DEST (x); + if (COMPARISON_P (src) + && REG_P (dest) + && GET_MODE (dest) == SImode) + last_dest = dest; + } + else + last_dest = NULL_RTX; + } + + return default_noce_conversion_profitable_p (seq, &riscv_if_info); +} + /* Return one word of double-word value OP. HIGH_P is true to select the high part or false to select the low part. */ @@ -9823,6 +9936,13 @@ riscv_preferred_else_value (unsigned ifn #define TARGET_RTX_COSTS riscv_rtx_costs #undef TARGET_ADDRESS_COST #define TARGET_ADDRESS_COST riscv_address_cost +#undef TARGET_INSN_COST +#define TARGET_INSN_COST riscv_insn_cost + +#undef TARGET_MAX_NOCE_IFCVT_SEQ_COST +#define TARGET_MAX_NOCE_IFCVT_SEQ_COST riscv_max_noce_ifcvt_seq_cost +#undef TARGET_NOCE_CONVERSION_PROFITABLE_P +#define TARGET_NOCE_CONVERSION_PROFITABLE_P riscv_noce_conversion_profitable_p #undef TARGET_ASM_FILE_START #define TARGET_ASM_FILE_START riscv_file_start Index: gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c =================================================================== --- gcc.orig/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c +++ gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ -/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=4" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=4" { target { rv32 } } } */ /* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */ long primitiveSemantics_compare_imm_return_imm_imm_00(long a, long b) { Index: gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c =================================================================== --- gcc.orig/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c +++ gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ -/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=4" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=4" { target { rv32 } } } */ /* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */ long primitiveSemantics_compare_imm_return_imm_reg_00(long a, long b) { Index: gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c =================================================================== --- gcc.orig/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c +++ gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ -/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=5" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=5" { target { rv32 } } } */ /* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */ long primitiveSemantics_compare_imm_return_reg_reg_00(long a, long b, long c) { Index: gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c =================================================================== --- gcc.orig/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c +++ gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ -/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=4" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=4" { target { rv32 } } } */ /* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */ long primitiveSemantics_compare_reg_return_imm_imm_00(long a, long b, long c) { Index: gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c =================================================================== --- gcc.orig/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c +++ gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ -/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=4" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=4" { target { rv32 } } } */ /* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */ long primitiveSemantics_compare_reg_return_imm_reg_00(long a, long b, long c) { Index: gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c =================================================================== --- gcc.orig/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c +++ gcc/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */ -/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=5" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=5" { target { rv32 } } } */ /* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */ long primitiveSemantics_compare_reg_return_reg_reg_00(long a, long b, long c,