@@ -24,10 +24,10 @@ def SubIntAttrs : NativeCodeCall<"subIntegerAttrs($_builder, $0, $1, $2)">;
24
24
// Multiply two integer attributes and create a new one with the result.
25
25
def MulIntAttrs : NativeCodeCall<"mulIntegerAttrs($_builder, $0, $1, $2)">;
26
26
27
- // TODO: Canonicalizations currently doesn't take into account integer overflow
28
- // flags and always reset them to default (wraparound) which is safe but can
29
- // inhibit later optimizations. Individual patterns must be reviewed for
30
- // better handling of overflow flags .
27
+ // Merge overflow flags from 2 ops, selecting the most conservative combination.
28
+ def MergeOverflow : NativeCodeCall<"mergeOverflowFlags($0, $1)">;
29
+
30
+ // Default overflow flag (all wraparounds allowed) .
31
31
defvar DefOverflow = ConstantEnumCase<Arith_IntegerOverflowAttr, "none">;
32
32
33
33
class cast<string type> : NativeCodeCall<"::mlir::cast<" # type # ">($0)">;
@@ -45,23 +45,23 @@ def AddIAddConstant :
45
45
(Arith_AddIOp $x, (ConstantLikeMatcher APIntAttr:$c0), $ovf1),
46
46
(ConstantLikeMatcher APIntAttr:$c1), $ovf2),
47
47
(Arith_AddIOp $x, (Arith_ConstantOp (AddIntAttrs $res, $c0, $c1)),
48
- DefOverflow )>;
48
+ (MergeOverflow $ovf1, $ovf2) )>;
49
49
50
50
// addi(subi(x, c0), c1) -> addi(x, c1 - c0)
51
51
def AddISubConstantRHS :
52
52
Pat<(Arith_AddIOp:$res
53
53
(Arith_SubIOp $x, (ConstantLikeMatcher APIntAttr:$c0), $ovf1),
54
54
(ConstantLikeMatcher APIntAttr:$c1), $ovf2),
55
55
(Arith_AddIOp $x, (Arith_ConstantOp (SubIntAttrs $res, $c1, $c0)),
56
- DefOverflow )>;
56
+ (MergeOverflow $ovf1, $ovf2) )>;
57
57
58
58
// addi(subi(c0, x), c1) -> subi(c0 + c1, x)
59
59
def AddISubConstantLHS :
60
60
Pat<(Arith_AddIOp:$res
61
61
(Arith_SubIOp (ConstantLikeMatcher APIntAttr:$c0), $x, $ovf1),
62
62
(ConstantLikeMatcher APIntAttr:$c1), $ovf2),
63
63
(Arith_SubIOp (Arith_ConstantOp (AddIntAttrs $res, $c0, $c1)), $x,
64
- DefOverflow )>;
64
+ (MergeOverflow $ovf1, $ovf2) )>;
65
65
66
66
def IsScalarOrSplatNegativeOne :
67
67
Constraint<And<[
@@ -73,15 +73,15 @@ def AddIMulNegativeOneRhs :
73
73
Pat<(Arith_AddIOp
74
74
$x,
75
75
(Arith_MulIOp $y, (ConstantLikeMatcher AnyAttr:$c0), $ovf1), $ovf2),
76
- (Arith_SubIOp $x, $y, DefOverflow),
76
+ (Arith_SubIOp $x, $y, DefOverflow), // TODO: overflow flags
77
77
[(IsScalarOrSplatNegativeOne $c0)]>;
78
78
79
79
// addi(muli(x, -1), y) -> subi(y, x)
80
80
def AddIMulNegativeOneLhs :
81
81
Pat<(Arith_AddIOp
82
82
(Arith_MulIOp $x, (ConstantLikeMatcher AnyAttr:$c0), $ovf1),
83
83
$y, $ovf2),
84
- (Arith_SubIOp $y, $x, DefOverflow),
84
+ (Arith_SubIOp $y, $x, DefOverflow), // TODO: overflow flags
85
85
[(IsScalarOrSplatNegativeOne $c0)]>;
86
86
87
87
// muli(muli(x, c0), c1) -> muli(x, c0 * c1)
@@ -90,7 +90,7 @@ def MulIMulIConstant :
90
90
(Arith_MulIOp $x, (ConstantLikeMatcher APIntAttr:$c0), $ovf1),
91
91
(ConstantLikeMatcher APIntAttr:$c1), $ovf2),
92
92
(Arith_MulIOp $x, (Arith_ConstantOp (MulIntAttrs $res, $c0, $c1)),
93
- DefOverflow )>;
93
+ (MergeOverflow $ovf1, $ovf2) )>;
94
94
95
95
//===----------------------------------------------------------------------===//
96
96
// AddUIExtendedOp
@@ -113,52 +113,53 @@ def SubIRHSAddConstant :
113
113
(Arith_AddIOp $x, (ConstantLikeMatcher APIntAttr:$c0), $ovf1),
114
114
(ConstantLikeMatcher APIntAttr:$c1), $ovf2),
115
115
(Arith_AddIOp $x, (Arith_ConstantOp (SubIntAttrs $res, $c0, $c1)),
116
- DefOverflow)>;
116
+ DefOverflow)>; // TODO: overflow flags
117
117
118
118
// subi(c1, addi(x, c0)) -> subi(c1 - c0, x)
119
119
def SubILHSAddConstant :
120
120
Pat<(Arith_SubIOp:$res
121
121
(ConstantLikeMatcher APIntAttr:$c1),
122
122
(Arith_AddIOp $x, (ConstantLikeMatcher APIntAttr:$c0), $ovf1), $ovf2),
123
123
(Arith_SubIOp (Arith_ConstantOp (SubIntAttrs $res, $c1, $c0)), $x,
124
- DefOverflow )>;
124
+ (MergeOverflow $ovf1, $ovf2) )>;
125
125
126
126
// subi(subi(x, c0), c1) -> subi(x, c0 + c1)
127
127
def SubIRHSSubConstantRHS :
128
128
Pat<(Arith_SubIOp:$res
129
129
(Arith_SubIOp $x, (ConstantLikeMatcher APIntAttr:$c0), $ovf1),
130
130
(ConstantLikeMatcher APIntAttr:$c1), $ovf2),
131
131
(Arith_SubIOp $x, (Arith_ConstantOp (AddIntAttrs $res, $c0, $c1)),
132
- DefOverflow )>;
132
+ (MergeOverflow $ovf1, $ovf2) )>;
133
133
134
134
// subi(subi(c0, x), c1) -> subi(c0 - c1, x)
135
135
def SubIRHSSubConstantLHS :
136
136
Pat<(Arith_SubIOp:$res
137
137
(Arith_SubIOp (ConstantLikeMatcher APIntAttr:$c0), $x, $ovf1),
138
138
(ConstantLikeMatcher APIntAttr:$c1), $ovf2),
139
139
(Arith_SubIOp (Arith_ConstantOp (SubIntAttrs $res, $c0, $c1)), $x,
140
- DefOverflow )>;
140
+ (MergeOverflow $ovf1, $ovf2) )>;
141
141
142
142
// subi(c1, subi(x, c0)) -> subi(c0 + c1, x)
143
143
def SubILHSSubConstantRHS :
144
144
Pat<(Arith_SubIOp:$res
145
145
(ConstantLikeMatcher APIntAttr:$c1),
146
146
(Arith_SubIOp $x, (ConstantLikeMatcher APIntAttr:$c0), $ovf1), $ovf2),
147
147
(Arith_SubIOp (Arith_ConstantOp (AddIntAttrs $res, $c0, $c1)), $x,
148
- DefOverflow )>;
148
+ (MergeOverflow $ovf1, $ovf2) )>;
149
149
150
150
// subi(c1, subi(c0, x)) -> addi(x, c1 - c0)
151
151
def SubILHSSubConstantLHS :
152
152
Pat<(Arith_SubIOp:$res
153
153
(ConstantLikeMatcher APIntAttr:$c1),
154
154
(Arith_SubIOp (ConstantLikeMatcher APIntAttr:$c0), $x, $ovf1), $ovf2),
155
155
(Arith_AddIOp $x, (Arith_ConstantOp (SubIntAttrs $res, $c1, $c0)),
156
- DefOverflow )>;
156
+ (MergeOverflow $ovf1, $ovf2) )>;
157
157
158
158
// subi(subi(a, b), a) -> subi(0, b)
159
159
def SubISubILHSRHSLHS :
160
160
Pat<(Arith_SubIOp:$res (Arith_SubIOp $x, $y, $ovf1), $x, $ovf2),
161
- (Arith_SubIOp (Arith_ConstantOp (GetZeroAttr $y)), $y, DefOverflow)>;
161
+ (Arith_SubIOp (Arith_ConstantOp (GetZeroAttr $y)), $y,
162
+ (MergeOverflow $ovf1, $ovf2))>;
162
163
163
164
//===----------------------------------------------------------------------===//
164
165
// MulSIExtendedOp
0 commit comments