brintos

brintos / llvm-project-archived public Read only

0
0
Text · 17.8 KiB · e256915 Raw
435 lines · plain
1//===- ArithPatterns.td - Arith dialect 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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef ARITH_PATTERNS10#define ARITH_PATTERNS11 12include "mlir/IR/PatternBase.td"13include "mlir/Dialect/Arith/IR/ArithOps.td"14 15// Create zero attribute of type matching the argument's type.16def GetZeroAttr : NativeCodeCall<"$_builder.getZeroAttr($0.getType())">;17 18// Add two integer attributes and create a new one with the result.19def AddIntAttrs : NativeCodeCall<"addIntegerAttrs($_builder, $0, $1, $2)">;20 21// Subtract two integer attributes and create a new one with the result.22def SubIntAttrs : NativeCodeCall<"subIntegerAttrs($_builder, $0, $1, $2)">;23 24// Multiply two integer attributes and create a new one with the result.25def MulIntAttrs : NativeCodeCall<"mulIntegerAttrs($_builder, $0, $1, $2)">;26 27// Merge overflow flags from 2 ops, selecting the most conservative combination.28def MergeOverflow : NativeCodeCall<"mergeOverflowFlags($0, $1)">;29 30// Default overflow flag (all wraparounds allowed).31defvar DefOverflow = ConstantEnumCase<Arith_IntegerOverflowAttr, "none">;32 33class cast<string type> : NativeCodeCall<"::mlir::cast<" # type # ">($0)">;34 35//===----------------------------------------------------------------------===//36// AddIOp37//===----------------------------------------------------------------------===//38 39// addi is commutative and will be canonicalized to have its constants appear40// as the second operand.41 42// addi(addi(x, c0), c1) -> addi(x, c0 + c1)43def AddIAddConstant :44    Pat<(Arith_AddIOp:$res45          (Arith_AddIOp $x, (ConstantLikeMatcher APIntAttr:$c0), $ovf1),46          (ConstantLikeMatcher APIntAttr:$c1), $ovf2),47        (Arith_AddIOp $x, (Arith_ConstantOp (AddIntAttrs $res, $c0, $c1)),48            (MergeOverflow $ovf1, $ovf2))>;49 50// addi(subi(x, c0), c1) -> addi(x, c1 - c0)51def AddISubConstantRHS :52    Pat<(Arith_AddIOp:$res53          (Arith_SubIOp $x, (ConstantLikeMatcher APIntAttr:$c0), $ovf1),54          (ConstantLikeMatcher APIntAttr:$c1), $ovf2),55        (Arith_AddIOp $x, (Arith_ConstantOp (SubIntAttrs $res, $c1, $c0)),56            (MergeOverflow $ovf1, $ovf2))>;57 58// addi(subi(c0, x), c1) -> subi(c0 + c1, x)59def AddISubConstantLHS :60    Pat<(Arith_AddIOp:$res61          (Arith_SubIOp (ConstantLikeMatcher APIntAttr:$c0), $x, $ovf1),62          (ConstantLikeMatcher APIntAttr:$c1), $ovf2),63        (Arith_SubIOp (Arith_ConstantOp (AddIntAttrs $res, $c0, $c1)), $x,64            (MergeOverflow $ovf1, $ovf2))>;65 66def IsScalarOrSplatNegativeOne :67    Constraint<And<[68      CPred<"succeeded(getIntOrSplatIntValue($0))">,69      CPred<"getIntOrSplatIntValue($0)->isAllOnes()">]>>;70 71// addi(x, muli(y, -1)) -> subi(x, y)72def AddIMulNegativeOneRhs :73    Pat<(Arith_AddIOp74           $x,75           (Arith_MulIOp $y, (ConstantLikeMatcher AnyAttr:$c0), $ovf1), $ovf2),76        (Arith_SubIOp $x, $y, DefOverflow), // TODO: overflow flags77        [(IsScalarOrSplatNegativeOne $c0)]>;78 79// addi(muli(x, -1), y) -> subi(y, x)80def AddIMulNegativeOneLhs :81    Pat<(Arith_AddIOp82           (Arith_MulIOp $x, (ConstantLikeMatcher AnyAttr:$c0), $ovf1),83           $y, $ovf2),84        (Arith_SubIOp $y, $x, DefOverflow), // TODO: overflow flags85        [(IsScalarOrSplatNegativeOne $c0)]>;86 87// muli(muli(x, c0), c1) -> muli(x, c0 * c1)88def MulIMulIConstant :89    Pat<(Arith_MulIOp:$res90          (Arith_MulIOp $x, (ConstantLikeMatcher APIntAttr:$c0), $ovf1),91          (ConstantLikeMatcher APIntAttr:$c1), $ovf2),92        (Arith_MulIOp $x, (Arith_ConstantOp (MulIntAttrs $res, $c0, $c1)),93            (MergeOverflow $ovf1, $ovf2)),94             [(Constraint<CPred<"$0.getType() == cast<IntegerAttr>($1).getType()">> $res, $c0),95              (Constraint<CPred<"$0.getType() == cast<IntegerAttr>($1).getType()">> $res, $c1)]>;96 97//===----------------------------------------------------------------------===//98// AddUIExtendedOp99//===----------------------------------------------------------------------===//100 101// addui_extended(x, y) -> [addi(x, y), x], when the `overflow` result has no102// uses. Since the 'overflow' result is unused, any replacement value will do.103def AddUIExtendedToAddI:104    Pattern<(Arith_AddUIExtendedOp:$res $x, $y),105             [(Arith_AddIOp $x, $y, DefOverflow), (replaceWithValue $x)],106             [(Constraint<CPred<"$0.getUses().empty()">> $res__1)]>;107 108//===----------------------------------------------------------------------===//109// SubIOp110//===----------------------------------------------------------------------===//111 112// subi(addi(x, c0), c1) -> addi(x, c0 - c1)113def SubIRHSAddConstant :114    Pat<(Arith_SubIOp:$res115          (Arith_AddIOp $x, (ConstantLikeMatcher APIntAttr:$c0), $ovf1),116          (ConstantLikeMatcher APIntAttr:$c1), $ovf2),117        (Arith_AddIOp $x, (Arith_ConstantOp (SubIntAttrs $res, $c0, $c1)),118            DefOverflow)>; // TODO: overflow flags119 120// subi(c1, addi(x, c0)) -> subi(c1 - c0, x)121def SubILHSAddConstant :122    Pat<(Arith_SubIOp:$res123          (ConstantLikeMatcher APIntAttr:$c1),124          (Arith_AddIOp $x, (ConstantLikeMatcher APIntAttr:$c0), $ovf1), $ovf2),125        (Arith_SubIOp (Arith_ConstantOp (SubIntAttrs $res, $c1, $c0)), $x,126            (MergeOverflow $ovf1, $ovf2))>;127 128// subi(subi(x, c0), c1) -> subi(x, c0 + c1)129def SubIRHSSubConstantRHS :130    Pat<(Arith_SubIOp:$res131          (Arith_SubIOp $x, (ConstantLikeMatcher APIntAttr:$c0), $ovf1),132          (ConstantLikeMatcher APIntAttr:$c1), $ovf2),133        (Arith_SubIOp $x, (Arith_ConstantOp (AddIntAttrs $res, $c0, $c1)),134            (MergeOverflow $ovf1, $ovf2))>;135 136// subi(subi(c0, x), c1) -> subi(c0 - c1, x)137def SubIRHSSubConstantLHS :138    Pat<(Arith_SubIOp:$res139          (Arith_SubIOp (ConstantLikeMatcher APIntAttr:$c0), $x, $ovf1),140          (ConstantLikeMatcher APIntAttr:$c1), $ovf2),141        (Arith_SubIOp (Arith_ConstantOp (SubIntAttrs $res, $c0, $c1)), $x,142            (MergeOverflow $ovf1, $ovf2))>;143 144// subi(c1, subi(x, c0)) -> subi(c0 + c1, x)145def SubILHSSubConstantRHS :146    Pat<(Arith_SubIOp:$res147          (ConstantLikeMatcher APIntAttr:$c1),148          (Arith_SubIOp $x, (ConstantLikeMatcher APIntAttr:$c0), $ovf1), $ovf2),149        (Arith_SubIOp (Arith_ConstantOp (AddIntAttrs $res, $c0, $c1)), $x,150            (MergeOverflow $ovf1, $ovf2))>;151 152// subi(c1, subi(c0, x)) -> addi(x, c1 - c0)153def SubILHSSubConstantLHS :154    Pat<(Arith_SubIOp:$res155          (ConstantLikeMatcher APIntAttr:$c1),156          (Arith_SubIOp (ConstantLikeMatcher APIntAttr:$c0), $x, $ovf1), $ovf2),157        (Arith_AddIOp $x, (Arith_ConstantOp (SubIntAttrs $res, $c1, $c0)),158            (MergeOverflow $ovf1, $ovf2))>;159 160// subi(subi(a, b), a) -> subi(0, b)161def SubISubILHSRHSLHS :162    Pat<(Arith_SubIOp:$res (Arith_SubIOp $x, $y, $ovf1), $x, $ovf2),163        (Arith_SubIOp (Arith_ConstantOp (GetZeroAttr $y)), $y,164            (MergeOverflow $ovf1, $ovf2))>;165 166//===----------------------------------------------------------------------===//167// MulSIExtendedOp168//===----------------------------------------------------------------------===//169 170// mulsi_extended(x, y) -> [muli(x, y), x], when the `high` result is unused.171// Since the `high` result it not used, any replacement value will do.172def MulSIExtendedToMulI :173    Pattern<(Arith_MulSIExtendedOp:$res $x, $y),174        [(Arith_MulIOp $x, $y, DefOverflow), (replaceWithValue $x)],175        [(Constraint<CPred<"$0.getUses().empty()">> $res__1)]>;176 177 178def IsScalarOrSplatOne :179    Constraint<And<[180      CPred<"succeeded(getIntOrSplatIntValue($0))">,181      CPred<"getIntOrSplatIntValue($0)->isStrictlyPositive()">,182      CPred<"*getIntOrSplatIntValue($0) == 1">]>>;183 184// mulsi_extended(x, 1) -> [x, extsi(cmpi slt, x, 0)]185def MulSIExtendedRHSOne :186    Pattern<(Arith_MulSIExtendedOp $x, (ConstantLikeMatcher AnyAttr:$c1)),187            [(replaceWithValue $x),188             (Arith_ExtSIOp(Arith_CmpIOp189                ConstantEnumCase<Arith_CmpIPredicateAttr, "slt">,190                $x,191                (Arith_ConstantOp (GetZeroAttr $x))))],192            [(IsScalarOrSplatOne $c1)]>;193 194//===----------------------------------------------------------------------===//195// MulUIExtendedOp196//===----------------------------------------------------------------------===//197 198// mului_extended(x, y) -> [muli(x, y), x], when the `high` result is unused.199// Since the `high` result it not used, any replacement value will do.200def MulUIExtendedToMulI :201    Pattern<(Arith_MulUIExtendedOp:$res $x, $y),202        [(Arith_MulIOp $x, $y, DefOverflow), (replaceWithValue $x)],203        [(Constraint<CPred<"$0.getUses().empty()">> $res__1)]>;204 205//===----------------------------------------------------------------------===//206// XOrIOp207//===----------------------------------------------------------------------===//208 209// xori is commutative and will be canonicalized to have its constants appear210// as the second operand.211 212// not(cmpi(pred, a, b)) -> cmpi(~pred, a, b), where not(x) is xori(x, 1)213def InvertPredicate : NativeCodeCall<"invertPredicate($0)">;214def XOrINotCmpI :215    Pat<(Arith_XOrIOp216          (Arith_CmpIOp $pred, $a, $b),217          (ConstantLikeMatcher ConstantAttr<I1Attr, "1">)),218        (Arith_CmpIOp (InvertPredicate $pred), $a, $b)>;219 220// xor extui(x), extui(y) -> extui(xor(x,y))221def XOrIOfExtUI :222    Pat<(Arith_XOrIOp (Arith_ExtUIOp $x), (Arith_ExtUIOp $y)), (Arith_ExtUIOp (Arith_XOrIOp $x, $y)),223      [(Constraint<CPred<"$0.getType() == $1.getType()">> $x, $y)]>;224 225// xor extsi(x), extsi(y) -> extsi(xor(x,y))226def XOrIOfExtSI :227    Pat<(Arith_XOrIOp (Arith_ExtSIOp $x), (Arith_ExtSIOp $y)), (Arith_ExtSIOp (Arith_XOrIOp $x, $y)),228      [(Constraint<CPred<"$0.getType() == $1.getType()">> $x, $y)]>;229 230//===----------------------------------------------------------------------===//231// CmpIOp232//===----------------------------------------------------------------------===//233 234// cmpi(== or !=, a ext iNN, b ext iNN) == cmpi(== or !=, a, b)235def CmpIExtSI :236    Pat<(Arith_CmpIOp $pred,237          (Arith_ExtSIOp $a),238          (Arith_ExtSIOp $b)),239        (Arith_CmpIOp $pred, $a, $b),240        [(Constraint<CPred<"$0.getType() == $1.getType()">> $a, $b),241         (Constraint<242            CPred<"$0.getValue() == arith::CmpIPredicate::eq || "243                  "$0.getValue() == arith::CmpIPredicate::ne">> $pred)]>;244 245// cmpi(== or !=, a ext iNN, b ext iNN) == cmpi(== or !=, a, b)246def CmpIExtUI :247    Pat<(Arith_CmpIOp $pred,248          (Arith_ExtUIOp $a),249          (Arith_ExtUIOp $b)),250        (Arith_CmpIOp $pred, $a, $b),251        [(Constraint<CPred<"$0.getType() == $1.getType()">> $a, $b),252         (Constraint<253            CPred<"$0.getValue() == arith::CmpIPredicate::eq || "254                  "$0.getValue() == arith::CmpIPredicate::ne">> $pred)]>;255 256//===----------------------------------------------------------------------===//257// SelectOp258//===----------------------------------------------------------------------===//259 260// select(not(pred), a, b) => select(pred, b, a)261def SelectNotCond :262    Pat<(SelectOp (Arith_XOrIOp $pred, (ConstantLikeMatcher APIntAttr:$ones)), $a, $b),263        (SelectOp $pred, $b, $a),264        [(IsScalarOrSplatNegativeOne $ones)]>;265 266// select(pred, select(pred, a, b), c) => select(pred, a, c)267def RedundantSelectTrue :268    Pat<(SelectOp $pred, (SelectOp $pred, $a, $b), $c),269        (SelectOp $pred, $a, $c)>;270 271// select(pred, a, select(pred, b, c)) => select(pred, a, c)272def RedundantSelectFalse :273    Pat<(SelectOp $pred, $a, (SelectOp $pred, $b, $c)),274        (SelectOp $pred, $a, $c)>;275 276// select(pred, false, true) => not(pred)277def SelectI1ToNot :278    Pat<(SelectOp $pred,279                  (ConstantLikeMatcher ConstantAttr<I1Attr, "0">),280                  (ConstantLikeMatcher ConstantAttr<I1Attr, "1">)),281        (Arith_XOrIOp $pred, (Arith_ConstantOp ConstantAttr<I1Attr, "1">))>;282 283//===----------------------------------------------------------------------===//284// IndexCastOp285//===----------------------------------------------------------------------===//286 287// index_cast(index_cast(x)) -> x, if dstType == srcType.288def IndexCastOfIndexCast :289    Pat<(Arith_IndexCastOp:$res (Arith_IndexCastOp $x)),290        (replaceWithValue $x),291        [(Constraint<CPred<"$0.getType() == $1.getType()">> $res, $x)]>;292 293// index_cast(extsi(x)) -> index_cast(x)294def IndexCastOfExtSI :295    Pat<(Arith_IndexCastOp (Arith_ExtSIOp $x)), (Arith_IndexCastOp $x)>;296 297//===----------------------------------------------------------------------===//298// IndexCastUIOp299//===----------------------------------------------------------------------===//300 301// index_castui(index_castui(x)) -> x, if dstType == srcType.302def IndexCastUIOfIndexCastUI :303    Pat<(Arith_IndexCastUIOp:$res (Arith_IndexCastUIOp $x)),304        (replaceWithValue $x),305        [(Constraint<CPred<"$0.getType() == $1.getType()">> $res, $x)]>;306 307// index_castui(extui(x)) -> index_castui(x)308def IndexCastUIOfExtUI :309    Pat<(Arith_IndexCastUIOp (Arith_ExtUIOp $x)), (Arith_IndexCastUIOp $x)>;310 311 312//===----------------------------------------------------------------------===//313// BitcastOp314//===----------------------------------------------------------------------===//315 316// bitcast(type1, bitcast(type2, x)) -> bitcast(type1, x)317def BitcastOfBitcast :318    Pat<(Arith_BitcastOp (Arith_BitcastOp $x)), (Arith_BitcastOp $x)>;319 320//===----------------------------------------------------------------------===//321// ExtSIOp322//===----------------------------------------------------------------------===//323 324// extsi(extui(x iN : iM) : iL) -> extui(x : iL)325def ExtSIOfExtUI :326    Pat<(Arith_ExtSIOp (Arith_ExtUIOp $x)), (Arith_ExtUIOp $x)>;327 328//===----------------------------------------------------------------------===//329// AndIOp330//===----------------------------------------------------------------------===//331 332// and extui(x), extui(y) -> extui(and(x,y))333def AndOfExtUI :334    Pat<(Arith_AndIOp (Arith_ExtUIOp $x), (Arith_ExtUIOp $y)),335        (Arith_ExtUIOp (Arith_AndIOp $x, $y)),336        [(Constraint<CPred<"$0.getType() == $1.getType()">> $x, $y)]>;337 338// and extsi(x), extsi(y) -> extsi(and(x,y))339def AndOfExtSI :340    Pat<(Arith_AndIOp (Arith_ExtSIOp $x), (Arith_ExtSIOp $y)),341        (Arith_ExtSIOp (Arith_AndIOp $x, $y)),342        [(Constraint<CPred<"$0.getType() == $1.getType()">> $x, $y)]>;343 344//===----------------------------------------------------------------------===//345// OrIOp346//===----------------------------------------------------------------------===//347 348// or extui(x), extui(y) -> extui(or(x,y))349def OrOfExtUI :350    Pat<(Arith_OrIOp (Arith_ExtUIOp $x), (Arith_ExtUIOp $y)),351        (Arith_ExtUIOp (Arith_OrIOp $x, $y)),352        [(Constraint<CPred<"$0.getType() == $1.getType()">> $x, $y)]>;353 354// or extsi(x), extsi(y) -> extsi(or(x,y))355def OrOfExtSI :356    Pat<(Arith_OrIOp (Arith_ExtSIOp $x), (Arith_ExtSIOp $y)),357        (Arith_ExtSIOp (Arith_OrIOp $x, $y)),358        [(Constraint<CPred<"$0.getType() == $1.getType()">> $x, $y)]>;359 360//===----------------------------------------------------------------------===//361// TruncIOp362//===----------------------------------------------------------------------===//363 364def ValueWiderThan :365    Constraint<And<[366      CPred<"getScalarOrElementWidth($0) > getScalarOrElementWidth($1)">,367      CPred<"getScalarOrElementWidth($1) > 0">]>>;368 369def TruncationMatchesShiftAmount :370    Constraint<And<[371      CPred<"succeeded(getIntOrSplatIntValue($2))">,372      CPred<"(getScalarOrElementWidth($0) - getScalarOrElementWidth($1)) == "373              "*getIntOrSplatIntValue($2)">]>>;374 375// trunci(extsi(x)) -> extsi(x), when only the sign-extension bits are truncated376def TruncIExtSIToExtSI :377    Pat<(Arith_TruncIOp:$tr (Arith_ExtSIOp:$ext $x), $overflow),378        (Arith_ExtSIOp $x),379        [(ValueWiderThan $ext, $tr),380         (ValueWiderThan $tr, $x)]>;381 382// trunci(extui(x)) -> extui(x), when only the zero-extension bits are truncated383def TruncIExtUIToExtUI :384    Pat<(Arith_TruncIOp:$tr (Arith_ExtUIOp:$ext $x), $overflow),385        (Arith_ExtUIOp $x),386        [(ValueWiderThan $ext, $tr),387         (ValueWiderThan $tr, $x)]>;388 389// trunci(shrsi(x, c)) -> trunci(shrui(x, c))390def TruncIShrSIToTrunciShrUI :391    Pat<(Arith_TruncIOp:$tr392          (Arith_ShRSIOp $x, (ConstantLikeMatcher TypedAttrInterface:$c0), $exact), $overflow),393        (Arith_TruncIOp (Arith_ShRUIOp $x, (Arith_ConstantOp (cast<"TypedAttr"> $c0)), $exact), $overflow),394        [(TruncationMatchesShiftAmount $x, $tr, $c0)]>;395 396//===----------------------------------------------------------------------===//397// TruncFOp398//===----------------------------------------------------------------------===//399 400// truncf(sitofp(x)) -> sitofp(x) if default rounding mode.401def TruncFSIToFPToSIToFP :402    Pat<(Arith_TruncFOp:$tr (Arith_SIToFPOp:$fp $x), $rmf, $fmf),403        (Arith_SIToFPOp $x),404        [(Constraint<CPred<"$0 == nullptr">, "default rounding mode"> $rmf)]>;405 406// truncf(uitofp(x)) -> uitofp(x) if default rounding mode.407def TruncFUIToFPToUIToFP :408    Pat<(Arith_TruncFOp:$tr (Arith_UIToFPOp:$fp $x), $rmf, $fmf),409        (Arith_UIToFPOp $x),410        [(Constraint<CPred<"$0 == nullptr">, "default rounding mode"> $rmf)]>;411 412//===----------------------------------------------------------------------===//413// MulFOp414//===----------------------------------------------------------------------===//415 416// mulf(negf(x), negf(y)) -> mulf(x,y)417// (retain fastmath flags of original mulf)418def MulFOfNegF :419    Pat<(Arith_MulFOp (Arith_NegFOp $x, $_), (Arith_NegFOp $y, $_), $fmf),420        (Arith_MulFOp $x, $y, $fmf),421        [(Constraint<CPred<"$0.getType() == $1.getType()">> $x, $y)]>;422 423//===----------------------------------------------------------------------===//424// DivFOp425//===----------------------------------------------------------------------===//426 427// divf(negf(x), negf(y)) -> divf(x,y)428// (retain fastmath flags of original divf)429def DivFOfNegF :430    Pat<(Arith_DivFOp (Arith_NegFOp $x, $_), (Arith_NegFOp $y, $_), $fmf),431        (Arith_DivFOp $x, $y, $fmf),432        [(Constraint<CPred<"$0.getType() == $1.getType()">> $x, $y)]>;433 434#endif // ARITH_PATTERNS435