| //===-- WebAssemblyGISel.td - Wasm GlobalISel Patterns -----*- tablegen -*-===// | |
| // | |
| // 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 | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| /// \file | |
| /// This file contains patterns that are relevant to GlobalISel, including | |
| /// GIComplexOperandMatcher definitions for equivalent SelectionDAG | |
| /// ComplexPatterns. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| include "WebAssembly.td" | |
| include "WebAssemblyCombine.td" | |
| defvar ModeAddr32 = DefaultMode; | |
| def ModeAddr64 : HwMode<[HasAddr64]>; | |
| def p0i : ValueTypeByHwMode<[ModeAddr32, ModeAddr64], | |
| [i32, i64]>; | |
| def p0 : PtrValueTypeByHwMode<p0i, 0>; | |
| def : Pat<(p0 (ptradd p0:$lhs, p0i:$rhs)), | |
| (ADD_I32 I32:$lhs, I32:$rhs)>, Requires<[HasAddr32]>; | |
| def : Pat<(p0 (ptradd p0:$lhs, p0i:$rhs)), | |
| (ADD_I64 I64:$lhs, I64:$rhs)>, Requires<[HasAddr64]>; | |
| def : Pat<(frameindex:$fi), | |
| (COPY_I32 (to_tframeindex $fi))>, Requires<[HasAddr32]>; | |
| def : Pat<(frameindex:$fi), | |
| (COPY_I64 (to_tframeindex $fi))>, Requires<[HasAddr64]>; | |
| // G_ICMP between p0 | |
| multiclass ComparisonP0<CondCode cond, string Name> { | |
| def : Pat<(setcc p0:$lhs, p0:$rhs, cond), | |
| (!cast<NI>(Name # "_I32") I32:$lhs, I32:$rhs)>, Requires<[HasAddr32]>; | |
| def : Pat<(setcc p0:$lhs, p0:$rhs, cond), | |
| (!cast<NI>(Name # "_I64") I64:$lhs, I64:$rhs)>, Requires<[HasAddr64]>; | |
| } | |
| defm : ComparisonP0<SETEQ, "EQ">; | |
| defm : ComparisonP0<SETNE, "NE">; | |
| defm : ComparisonP0<SETLT, "LT_S">; | |
| defm : ComparisonP0<SETULT, "LT_U">; | |
| defm : ComparisonP0<SETGT, "GT_S">; | |
| defm : ComparisonP0<SETUGT, "GT_U">; | |
| defm : ComparisonP0<SETLE, "LE_S">; | |
| defm : ComparisonP0<SETULE, "LE_U">; | |
| defm : ComparisonP0<SETGE, "GE_S">; | |
| defm : ComparisonP0<SETUGE, "GE_U">; | |
| // G_SELECT of p0 | |
| def : Pat<(select I32:$cond, p0:$lhs, p0:$rhs), | |
| (SELECT_I32 I32:$lhs, I32:$rhs, I32:$cond)>, Requires<[HasAddr32]>; | |
| def : Pat<(select I32:$cond, p0:$lhs, p0:$rhs), | |
| (SELECT_I64 I64:$lhs, I64:$rhs, I32:$cond)>, Requires<[HasAddr64]>; | |
| // ISD::SELECT requires its operand to conform to getBooleanContents, but | |
| // WebAssembly's select interprets any non-zero value as true, so we can fold | |
| // a setne with 0 into a select. | |
| def : Pat<(select (i32 (setne I32:$cond, 0)), p0:$lhs, p0:$rhs), | |
| (SELECT_I32 I32:$lhs, I32:$rhs, I32:$cond)>, Requires<[HasAddr32]>; | |
| def : Pat<(select (i32 (setne I32:$cond, 0)), p0:$lhs, p0:$rhs), | |
| (SELECT_I64 I64:$lhs, I64:$rhs, I32:$cond)>, Requires<[HasAddr64]>; | |
| // And again, this time with seteq instead of setne and the arms reversed. | |
| def : Pat<(select (i32 (seteq I32:$cond, 0)), p0:$lhs, p0:$rhs), | |
| (SELECT_I32 I32:$rhs, I32:$lhs, I32:$cond)>, Requires<[HasAddr32]>; | |
| def : Pat<(select (i32 (seteq I32:$cond, 0)), p0:$lhs, p0:$rhs), | |
| (SELECT_I64 I64:$rhs, I64:$lhs, I32:$cond)>, Requires<[HasAddr64]>; | |
| //===----------------------------------------------------------------------===// | |
| // Complex pattern equivalents | |
| //===----------------------------------------------------------------------===// | |
| def gi_AddrOps32 : GIComplexOperandMatcher<s32, "selectAddrOperands32">, | |
| GIComplexPatternEquiv<AddrOps32>; | |
| def gi_AddrOps64 : GIComplexOperandMatcher<s64, "selectAddrOperands64">, | |
| GIComplexPatternEquiv<AddrOps64>; |