mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
3fcc23c823
This adds a generic opcode which communicates that a type has already been zero-extended from a narrower type. This is intended to be similar to AssertZext in SelectionDAG. For example, ``` %x_was_extended:_(s64) = G_ASSERT_ZEXT %x, 16 ``` Signifies that the top 48 bits of %x are known to be 0. This is useful in cases like this: ``` define i1 @zeroext_param(i8 zeroext %x) { %cmp = icmp ult i8 %x, -20 ret i1 %cmp } ``` In AArch64, `%x` must use a 32-bit register, which is then truncated to a 8-bit value. If we know that `%x` is already zero-ed out in the relevant high bits, we can avoid the truncate. Currently, in GISel, this looks like this: ``` _zeroext_param: and w8, w0, #0xff ; We don't actually need this! cmp w8, #236 cset w0, lo ret ``` While SDAG does not produce the truncation, since it knows that it's unnecessary: ``` _zeroext_param: cmp w0, #236 cset w0, lo ret ``` This patch - Adds G_ASSERT_ZEXT - Adds MIRBuilder support for it - Adds MachineVerifier support for it - Documents it It also puts G_ASSERT_ZEXT into its own class of "hint instruction." (There should be a G_ASSERT_SEXT in the future, maybe a G_ASSERT_ALIGN as well.) This allows us to skip over hints in the legalizer etc. These can then later be selected like COPY instructions or removed. Differential Revision: https://reviews.llvm.org/D95564
50 lines
1.7 KiB
C++
50 lines
1.7 KiB
C++
//===-- llvm/CodeGen/TargetOpcodes.h - Target Indep Opcodes -----*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines the target independent instruction opcodes.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_CODEGEN_TARGETOPCODES_H
|
|
#define LLVM_CODEGEN_TARGETOPCODES_H
|
|
|
|
namespace llvm {
|
|
|
|
/// Invariant opcodes: All instruction sets have these as their low opcodes.
|
|
///
|
|
namespace TargetOpcode {
|
|
enum {
|
|
#define HANDLE_TARGET_OPCODE(OPC) OPC,
|
|
#define HANDLE_TARGET_OPCODE_MARKER(IDENT, OPC) IDENT = OPC,
|
|
#include "llvm/Support/TargetOpcodes.def"
|
|
};
|
|
} // end namespace TargetOpcode
|
|
|
|
/// Check whether the given Opcode is a generic opcode that is not supposed
|
|
/// to appear after ISel.
|
|
inline bool isPreISelGenericOpcode(unsigned Opcode) {
|
|
return Opcode >= TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START &&
|
|
Opcode <= TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
|
|
}
|
|
|
|
/// Check whether the given Opcode is a target-specific opcode.
|
|
inline bool isTargetSpecificOpcode(unsigned Opcode) {
|
|
return Opcode > TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
|
|
}
|
|
|
|
/// \returns true if \p Opcode is an optimization hint opcode which is not
|
|
/// supposed to appear after ISel.
|
|
inline bool isPreISelGenericOptimizationHint(unsigned Opcode) {
|
|
return Opcode >= TargetOpcode::PRE_ISEL_GENERIC_OPTIMIZATION_HINT_START &&
|
|
Opcode <= TargetOpcode::PRE_ISEL_GENERIC_OPTIMIZATION_HINT_END;
|
|
}
|
|
|
|
} // end namespace llvm
|
|
|
|
#endif
|