1//===- ArithmeticPatterns.td - Arithmetic 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-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef ARITHMETIC_PATTERNS
10#define ARITHMETIC_PATTERNS
11
12include "mlir/IR/PatternBase.td"
13include "mlir/Dialect/Arithmetic/IR/ArithmeticOps.td"
14
15// Add two integer attributes and create a new one with the result.
16def AddIntAttrs : NativeCodeCall<"addIntegerAttrs($_builder, $0, $1, $2)">;
17
18// Subtract two integer attributes and createa a new one with the result.
19def SubIntAttrs : NativeCodeCall<"subIntegerAttrs($_builder, $0, $1, $2)">;
20
21//===----------------------------------------------------------------------===//
22// AddIOp
23//===----------------------------------------------------------------------===//
24
25// addi is commutative and will be canonicalized to have its constants appear
26// as the second operand.
27
28// addi(addi(x, c0), c1) -> addi(x, c0 + c1)
29def AddIAddConstant :
30    Pat<(Arith_AddIOp:$res
31          (Arith_AddIOp $x, (Arith_ConstantOp APIntAttr:$c0)),
32          (Arith_ConstantOp APIntAttr:$c1)),
33        (Arith_AddIOp $x, (Arith_ConstantOp (AddIntAttrs $res, $c0, $c1)))>;
34
35// addi(subi(x, c0), c1) -> addi(x, c1 - c0)
36def AddISubConstantRHS :
37    Pat<(Arith_AddIOp:$res
38          (Arith_SubIOp $x, (Arith_ConstantOp APIntAttr:$c0)),
39          (Arith_ConstantOp APIntAttr:$c1)),
40        (Arith_AddIOp $x, (Arith_ConstantOp (SubIntAttrs $res, $c1, $c0)))>;
41
42// addi(subi(c0, x), c1) -> subi(c0 + c1, x)
43def AddISubConstantLHS :
44    Pat<(Arith_AddIOp:$res
45          (Arith_SubIOp (Arith_ConstantOp APIntAttr:$c0), $x),
46          (Arith_ConstantOp APIntAttr:$c1)),
47        (Arith_SubIOp (Arith_ConstantOp (AddIntAttrs $res, $c0, $c1)), $x)>;
48
49//===----------------------------------------------------------------------===//
50// SubIOp
51//===----------------------------------------------------------------------===//
52
53// subi(addi(x, c0), c1) -> addi(x, c0 - c1)
54def SubIRHSAddConstant :
55    Pat<(Arith_SubIOp:$res
56          (Arith_AddIOp $x, (Arith_ConstantOp APIntAttr:$c0)),
57          (Arith_ConstantOp APIntAttr:$c1)),
58        (Arith_AddIOp $x, (Arith_ConstantOp (SubIntAttrs $res, $c0, $c1)))>;
59
60// subi(c1, addi(x, c0)) -> subi(c1 - c0, x)
61def SubILHSAddConstant :
62    Pat<(Arith_SubIOp:$res
63          (Arith_ConstantOp APIntAttr:$c1),
64          (Arith_AddIOp $x, (Arith_ConstantOp APIntAttr:$c0))),
65        (Arith_SubIOp (Arith_ConstantOp (SubIntAttrs $res, $c1, $c0)), $x)>;
66
67// subi(subi(x, c0), c1) -> subi(x, c0 + c1)
68def SubIRHSSubConstantRHS :
69    Pat<(Arith_SubIOp:$res
70          (Arith_SubIOp $x, (Arith_ConstantOp APIntAttr:$c0)),
71          (Arith_ConstantOp APIntAttr:$c1)),
72        (Arith_SubIOp $x, (Arith_ConstantOp (AddIntAttrs $res, $c0, $c1)))>;
73
74// subi(subi(c0, x), c1) -> subi(c0 - c1, x)
75def SubIRHSSubConstantLHS :
76    Pat<(Arith_SubIOp:$res
77          (Arith_SubIOp (Arith_ConstantOp APIntAttr:$c0), $x),
78          (Arith_ConstantOp APIntAttr:$c1)),
79        (Arith_SubIOp (Arith_ConstantOp (SubIntAttrs $res, $c0, $c1)), $x)>;
80
81// subi(c1, subi(x, c0)) -> subi(c0 + c1, x)
82def SubILHSSubConstantRHS :
83    Pat<(Arith_SubIOp:$res
84          (Arith_ConstantOp APIntAttr:$c1),
85          (Arith_SubIOp $x, (Arith_ConstantOp APIntAttr:$c0))),
86        (Arith_SubIOp (Arith_ConstantOp (AddIntAttrs $res, $c0, $c1)), $x)>;
87
88// subi(c1, subi(c0, x)) -> addi(x, c1 - c0)
89def SubILHSSubConstantLHS :
90    Pat<(Arith_SubIOp:$res
91          (Arith_ConstantOp APIntAttr:$c1),
92          (Arith_SubIOp (Arith_ConstantOp APIntAttr:$c0), $x)),
93        (Arith_AddIOp $x, (Arith_ConstantOp (SubIntAttrs $res, $c1, $c0)))>;
94
95//===----------------------------------------------------------------------===//
96// XOrIOp
97//===----------------------------------------------------------------------===//
98
99// xori is commutative and will be canonicalized to have its constants appear
100// as the second operand.
101
102// not(cmpi(pred, a, b)) -> cmpi(~pred, a, b), where not(x) is xori(x, 1)
103def InvertPredicate : NativeCodeCall<"invertPredicate($0)">;
104def XOrINotCmpI :
105    Pat<(Arith_XOrIOp
106          (Arith_CmpIOp $pred, $a, $b),
107          (Arith_ConstantOp ConstantAttr<I1Attr, "1">)),
108        (Arith_CmpIOp (InvertPredicate $pred), $a, $b)>;
109
110//===----------------------------------------------------------------------===//
111// CmpIOp
112//===----------------------------------------------------------------------===//
113
114// cmpi(== or !=, a ext iNN, b ext iNN) == cmpi(== or !=, a, b)
115def CmpIExtSI :
116    Pat<(Arith_CmpIOp $pred,
117          (Arith_ExtSIOp $a),
118          (Arith_ExtSIOp $b)),
119        (Arith_CmpIOp $pred, $a, $b),
120        [(Constraint<CPred<"$0.getType() == $1.getType()">> $a, $b),
121         (Constraint<CPred<"$0.getValue() == arith::CmpIPredicate::eq || $0.getValue() == arith::CmpIPredicate::ne">> $pred)]>;
122
123// cmpi(== or !=, a ext iNN, b ext iNN) == cmpi(== or !=, a, b)
124def CmpIExtUI :
125    Pat<(Arith_CmpIOp $pred,
126          (Arith_ExtUIOp $a),
127          (Arith_ExtUIOp $b)),
128        (Arith_CmpIOp $pred, $a, $b),
129        [(Constraint<CPred<"$0.getType() == $1.getType()">> $a, $b),
130         (Constraint<CPred<"$0.getValue() == arith::CmpIPredicate::eq || $0.getValue() == arith::CmpIPredicate::ne">> $pred)]>;
131
132//===----------------------------------------------------------------------===//
133// IndexCastOp
134//===----------------------------------------------------------------------===//
135
136// index_cast(index_cast(x)) -> x, if dstType == srcType.
137def IndexCastOfIndexCast :
138    Pat<(Arith_IndexCastOp:$res (Arith_IndexCastOp $x)),
139        (replaceWithValue $x),
140        [(Constraint<CPred<"$0.getType() == $1.getType()">> $res, $x)]>;
141
142// index_cast(extsi(x)) -> index_cast(x)
143def IndexCastOfExtSI :
144    Pat<(Arith_IndexCastOp (Arith_ExtSIOp $x)), (Arith_IndexCastOp $x)>;
145
146//===----------------------------------------------------------------------===//
147// BitcastOp
148//===----------------------------------------------------------------------===//
149
150// bitcast(bitcast(x)) -> x
151def BitcastOfBitcast :
152    Pat<(Arith_BitcastOp (Arith_BitcastOp $x)), (replaceWithValue $x)>;
153
154//===----------------------------------------------------------------------===//
155// ExtSIOp
156//===----------------------------------------------------------------------===//
157
158// extsi(extui(x iN : iM) : iL) -> extui(x : iL)
159def ExtSIOfExtUI :
160    Pat<(Arith_ExtSIOp (Arith_ExtUIOp $x)), (Arith_ExtUIOp $x)>;
161
162//===----------------------------------------------------------------------===//
163// AndIOp
164//===----------------------------------------------------------------------===//
165
166// and extui(x), extui(y) -> extui(and(x,y))
167def AndOfExtUI :
168    Pat<(Arith_AndIOp (Arith_ExtUIOp $x), (Arith_ExtUIOp $y)), (Arith_ExtUIOp (Arith_AndIOp $x, $y)),
169      [(Constraint<CPred<"$0.getType() == $1.getType()">> $x, $y)]>;
170
171// and extsi(x), extsi(y) -> extsi(and(x,y))
172def AndOfExtSI :
173    Pat<(Arith_AndIOp (Arith_ExtSIOp $x), (Arith_ExtSIOp $y)), (Arith_ExtSIOp (Arith_AndIOp $x, $y)),
174      [(Constraint<CPred<"$0.getType() == $1.getType()">> $x, $y)]>;
175
176//===----------------------------------------------------------------------===//
177// OrIOp
178//===----------------------------------------------------------------------===//
179
180// or extui(x), extui(y) -> extui(or(x,y))
181def OrOfExtUI :
182    Pat<(Arith_OrIOp (Arith_ExtUIOp $x), (Arith_ExtUIOp $y)), (Arith_ExtUIOp (Arith_OrIOp $x, $y)),
183      [(Constraint<CPred<"$0.getType() == $1.getType()">> $x, $y)]>;
184
185// or extsi(x), extsi(y) -> extsi(or(x,y))
186def OrOfExtSI :
187    Pat<(Arith_OrIOp (Arith_ExtSIOp $x), (Arith_ExtSIOp $y)), (Arith_ExtSIOp (Arith_OrIOp $x, $y)),
188      [(Constraint<CPred<"$0.getType() == $1.getType()">> $x, $y)]>;
189
190#endif // ARITHMETIC_PATTERNS
191