Skip to content

Commit b1eb021

Browse files
authored
Merge pull request #163 from Xilinx/corentin.cmpf
[FXML-4414] Implement leftover variants of cmpf
2 parents 0cc0844 + 3c8dc44 commit b1eb021

File tree

3 files changed

+168
-25
lines changed

3 files changed

+168
-25
lines changed

mlir/lib/Conversion/ArithToEmitC/ArithToEmitC.cpp

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,41 @@ class CmpFOpConversion : public OpConversionPattern<arith::CmpFOp> {
9696
bool unordered = false;
9797
emitc::CmpPredicate predicate;
9898
switch (op.getPredicate()) {
99+
case arith::CmpFPredicate::AlwaysFalse: {
100+
auto constant = rewriter.create<emitc::ConstantOp>(
101+
op.getLoc(), rewriter.getI1Type(),
102+
rewriter.getBoolAttr(/*value=*/false));
103+
rewriter.replaceOp(op, constant);
104+
return success();
105+
}
106+
case arith::CmpFPredicate::OEQ:
107+
unordered = false;
108+
predicate = emitc::CmpPredicate::eq;
109+
break;
110+
case arith::CmpFPredicate::OGT:
111+
// ordered and greater than
112+
unordered = false;
113+
predicate = emitc::CmpPredicate::gt;
114+
break;
115+
case arith::CmpFPredicate::OGE:
116+
unordered = false;
117+
predicate = emitc::CmpPredicate::ge;
118+
break;
119+
case arith::CmpFPredicate::OLT:
120+
unordered = false;
121+
predicate = emitc::CmpPredicate::lt;
122+
break;
123+
case arith::CmpFPredicate::ONE:
124+
unordered = false;
125+
predicate = emitc::CmpPredicate::ne;
126+
break;
127+
case arith::CmpFPredicate::ORD: {
128+
// ordered, i.e. none of the operands is NaN
129+
auto cmp = createCheckIsOrdered(rewriter, op.getLoc(), adaptor.getLhs(),
130+
adaptor.getRhs());
131+
rewriter.replaceOp(op, cmp);
132+
return success();
133+
}
99134
case arith::CmpFPredicate::UEQ:
100135
// unordered or equal
101136
unordered = true;
@@ -121,18 +156,24 @@ class CmpFOpConversion : public OpConversionPattern<arith::CmpFOp> {
121156
unordered = true;
122157
predicate = emitc::CmpPredicate::le;
123158
break;
159+
case arith::CmpFPredicate::UNE:
160+
unordered = true;
161+
predicate = emitc::CmpPredicate::ne;
162+
break;
124163
case arith::CmpFPredicate::UNO: {
125164
// unordered, i.e. either operand is nan
126165
auto cmp = createCheckIsUnordered(rewriter, op.getLoc(), adaptor.getLhs(),
127166
adaptor.getRhs());
128167
rewriter.replaceOp(op, cmp);
129168
return success();
130169
}
131-
case arith::CmpFPredicate::OGT:
132-
// ordered and greater than
133-
unordered = false;
134-
predicate = emitc::CmpPredicate::gt;
135-
break;
170+
case arith::CmpFPredicate::AlwaysTrue: {
171+
auto constant = rewriter.create<emitc::ConstantOp>(
172+
op.getLoc(), rewriter.getI1Type(),
173+
rewriter.getBoolAttr(/*value=*/true));
174+
rewriter.replaceOp(op, constant);
175+
return success();
176+
}
136177
default:
137178
return rewriter.notifyMatchFailure(op.getLoc(),
138179
"cannot match predicate ");

mlir/test/Conversion/ArithToEmitC/arith-to-emitc-unsupported.mlir

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,6 @@ func.func @arith_cmpf_vector(%arg0: vector<5xf32>, %arg1: vector<5xf32>) -> vect
1616

1717
// -----
1818

19-
func.func @arith_cmpf_ordered(%arg0: f32, %arg1: f32) -> i1 {
20-
// expected-error @+1 {{failed to legalize operation 'arith.cmpf'}}
21-
%oge = arith.cmpf oge, %arg0, %arg1 : f32
22-
return %oge: i1
23-
}
24-
25-
// -----
26-
2719
func.func @arith_cast_f32(%arg0: f32) -> i32 {
2820
// expected-error @+1 {{failed to legalize operation 'arith.fptosi'}}
2921
%t = arith.fptosi %arg0 : f32 to i32

mlir/test/Conversion/ArithToEmitC/arith-to-emitc.mlir

Lines changed: 122 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,105 @@ func.func @arith_select(%arg0: i1, %arg1: tensor<8xi32>, %arg2: tensor<8xi32>) -
6262

6363
// -----
6464

65+
func.func @arith_cmpf_false(%arg0: f32, %arg1: f32) -> i1 {
66+
// CHECK-LABEL: arith_cmpf_false
67+
// CHECK-SAME: ([[Arg0:[^ ]*]]: f32, [[Arg1:[^ ]*]]: f32)
68+
// CHECK-DAG: [[False:[^ ]*]] = "emitc.constant"() <{value = false}> : () -> i1
69+
%ueq = arith.cmpf false, %arg0, %arg1 : f32
70+
// CHECK: return [[False]]
71+
return %ueq: i1
72+
}
73+
74+
// -----
75+
76+
func.func @arith_cmpf_oeq(%arg0: f32, %arg1: f32) -> i1 {
77+
// CHECK-LABEL: arith_cmpf_oeq
78+
// CHECK-SAME: ([[Arg0:[^ ]*]]: f32, [[Arg1:[^ ]*]]: f32)
79+
// CHECK-DAG: [[EQ:[^ ]*]] = emitc.cmp eq, [[Arg0]], [[Arg1]] : (f32, f32) -> i1
80+
// CHECK-DAG: [[NaNArg0:[^ ]*]] = emitc.cmp eq, [[Arg0]], [[Arg0]] : (f32, f32) -> i1
81+
// CHECK-DAG: [[NaNArg1:[^ ]*]] = emitc.cmp eq, [[Arg1]], [[Arg1]] : (f32, f32) -> i1
82+
// CHECK-DAG: [[Ordered:[^ ]*]] = emitc.logical_and [[NaNArg0]], [[NaNArg1]] : i1, i1
83+
// CHECK-DAG: [[OEQ:[^ ]*]] = emitc.logical_and [[Ordered]], [[EQ]] : i1, i1
84+
%ueq = arith.cmpf oeq, %arg0, %arg1 : f32
85+
// CHECK: return [[OEQ]]
86+
return %ueq: i1
87+
}
88+
89+
// -----
90+
91+
func.func @arith_cmpf_ogt(%arg0: f32, %arg1: f32) -> i1 {
92+
// CHECK-LABEL: arith_cmpf_ogt
93+
// CHECK-SAME: ([[Arg0:[^ ]*]]: f32, [[Arg1:[^ ]*]]: f32)
94+
// CHECK-DAG: [[GT:[^ ]*]] = emitc.cmp gt, [[Arg0]], [[Arg1]] : (f32, f32) -> i1
95+
// CHECK-DAG: [[OrderedArg0:[^ ]*]] = emitc.cmp eq, [[Arg0]], [[Arg0]] : (f32, f32) -> i1
96+
// CHECK-DAG: [[OrderedArg1:[^ ]*]] = emitc.cmp eq, [[Arg1]], [[Arg1]] : (f32, f32) -> i1
97+
// CHECK-DAG: [[Ordered:[^ ]*]] = emitc.logical_and [[OrderedArg0]], [[OrderedArg1]] : i1, i1
98+
// CHECK-DAG: [[OGT:[^ ]*]] = emitc.logical_and [[Ordered]], [[GT]] : i1, i1
99+
%ogt = arith.cmpf ogt, %arg0, %arg1 : f32
100+
// CHECK: return [[OGT]]
101+
return %ogt: i1
102+
}
103+
104+
// -----
105+
106+
func.func @arith_cmpf_oge(%arg0: f32, %arg1: f32) -> i1 {
107+
// CHECK-LABEL: arith_cmpf_oge
108+
// CHECK-SAME: ([[Arg0:[^ ]*]]: f32, [[Arg1:[^ ]*]]: f32)
109+
// CHECK-DAG: [[GE:[^ ]*]] = emitc.cmp ge, [[Arg0]], [[Arg1]] : (f32, f32) -> i1
110+
// CHECK-DAG: [[NaNArg0:[^ ]*]] = emitc.cmp eq, [[Arg0]], [[Arg0]] : (f32, f32) -> i1
111+
// CHECK-DAG: [[NaNArg1:[^ ]*]] = emitc.cmp eq, [[Arg1]], [[Arg1]] : (f32, f32) -> i1
112+
// CHECK-DAG: [[Ordered:[^ ]*]] = emitc.logical_and [[NaNArg0]], [[NaNArg1]] : i1, i1
113+
// CHECK-DAG: [[OGE:[^ ]*]] = emitc.logical_and [[Ordered]], [[GE]] : i1, i1
114+
%ueq = arith.cmpf oge, %arg0, %arg1 : f32
115+
// CHECK: return [[OGE]]
116+
return %ueq: i1
117+
}
118+
119+
// -----
120+
121+
func.func @arith_cmpf_olt(%arg0: f32, %arg1: f32) -> i1 {
122+
// CHECK-LABEL: arith_cmpf_olt
123+
// CHECK-SAME: ([[Arg0:[^ ]*]]: f32, [[Arg1:[^ ]*]]: f32)
124+
// CHECK-DAG: [[LT:[^ ]*]] = emitc.cmp lt, [[Arg0]], [[Arg1]] : (f32, f32) -> i1
125+
// CHECK-DAG: [[NaNArg0:[^ ]*]] = emitc.cmp eq, [[Arg0]], [[Arg0]] : (f32, f32) -> i1
126+
// CHECK-DAG: [[NaNArg1:[^ ]*]] = emitc.cmp eq, [[Arg1]], [[Arg1]] : (f32, f32) -> i1
127+
// CHECK-DAG: [[Ordered:[^ ]*]] = emitc.logical_and [[NaNArg0]], [[NaNArg1]] : i1, i1
128+
// CHECK-DAG: [[UEQ:[^ ]*]] = emitc.logical_and [[Ordered]], [[LT]] : i1, i1
129+
%ueq = arith.cmpf olt, %arg0, %arg1 : f32
130+
// CHECK: return [[UEQ]]
131+
return %ueq: i1
132+
}
133+
134+
// -----
135+
136+
func.func @arith_cmpf_one(%arg0: f32, %arg1: f32) -> i1 {
137+
// CHECK-LABEL: arith_cmpf_one
138+
// CHECK-SAME: ([[Arg0:[^ ]*]]: f32, [[Arg1:[^ ]*]]: f32)
139+
// CHECK-DAG: [[NEQ:[^ ]*]] = emitc.cmp ne, [[Arg0]], [[Arg1]] : (f32, f32) -> i1
140+
// CHECK-DAG: [[NaNArg0:[^ ]*]] = emitc.cmp eq, [[Arg0]], [[Arg0]] : (f32, f32) -> i1
141+
// CHECK-DAG: [[NaNArg1:[^ ]*]] = emitc.cmp eq, [[Arg1]], [[Arg1]] : (f32, f32) -> i1
142+
// CHECK-DAG: [[Ordered:[^ ]*]] = emitc.logical_and [[NaNArg0]], [[NaNArg1]] : i1, i1
143+
// CHECK-DAG: [[ONE:[^ ]*]] = emitc.logical_and [[Ordered]], [[NEQ]] : i1, i1
144+
%ueq = arith.cmpf one, %arg0, %arg1 : f32
145+
// CHECK: return [[ONE]]
146+
return %ueq: i1
147+
}
148+
149+
// -----
150+
151+
func.func @arith_cmpf_ord(%arg0: f32, %arg1: f32) -> i1 {
152+
// CHECK-LABEL: arith_cmpf_ord
153+
// CHECK-SAME: ([[Arg0:[^ ]*]]: f32, [[Arg1:[^ ]*]]: f32)
154+
// CHECK-DAG: [[NaNArg0:[^ ]*]] = emitc.cmp eq, [[Arg0]], [[Arg0]] : (f32, f32) -> i1
155+
// CHECK-DAG: [[NaNArg1:[^ ]*]] = emitc.cmp eq, [[Arg1]], [[Arg1]] : (f32, f32) -> i1
156+
// CHECK-DAG: [[Ordered:[^ ]*]] = emitc.logical_and [[NaNArg0]], [[NaNArg1]] : i1, i1
157+
%ueq = arith.cmpf ord, %arg0, %arg1 : f32
158+
// CHECK: return [[Ordered]]
159+
return %ueq: i1
160+
}
161+
162+
// -----
163+
65164
func.func @arith_cmpf_ueq(%arg0: f32, %arg1: f32) -> i1 {
66165
// CHECK-LABEL: arith_cmpf_ueq
67166
// CHECK-SAME: ([[Arg0:[^ ]*]]: f32, [[Arg1:[^ ]*]]: f32)
@@ -137,30 +236,41 @@ func.func @arith_cmpf_ule(%arg0: f32, %arg1: f32) -> i1 {
137236

138237
// -----
139238

239+
func.func @arith_cmpf_une(%arg0: f32, %arg1: f32) -> i1 {
240+
// CHECK-LABEL: arith_cmpf_une
241+
// CHECK-SAME: ([[Arg0:[^ ]*]]: f32, [[Arg1:[^ ]*]]: f32)
242+
// CHECK-DAG: [[NEQ:[^ ]*]] = emitc.cmp ne, [[Arg0]], [[Arg1]] : (f32, f32) -> i1
243+
// CHECK-DAG: [[NaNArg0:[^ ]*]] = emitc.cmp ne, [[Arg0]], [[Arg0]] : (f32, f32) -> i1
244+
// CHECK-DAG: [[NaNArg1:[^ ]*]] = emitc.cmp ne, [[Arg1]], [[Arg1]] : (f32, f32) -> i1
245+
// CHECK-DAG: [[Unordered:[^ ]*]] = emitc.logical_or [[NaNArg0]], [[NaNArg1]] : i1, i1
246+
// CHECK-DAG: [[UNE:[^ ]*]] = emitc.logical_or [[Unordered]], [[NEQ]] : i1, i1
247+
%une = arith.cmpf une, %arg0, %arg1 : f32
248+
// CHECK: return [[UNE]]
249+
return %une: i1
250+
}
251+
252+
// -----
253+
140254
func.func @arith_cmpf_uno(%arg0: f32, %arg1: f32) -> i1 {
141255
// CHECK-LABEL: arith_cmpf_uno
142256
// CHECK-SAME: ([[Arg0:[^ ]*]]: f32, [[Arg1:[^ ]*]]: f32)
143257
// CHECK-DAG: [[NaNArg0:[^ ]*]] = emitc.cmp ne, [[Arg0]], [[Arg0]] : (f32, f32) -> i1
144258
// CHECK-DAG: [[NaNArg1:[^ ]*]] = emitc.cmp ne, [[Arg1]], [[Arg1]] : (f32, f32) -> i1
145259
// CHECK-DAG: [[Unordered:[^ ]*]] = emitc.logical_or [[NaNArg0]], [[NaNArg1]] : i1, i1
146-
%2 = arith.cmpf uno, %arg0, %arg1 : f32
260+
%uno = arith.cmpf uno, %arg0, %arg1 : f32
147261
// CHECK: return [[Unordered]]
148-
return %2: i1
262+
return %uno: i1
149263
}
150264

151265
// -----
152266

153-
func.func @arith_cmpf_ogt(%arg0: f32, %arg1: f32) -> i1 {
154-
// CHECK-LABEL: arith_cmpf_ogt
267+
func.func @arith_cmpf_true(%arg0: f32, %arg1: f32) -> i1 {
268+
// CHECK-LABEL: arith_cmpf_true
155269
// CHECK-SAME: ([[Arg0:[^ ]*]]: f32, [[Arg1:[^ ]*]]: f32)
156-
// CHECK-DAG: [[GT:[^ ]*]] = emitc.cmp gt, [[Arg0]], [[Arg1]] : (f32, f32) -> i1
157-
// CHECK-DAG: [[OrderedArg0:[^ ]*]] = emitc.cmp eq, [[Arg0]], [[Arg0]] : (f32, f32) -> i1
158-
// CHECK-DAG: [[OrderedArg1:[^ ]*]] = emitc.cmp eq, [[Arg1]], [[Arg1]] : (f32, f32) -> i1
159-
// CHECK-DAG: [[Ordered:[^ ]*]] = emitc.logical_and [[OrderedArg0]], [[OrderedArg1]] : i1, i1
160-
// CHECK-DAG: [[OGT:[^ ]*]] = emitc.logical_and [[Ordered]], [[GT]] : i1, i1
161-
%ule = arith.cmpf ogt, %arg0, %arg1 : f32
162-
// CHECK: return [[OGT]]
163-
return %ule: i1
270+
// CHECK-DAG: [[True:[^ ]*]] = "emitc.constant"() <{value = true}> : () -> i1
271+
%ueq = arith.cmpf true, %arg0, %arg1 : f32
272+
// CHECK: return [[True]]
273+
return %ueq: i1
164274
}
165275

166276
// -----

0 commit comments

Comments
 (0)