1//===-- RISCVGIsel.td - RISC-V GlobalISel Patterns ---------*- tablegen -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9/// \file 10/// This file contains patterns that are relevant to GlobalISel, including 11/// GIComplexOperandMatcher definitions for equivalent SelectionDAG 12/// ComplexPatterns. 13// 14//===----------------------------------------------------------------------===// 15 16include "RISCV.td" 17include "RISCVCombine.td" 18 19def simm12Plus1 : ImmLeaf<XLenVT, [{ 20 return (isInt<12>(Imm) && Imm != -2048) || Imm == 2048;}]>; 21def simm12Plus1i32 : ImmLeaf<i32, [{ 22 return (isInt<12>(Imm) && Imm != -2048) || Imm == 2048;}]>; 23 24// FIXME: This doesn't check that the G_CONSTANT we're deriving the immediate 25// from is only used once 26def simm12Minus1Nonzero : ImmLeaf<XLenVT, [{ 27 return (Imm >= -2049 && Imm < 0) || (Imm > 0 && Imm <= 2046);}]>; 28 29def simm12Minus1NonzeroNonNeg1 : ImmLeaf<XLenVT, [{ 30 return (Imm >= -2049 && Imm < -1) || (Imm > 0 && Imm <= 2046);}]>; 31 32// Return an immediate value plus 1. 33def ImmPlus1 : SDNodeXForm<imm, [{ 34 return CurDAG->getTargetConstant(N->getSExtValue() + 1, SDLoc(N), 35 N->getValuePtrVTpe(0));}]>; 36def GIImmPlus1 : 37 GICustomOperandRenderer<"renderImmPlus1">, 38 GISDNodeXFormEquiv<ImmPlus1>; 39 40// Ptr type used in patterns with GlobalISelEmitter 41def PtrVT : PtrValueTypeByHwMode<XLenVT, 0>; 42 43// Define pattern expansions for pointer ult/slt conditional codes 44def : Pat<(XLenVT (setult (PtrVT GPR:$rs1), simm12:$imm12)), 45 (SLTIU GPR:$rs1, simm12:$imm12)>; 46def : Pat<(XLenVT (setult (PtrVT GPR:$rs1), (PtrVT GPR:$rs2))), 47 (SLTU GPR:$rs1, GPR:$rs2)>; 48def : Pat<(XLenVT (setlt (PtrVT GPR:$rs1), simm12:$imm12)), 49 (SLTI GPR:$rs1, simm12:$imm12)>; 50def : Pat<(XLenVT (setlt (PtrVT GPR:$rs1), (PtrVT GPR:$rs2))), 51 (SLT GPR:$rs1, GPR:$rs2)>; 52 53// Define pattern expansions for setcc operations that aren't directly 54// handled by a RISC-V instruction. 55foreach Ty = [PtrVT, XLenVT] in { 56def : Pat<(XLenVT (seteq (Ty GPR:$rs1), (Ty 0))), (SLTIU GPR:$rs1, 1)>; 57def : Pat<(XLenVT (seteq (Ty GPR:$rs1), (Ty simm12Plus1:$imm12))), 58 (SLTIU (ADDI GPR:$rs1, (NegImm simm12Plus1:$imm12)), 1)>; 59def : Pat<(XLenVT (seteq (Ty GPR:$rs1), (Ty GPR:$rs2))), 60 (SLTIU (XOR GPR:$rs1, GPR:$rs2), 1)>; 61def : Pat<(XLenVT (setne (Ty GPR:$rs1), (Ty 0))), (SLTU (XLenVT X0), GPR:$rs1)>; 62def : Pat<(XLenVT (setne (Ty GPR:$rs1), (Ty simm12Plus1:$imm12))), 63 (SLTU (XLenVT X0), (ADDI GPR:$rs1, (NegImm simm12Plus1:$imm12)))>; 64def : Pat<(XLenVT (setne (Ty GPR:$rs1), (Ty GPR:$rs2))), 65 (SLTU (XLenVT X0), (XOR GPR:$rs1, GPR:$rs2))>; 66def : Pat<(XLenVT (setugt (Ty GPR:$rs1), (Ty simm12Minus1NonzeroNonNeg1:$imm))), 67 (XORI (SLTIU GPR:$rs1, 68 (ImmPlus1 simm12Minus1NonzeroNonNeg1:$imm)), 1)>; 69def : Pat<(XLenVT (setugt (Ty GPR:$rs1), (Ty GPR:$rs2))), 70 (SLTU GPR:$rs2, GPR:$rs1)>; 71def : Pat<(XLenVT (setgt (Ty GPR:$rs1), (Ty simm12Minus1Nonzero:$imm))), 72 (XORI (SLTI GPR:$rs1, (ImmPlus1 simm12Minus1Nonzero:$imm)), 1)>; 73def : Pat<(XLenVT (setgt (Ty GPR:$rs1), (Ty GPR:$rs2))), 74 (SLT GPR:$rs2, GPR:$rs1)>; 75def : Pat<(XLenVT (setuge (XLenVT GPR:$rs1), (Ty simm12:$imm))), 76 (XORI (SLTIU GPR:$rs1, simm12:$imm), 1)>; 77def : Pat<(XLenVT (setuge (Ty GPR:$rs1), (Ty GPR:$rs2))), 78 (XORI (SLTU GPR:$rs1, GPR:$rs2), 1)>; 79def : Pat<(XLenVT (setge (Ty GPR:$rs1), (Ty simm12:$imm))), 80 (XORI (SLTI GPR:$rs1, simm12:$imm), 1)>; 81def : Pat<(XLenVT (setge (Ty GPR:$rs1), (Ty GPR:$rs2))), 82 (XORI (SLT GPR:$rs1, GPR:$rs2), 1)>; 83def : Pat<(XLenVT (setule (Ty GPR:$rs1), (Ty simm12Minus1NonzeroNonNeg1:$imm))), 84 (SLTIU GPR:$rs1, (ImmPlus1 simm12Minus1NonzeroNonNeg1:$imm))>; 85def : Pat<(XLenVT (setule (Ty GPR:$rs1), (Ty GPR:$rs2))), 86 (XORI (SLTU GPR:$rs2, GPR:$rs1), 1)>; 87def : Pat<(XLenVT (setle (Ty GPR:$rs1), (Ty simm12Minus1Nonzero:$imm))), 88 (SLTI GPR:$rs1, (ImmPlus1 simm12Minus1Nonzero:$imm))>; 89def : Pat<(XLenVT (setle (Ty GPR:$rs1), (Ty GPR:$rs2))), 90 (XORI (SLT GPR:$rs2, GPR:$rs1), 1)>; 91} 92 93let Predicates = [IsRV32] in { 94def : LdPat<load, LW, PtrVT>; 95def : StPat<store, SW, GPR, PtrVT>; 96} 97 98let Predicates = [IsRV64] in { 99def : LdPat<load, LD, PtrVT>; 100def : StPat<store, SD, GPR, PtrVT>; 101} 102 103// Load and store patterns for i16, needed because Zfh makes s16 load/store 104// legal and regbank select may not constrain registers to FP. 105def : LdPat<load, LH, i16>; 106def : StPat<store, SH, GPR, i16>; 107 108def : LdPat<extloadi8, LBU, i16>; // Prefer unsigned due to no c.lb in Zcb. 109def : StPat<truncstorei8, SB, GPR, i16>; 110 111let Predicates = [HasAtomicLdSt] in { 112 def : LdPat<atomic_load_8, LB, i16>; 113 def : LdPat<atomic_load_16, LH, i16>; 114 115 def : StPat<atomic_store_8, SB, GPR, i16>; 116 def : StPat<atomic_store_16, SH, GPR, i16>; 117} 118 119let Predicates = [HasAtomicLdSt, IsRV64] in { 120 def : LdPat<atomic_load_32, LW, i32>; 121 def : StPat<atomic_store_32, SW, GPR, i32>; 122} 123 124//===----------------------------------------------------------------------===// 125// RV64 i32 patterns not used by SelectionDAG 126//===----------------------------------------------------------------------===// 127 128def uimm5i32 : ImmLeaf<i32, [{return isUInt<5>(Imm);}]>; 129 130def zext_is_sext : PatFrag<(ops node:$src), (zext node:$src), [{ 131 KnownBits Known = CurDAG->computeKnownBits(N->getOperand(0), 0); 132 return Known.isNonNegative(); 133}]>; 134 135let Predicates = [IsRV64] in { 136def : LdPat<extloadi8, LBU, i32>; // Prefer unsigned due to no c.lb in Zcb. 137def : LdPat<extloadi16, LH, i32>; 138 139def : StPat<truncstorei8, SB, GPR, i32>; 140def : StPat<truncstorei16, SH, GPR, i32>; 141 142def : Pat<(anyext (i32 GPR:$src)), (COPY GPR:$src)>; 143def : Pat<(sext (i32 GPR:$src)), (ADDIW GPR:$src, 0)>; 144def : Pat<(i32 (trunc GPR:$src)), (COPY GPR:$src)>; 145 146// Use sext if the sign bit of the input is 0. 147def : Pat<(zext_is_sext (i32 GPR:$src)), (ADDIW GPR:$src, 0)>; 148} 149 150let Predicates = [IsRV64, NotHasStdExtZba] in 151def : Pat<(zext (i32 GPR:$src)), (SRLI (i64 (SLLI GPR:$src, 32)), 32)>; 152 153let Predicates = [IsRV32, NoStdExtZbb, NoStdExtZbkb] in 154def : Pat<(XLenVT (zext (i16 GPR:$src))), 155 (SRLI (XLenVT (SLLI GPR:$src, 16)), 16)>; 156 157let Predicates = [IsRV64, NoStdExtZbb, NoStdExtZbkb] in { 158def : Pat<(i64 (zext (i16 GPR:$src))), 159 (SRLI (XLenVT (SLLI GPR:$src, 48)), 48)>; 160def : Pat<(i32 (zext (i16 GPR:$src))), 161 (SRLI (XLenVT (SLLI GPR:$src, 48)), 48)>; 162} 163 164let Predicates = [IsRV32, NoStdExtZbb] in 165def : Pat<(XLenVT (sext (i16 GPR:$src))), 166 (SRAI (XLenVT (SLLI GPR:$src, 16)), 16)>; 167 168let Predicates = [IsRV64, NoStdExtZbb] in { 169def : Pat<(i64 (sext (i16 GPR:$src))), 170 (SRAI (XLenVT (SLLI GPR:$src, 48)), 48)>; 171def : Pat<(i32 (sext (i16 GPR:$src))), 172 (SRAI (XLenVT (SLLI GPR:$src, 48)), 48)>; 173} 174 175//===----------------------------------------------------------------------===// 176// Zb* RV64 patterns not used by SelectionDAG. 177//===----------------------------------------------------------------------===// 178 179let Predicates = [HasStdExtZba, IsRV64] in { 180def : Pat<(zext (i32 GPR:$src)), (ADD_UW GPR:$src, (XLenVT X0))>; 181} 182 183let Predicates = [HasStdExtZbb] in 184def : Pat<(i32 (sext (i16 GPR:$rs))), (SEXT_H GPR:$rs)>; 185let Predicates = [HasStdExtZbb, IsRV64] in 186def : Pat<(i64 (sext (i16 GPR:$rs))), (SEXT_H GPR:$rs)>; 187 188let Predicates = [HasStdExtZbb, IsRV32] in 189def : Pat<(i32 (zext (i16 GPR:$rs))), (ZEXT_H_RV32 GPR:$rs)>; 190let Predicates = [HasStdExtZbb, IsRV64] in { 191def : Pat<(i64 (zext (i16 GPR:$rs))), (ZEXT_H_RV64 GPR:$rs)>; 192def : Pat<(i32 (zext (i16 GPR:$rs))), (ZEXT_H_RV64 GPR:$rs)>; 193} 194 195let Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV32] in 196def : Pat<(i32 (zext (i16 GPR:$rs))), (PACK GPR:$rs, (XLenVT X0))>; 197let Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV64] in { 198def : Pat<(i64 (zext (i16 GPR:$rs))), (PACKW GPR:$rs, (XLenVT X0))>; 199def : Pat<(i32 (zext (i16 GPR:$rs))), (PACKW GPR:$rs, (XLenVT X0))>; 200} 201