Skip to content

Commit 704808c

Browse files
krzysz00kuhar
andauthored
[mlir][affine] Add static basis support to affine.delinearize (#113846)
This commit makes `affine.delinealize` join other indexing operators, like `vector.extract`, which store a mixed static/dynamic set of sizes, offsets, or such. In this case, the `basis` (the set of values that will be used to decompose the linear index) is now stored as an array of index attributes where the basis is statically known, eliminating the need to cretae constants. This commit also adds copies of the delinearize utility in the affine dialect to allow it to take an array of `OpFoldResult`s and extends te DynamicIndexList parser/printer to allow specifying the delimiters in tablegen (this is needed to avoid breaking existing syntax). --------- Co-authored-by: Jakub Kuderski <[email protected]>
1 parent c949500 commit 704808c

File tree

15 files changed

+193
-151
lines changed

15 files changed

+193
-151
lines changed

mlir/include/mlir/Dialect/Affine/IR/AffineOps.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616

1717
#include "mlir/Dialect/Affine/IR/AffineMemoryOpInterfaces.h"
1818
#include "mlir/Dialect/Arith/IR/Arith.h"
19+
#include "mlir/Dialect/Utils/StaticValueUtils.h"
1920
#include "mlir/IR/AffineMap.h"
2021
#include "mlir/IR/Builders.h"
2122
#include "mlir/Interfaces/ControlFlowInterfaces.h"
2223
#include "mlir/Interfaces/LoopLikeInterface.h"
23-
2424
namespace mlir {
2525
namespace affine {
2626

mlir/include/mlir/Dialect/Affine/IR/AffineOps.td

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,17 +1084,31 @@ def AffineDelinearizeIndexOp : Affine_Op<"delinearize_index",
10841084
```
10851085
}];
10861086

1087-
let arguments = (ins Index:$linear_index, Variadic<Index>:$basis);
1087+
let arguments = (ins Index:$linear_index,
1088+
Variadic<Index>:$dynamic_basis,
1089+
DenseI64ArrayAttr:$static_basis);
10881090
let results = (outs Variadic<Index>:$multi_index);
10891091

10901092
let assemblyFormat = [{
1091-
$linear_index `into` ` ` `(` $basis `)` attr-dict `:` type($multi_index)
1093+
$linear_index `into` ` `
1094+
custom<DynamicIndexList>($dynamic_basis, $static_basis, "::mlir::AsmParser::Delimiter::Paren")
1095+
attr-dict `:` type($multi_index)
10921096
}];
10931097

10941098
let builders = [
1095-
OpBuilder<(ins "Value":$linear_index, "ArrayRef<OpFoldResult>":$basis)>
1099+
OpBuilder<(ins "Value":$linear_index, "ValueRange":$basis)>,
1100+
OpBuilder<(ins "Value":$linear_index, "ArrayRef<OpFoldResult>":$basis)>,
1101+
OpBuilder<(ins "Value":$linear_index, "ArrayRef<int64_t>":$basis)>
10961102
];
10971103

1104+
let extraClassDeclaration = [{
1105+
/// Returns a vector with all the static and dynamic basis values.
1106+
SmallVector<OpFoldResult> getMixedBasis() {
1107+
OpBuilder builder(getContext());
1108+
return ::mlir::getMixedValues(getStaticBasis(), getDynamicBasis(), builder);
1109+
}
1110+
}];
1111+
10981112
let hasVerifier = 1;
10991113
let hasCanonicalizer = 1;
11001114
}

mlir/include/mlir/Dialect/Affine/Utils.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,10 @@ DivModValue getDivMod(OpBuilder &b, Location loc, Value lhs, Value rhs);
311311
FailureOr<SmallVector<Value>> delinearizeIndex(OpBuilder &b, Location loc,
312312
Value linearIndex,
313313
ArrayRef<Value> basis);
314+
315+
FailureOr<SmallVector<Value>> delinearizeIndex(OpBuilder &b, Location loc,
316+
Value linearIndex,
317+
ArrayRef<OpFoldResult> basis);
314318
// Generate IR that extracts the linear index from a multi-index according to
315319
// a basis/shape.
316320
OpFoldResult linearizeIndex(ArrayRef<OpFoldResult> multiIndex,

mlir/include/mlir/Interfaces/ViewLikeInterface.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,13 @@ void printDynamicIndexList(
109109
ArrayRef<int64_t> integers, ArrayRef<bool> scalables,
110110
TypeRange valueTypes = TypeRange(),
111111
AsmParser::Delimiter delimiter = AsmParser::Delimiter::Square);
112+
inline void printDynamicIndexList(OpAsmPrinter &printer, Operation *op,
113+
OperandRange values,
114+
ArrayRef<int64_t> integers,
115+
AsmParser::Delimiter delimiter) {
116+
return printDynamicIndexList(printer, op, values, integers, {}, TypeRange(),
117+
delimiter);
118+
}
112119
inline void printDynamicIndexList(
113120
OpAsmPrinter &printer, Operation *op, OperandRange values,
114121
ArrayRef<int64_t> integers, TypeRange valueTypes = TypeRange(),
@@ -144,6 +151,15 @@ ParseResult parseDynamicIndexList(
144151
DenseI64ArrayAttr &integers, DenseBoolArrayAttr &scalableVals,
145152
SmallVectorImpl<Type> *valueTypes = nullptr,
146153
AsmParser::Delimiter delimiter = AsmParser::Delimiter::Square);
154+
inline ParseResult
155+
parseDynamicIndexList(OpAsmParser &parser,
156+
SmallVectorImpl<OpAsmParser::UnresolvedOperand> &values,
157+
DenseI64ArrayAttr &integers,
158+
AsmParser::Delimiter delimiter) {
159+
DenseBoolArrayAttr scalableVals = {};
160+
return parseDynamicIndexList(parser, values, integers, scalableVals, nullptr,
161+
delimiter);
162+
}
147163
inline ParseResult parseDynamicIndexList(
148164
OpAsmParser &parser,
149165
SmallVectorImpl<OpAsmParser::UnresolvedOperand> &values,

mlir/lib/Dialect/Affine/IR/AffineOps.cpp

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "mlir/Dialect/Affine/IR/AffineValueMap.h"
1111
#include "mlir/Dialect/MemRef/IR/MemRef.h"
1212
#include "mlir/Dialect/UB/IR/UBOps.h"
13+
#include "mlir/Dialect/Utils/StaticValueUtils.h"
1314
#include "mlir/IR/AffineExprVisitor.h"
1415
#include "mlir/IR/IRMapping.h"
1516
#include "mlir/IR/IntegerSet.h"
@@ -4508,32 +4509,50 @@ LogicalResult AffineDelinearizeIndexOp::inferReturnTypes(
45084509
RegionRange regions, SmallVectorImpl<Type> &inferredReturnTypes) {
45094510
AffineDelinearizeIndexOpAdaptor adaptor(operands, attributes, properties,
45104511
regions);
4511-
inferredReturnTypes.assign(adaptor.getBasis().size(),
4512+
inferredReturnTypes.assign(adaptor.getStaticBasis().size(),
45124513
IndexType::get(context));
45134514
return success();
45144515
}
45154516

4516-
void AffineDelinearizeIndexOp::build(OpBuilder &builder, OperationState &result,
4517+
void AffineDelinearizeIndexOp::build(OpBuilder &odsBuilder,
4518+
OperationState &odsState,
4519+
Value linearIndex, ValueRange basis) {
4520+
SmallVector<Value> dynamicBasis;
4521+
SmallVector<int64_t> staticBasis;
4522+
dispatchIndexOpFoldResults(getAsOpFoldResult(basis), dynamicBasis,
4523+
staticBasis);
4524+
build(odsBuilder, odsState, linearIndex, dynamicBasis, staticBasis);
4525+
}
4526+
4527+
void AffineDelinearizeIndexOp::build(OpBuilder &odsBuilder,
4528+
OperationState &odsState,
45174529
Value linearIndex,
45184530
ArrayRef<OpFoldResult> basis) {
4519-
result.addTypes(SmallVector<Type>(basis.size(), builder.getIndexType()));
4520-
result.addOperands(linearIndex);
4521-
SmallVector<Value> basisValues =
4522-
llvm::map_to_vector(basis, [&](OpFoldResult ofr) -> Value {
4523-
std::optional<int64_t> staticDim = getConstantIntValue(ofr);
4524-
if (staticDim.has_value())
4525-
return builder.create<arith::ConstantIndexOp>(result.location,
4526-
*staticDim);
4527-
return llvm::dyn_cast_if_present<Value>(ofr);
4528-
});
4529-
result.addOperands(basisValues);
4531+
SmallVector<Value> dynamicBasis;
4532+
SmallVector<int64_t> staticBasis;
4533+
dispatchIndexOpFoldResults(basis, dynamicBasis, staticBasis);
4534+
build(odsBuilder, odsState, linearIndex, dynamicBasis, staticBasis);
4535+
}
4536+
4537+
void AffineDelinearizeIndexOp::build(OpBuilder &odsBuilder,
4538+
OperationState &odsState,
4539+
Value linearIndex,
4540+
ArrayRef<int64_t> basis) {
4541+
build(odsBuilder, odsState, linearIndex, ValueRange{}, basis);
45304542
}
45314543

45324544
LogicalResult AffineDelinearizeIndexOp::verify() {
4533-
if (getBasis().empty())
4545+
if (getStaticBasis().empty())
45344546
return emitOpError("basis should not be empty");
4535-
if (getNumResults() != getBasis().size())
4547+
if (getNumResults() != getStaticBasis().size())
45364548
return emitOpError("should return an index for each basis element");
4549+
auto dynamicMarkersCount =
4550+
llvm::count_if(getStaticBasis(), ShapedType::isDynamic);
4551+
if (static_cast<size_t>(dynamicMarkersCount) != getDynamicBasis().size())
4552+
return emitOpError(
4553+
"mismatch between dynamic and static basis (kDynamic marker but no "
4554+
"corresponding dynamic basis entry) -- this can only happen due to an "
4555+
"incorrect fold/rewrite");
45374556
return success();
45384557
}
45394558

@@ -4557,15 +4576,16 @@ struct DropUnitExtentBasis
45574576

45584577
// Replace all indices corresponding to unit-extent basis with 0.
45594578
// Remaining basis can be used to get a new `affine.delinearize_index` op.
4560-
SmallVector<Value> newOperands;
4561-
for (auto [index, basis] : llvm::enumerate(delinearizeOp.getBasis())) {
4562-
if (matchPattern(basis, m_One()))
4579+
SmallVector<OpFoldResult> newOperands;
4580+
for (auto [index, basis] : llvm::enumerate(delinearizeOp.getMixedBasis())) {
4581+
std::optional<int64_t> basisVal = getConstantIntValue(basis);
4582+
if (basisVal && *basisVal == 1)
45634583
replacements[index] = getZero();
45644584
else
45654585
newOperands.push_back(basis);
45664586
}
45674587

4568-
if (newOperands.size() == delinearizeOp.getBasis().size())
4588+
if (newOperands.size() == delinearizeOp.getStaticBasis().size())
45694589
return failure();
45704590

45714591
if (!newOperands.empty()) {
@@ -4607,9 +4627,9 @@ struct DropDelinearizeOfSingleLoop
46074627

46084628
LogicalResult matchAndRewrite(affine::AffineDelinearizeIndexOp delinearizeOp,
46094629
PatternRewriter &rewriter) const override {
4610-
auto basis = delinearizeOp.getBasis();
4611-
if (basis.size() != 1)
4630+
if (delinearizeOp.getStaticBasis().size() != 1)
46124631
return failure();
4632+
auto basis = delinearizeOp.getMixedBasis();
46134633

46144634
// Check that the `linear_index` is an induction variable.
46154635
auto inductionVar = dyn_cast<BlockArgument>(delinearizeOp.getLinearIndex());
@@ -4634,7 +4654,7 @@ struct DropDelinearizeOfSingleLoop
46344654
// Check that the upper-bound is the basis.
46354655
auto upperBounds = loopLikeOp.getLoopUpperBounds();
46364656
if (!upperBounds || upperBounds->size() != 1 ||
4637-
upperBounds->front() != getAsOpFoldResult(basis.front())) {
4657+
upperBounds->front() != basis.front()) {
46384658
return rewriter.notifyMatchFailure(delinearizeOp,
46394659
"`basis` is not upper bound");
46404660
}

mlir/lib/Dialect/Affine/Transforms/AffineExpandIndexOps.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,8 @@ struct LowerDelinearizeIndexOps
3535
using OpRewritePattern<AffineDelinearizeIndexOp>::OpRewritePattern;
3636
LogicalResult matchAndRewrite(AffineDelinearizeIndexOp op,
3737
PatternRewriter &rewriter) const override {
38-
FailureOr<SmallVector<Value>> multiIndex =
39-
delinearizeIndex(rewriter, op->getLoc(), op.getLinearIndex(),
40-
llvm::to_vector(op.getBasis()));
38+
FailureOr<SmallVector<Value>> multiIndex = delinearizeIndex(
39+
rewriter, op->getLoc(), op.getLinearIndex(), op.getMixedBasis());
4140
if (failed(multiIndex))
4241
return failure();
4342
rewriter.replaceOp(op, *multiIndex);

mlir/lib/Dialect/Affine/Utils/Utils.cpp

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1931,37 +1931,63 @@ DivModValue mlir::affine::getDivMod(OpBuilder &b, Location loc, Value lhs,
19311931
return result;
19321932
}
19331933

1934-
/// Create IR that computes the product of all elements in the set.
1935-
static FailureOr<OpFoldResult> getIndexProduct(OpBuilder &b, Location loc,
1936-
ArrayRef<Value> set) {
1937-
if (set.empty())
1938-
return failure();
1939-
OpFoldResult result = set[0];
1934+
/// Create an affine map that computes `lhs` * `rhs`, composing in any other
1935+
/// affine maps.
1936+
static FailureOr<OpFoldResult> composedAffineMultiply(OpBuilder &b,
1937+
Location loc,
1938+
OpFoldResult lhs,
1939+
OpFoldResult rhs) {
19401940
AffineExpr s0, s1;
19411941
bindSymbols(b.getContext(), s0, s1);
1942-
for (unsigned i = 1, e = set.size(); i < e; i++)
1943-
result = makeComposedFoldedAffineApply(b, loc, s0 * s1, {result, set[i]});
1944-
return result;
1942+
return makeComposedFoldedAffineApply(b, loc, s0 * s1, {lhs, rhs});
19451943
}
19461944

19471945
FailureOr<SmallVector<Value>>
19481946
mlir::affine::delinearizeIndex(OpBuilder &b, Location loc, Value linearIndex,
19491947
ArrayRef<Value> basis) {
1950-
unsigned numDims = basis.size();
1948+
// Note: the divisors are backwards due to the scan.
1949+
SmallVector<Value> divisors;
1950+
OpFoldResult basisProd = b.getIndexAttr(1);
1951+
for (OpFoldResult basisElem : llvm::reverse(basis.drop_front())) {
1952+
FailureOr<OpFoldResult> nextProd =
1953+
composedAffineMultiply(b, loc, basisElem, basisProd);
1954+
if (failed(nextProd))
1955+
return failure();
1956+
basisProd = *nextProd;
1957+
divisors.push_back(getValueOrCreateConstantIndexOp(b, loc, basisProd));
1958+
}
1959+
1960+
SmallVector<Value> results;
1961+
results.reserve(divisors.size() + 1);
1962+
Value residual = linearIndex;
1963+
for (Value divisor : llvm::reverse(divisors)) {
1964+
DivModValue divMod = getDivMod(b, loc, residual, divisor);
1965+
results.push_back(divMod.quotient);
1966+
residual = divMod.remainder;
1967+
}
1968+
results.push_back(residual);
1969+
return results;
1970+
}
19511971

1972+
FailureOr<SmallVector<Value>>
1973+
mlir::affine::delinearizeIndex(OpBuilder &b, Location loc, Value linearIndex,
1974+
ArrayRef<OpFoldResult> basis) {
1975+
// Note: the divisors are backwards due to the scan.
19521976
SmallVector<Value> divisors;
1953-
for (unsigned i = 1; i < numDims; i++) {
1954-
ArrayRef<Value> slice = basis.drop_front(i);
1955-
FailureOr<OpFoldResult> prod = getIndexProduct(b, loc, slice);
1956-
if (failed(prod))
1977+
OpFoldResult basisProd = b.getIndexAttr(1);
1978+
for (OpFoldResult basisElem : llvm::reverse(basis.drop_front())) {
1979+
FailureOr<OpFoldResult> nextProd =
1980+
composedAffineMultiply(b, loc, basisElem, basisProd);
1981+
if (failed(nextProd))
19571982
return failure();
1958-
divisors.push_back(getValueOrCreateConstantIndexOp(b, loc, *prod));
1983+
basisProd = *nextProd;
1984+
divisors.push_back(getValueOrCreateConstantIndexOp(b, loc, basisProd));
19591985
}
19601986

19611987
SmallVector<Value> results;
19621988
results.reserve(divisors.size() + 1);
19631989
Value residual = linearIndex;
1964-
for (Value divisor : divisors) {
1990+
for (Value divisor : llvm::reverse(divisors)) {
19651991
DivModValue divMod = getDivMod(b, loc, residual, divisor);
19661992
results.push_back(divMod.quotient);
19671993
residual = divMod.remainder;

mlir/test/Conversion/AffineToStandard/lower-affine.mlir

Lines changed: 40 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -931,53 +931,48 @@ func.func @affine_parallel_with_reductions_i64(%arg0: memref<3x3xi64>, %arg1: me
931931
///////////////////////////////////////////////////////////////////////
932932

933933
func.func @test_dilinearize_index(%linear_index: index) -> (index, index, index) {
934-
%b0 = arith.constant 16 : index
935-
%b1 = arith.constant 224 : index
936-
%b2 = arith.constant 224 : index
937-
%1:3 = affine.delinearize_index %linear_index into (%b0, %b1, %b2) : index, index, index
934+
%1:3 = affine.delinearize_index %linear_index into (16, 224, 224) : index, index, index
938935
return %1#0, %1#1, %1#2 : index, index, index
939936
}
940937
// CHECK-LABEL: func.func @test_dilinearize_index(
941938
// CHECK-SAME: %[[VAL_0:.*]]: index) -> (index, index, index) {
942-
// CHECK: %[[VAL_1:.*]] = arith.constant 16 : index
943-
// CHECK: %[[VAL_2:.*]] = arith.constant 224 : index
944-
// CHECK: %[[VAL_3:.*]] = arith.constant 224 : index
945-
// CHECK: %[[VAL_4:.*]] = arith.constant 50176 : index
946-
// CHECK: %[[VAL_5:.*]] = arith.constant 50176 : index
947-
// CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
948-
// CHECK: %[[VAL_7:.*]] = arith.constant -1 : index
949-
// CHECK: %[[VAL_8:.*]] = arith.cmpi slt, %[[VAL_0]], %[[VAL_6]] : index
950-
// CHECK: %[[VAL_9:.*]] = arith.subi %[[VAL_7]], %[[VAL_0]] : index
951-
// CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_8]], %[[VAL_9]], %[[VAL_0]] : index
952-
// CHECK: %[[VAL_11:.*]] = arith.divsi %[[VAL_10]], %[[VAL_5]] : index
953-
// CHECK: %[[VAL_12:.*]] = arith.subi %[[VAL_7]], %[[VAL_11]] : index
954-
// CHECK: %[[VAL_13:.*]] = arith.select %[[VAL_8]], %[[VAL_12]], %[[VAL_11]] : index
955-
// CHECK: %[[VAL_14:.*]] = arith.constant 50176 : index
956-
// CHECK: %[[VAL_15:.*]] = arith.remsi %[[VAL_0]], %[[VAL_14]] : index
957-
// CHECK: %[[VAL_16:.*]] = arith.constant 0 : index
958-
// CHECK: %[[VAL_17:.*]] = arith.cmpi slt, %[[VAL_15]], %[[VAL_16]] : index
959-
// CHECK: %[[VAL_18:.*]] = arith.addi %[[VAL_15]], %[[VAL_14]] : index
960-
// CHECK: %[[VAL_19:.*]] = arith.select %[[VAL_17]], %[[VAL_18]], %[[VAL_15]] : index
961-
// CHECK: %[[VAL_20:.*]] = arith.constant 50176 : index
962-
// CHECK: %[[VAL_21:.*]] = arith.remsi %[[VAL_0]], %[[VAL_20]] : index
963-
// CHECK: %[[VAL_22:.*]] = arith.constant 0 : index
964-
// CHECK: %[[VAL_23:.*]] = arith.cmpi slt, %[[VAL_21]], %[[VAL_22]] : index
965-
// CHECK: %[[VAL_24:.*]] = arith.addi %[[VAL_21]], %[[VAL_20]] : index
966-
// CHECK: %[[VAL_25:.*]] = arith.select %[[VAL_23]], %[[VAL_24]], %[[VAL_21]] : index
967-
// CHECK: %[[VAL_26:.*]] = arith.constant 224 : index
968-
// CHECK: %[[VAL_27:.*]] = arith.constant 0 : index
969-
// CHECK: %[[VAL_28:.*]] = arith.constant -1 : index
970-
// CHECK: %[[VAL_29:.*]] = arith.cmpi slt, %[[VAL_25]], %[[VAL_27]] : index
971-
// CHECK: %[[VAL_30:.*]] = arith.subi %[[VAL_28]], %[[VAL_25]] : index
972-
// CHECK: %[[VAL_31:.*]] = arith.select %[[VAL_29]], %[[VAL_30]], %[[VAL_25]] : index
973-
// CHECK: %[[VAL_32:.*]] = arith.divsi %[[VAL_31]], %[[VAL_26]] : index
974-
// CHECK: %[[VAL_33:.*]] = arith.subi %[[VAL_28]], %[[VAL_32]] : index
975-
// CHECK: %[[VAL_34:.*]] = arith.select %[[VAL_29]], %[[VAL_33]], %[[VAL_32]] : index
976-
// CHECK: %[[VAL_35:.*]] = arith.constant 224 : index
977-
// CHECK: %[[VAL_36:.*]] = arith.remsi %[[VAL_0]], %[[VAL_35]] : index
978-
// CHECK: %[[VAL_37:.*]] = arith.constant 0 : index
979-
// CHECK: %[[VAL_38:.*]] = arith.cmpi slt, %[[VAL_36]], %[[VAL_37]] : index
980-
// CHECK: %[[VAL_39:.*]] = arith.addi %[[VAL_36]], %[[VAL_35]] : index
981-
// CHECK: %[[VAL_40:.*]] = arith.select %[[VAL_38]], %[[VAL_39]], %[[VAL_36]] : index
982-
// CHECK: return %[[VAL_13]], %[[VAL_34]], %[[VAL_40]] : index, index, index
939+
// CHECK: %[[VAL_1:.*]] = arith.constant 224 : index
940+
// CHECK: %[[VAL_2:.*]] = arith.constant 50176 : index
941+
// CHECK: %[[VAL_3:.*]] = arith.constant 50176 : index
942+
// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
943+
// CHECK: %[[VAL_5:.*]] = arith.constant -1 : index
944+
// CHECK: %[[VAL_6:.*]] = arith.cmpi slt, %[[VAL_0]], %[[VAL_4]] : index
945+
// CHECK: %[[VAL_7:.*]] = arith.subi %[[VAL_5]], %[[VAL_0]] : index
946+
// CHECK: %[[VAL_8:.*]] = arith.select %[[VAL_6]], %[[VAL_7]], %[[VAL_0]] : index
947+
// CHECK: %[[VAL_9:.*]] = arith.divsi %[[VAL_8]], %[[VAL_3]] : index
948+
// CHECK: %[[VAL_10:.*]] = arith.subi %[[VAL_5]], %[[VAL_9]] : index
949+
// CHECK: %[[VAL_11:.*]] = arith.select %[[VAL_6]], %[[VAL_10]], %[[VAL_9]] : index
950+
// CHECK: %[[VAL_12:.*]] = arith.constant 50176 : index
951+
// CHECK: %[[VAL_13:.*]] = arith.remsi %[[VAL_0]], %[[VAL_12]] : index
952+
// CHECK: %[[VAL_14:.*]] = arith.constant 0 : index
953+
// CHECK: %[[VAL_15:.*]] = arith.cmpi slt, %[[VAL_13]], %[[VAL_14]] : index
954+
// CHECK: %[[VAL_16:.*]] = arith.addi %[[VAL_13]], %[[VAL_12]] : index
955+
// CHECK: %[[VAL_17:.*]] = arith.select %[[VAL_15]], %[[VAL_16]], %[[VAL_13]] : index
956+
// CHECK: %[[VAL_18:.*]] = arith.constant 50176 : index
957+
// CHECK: %[[VAL_19:.*]] = arith.remsi %[[VAL_0]], %[[VAL_18]] : index
958+
// CHECK: %[[VAL_20:.*]] = arith.constant 0 : index
959+
// CHECK: %[[VAL_21:.*]] = arith.cmpi slt, %[[VAL_19]], %[[VAL_20]] : index
960+
// CHECK: %[[VAL_22:.*]] = arith.addi %[[VAL_19]], %[[VAL_18]] : index
961+
// CHECK: %[[VAL_23:.*]] = arith.select %[[VAL_21]], %[[VAL_22]], %[[VAL_19]] : index
962+
// CHECK: %[[VAL_24:.*]] = arith.constant 224 : index
963+
// CHECK: %[[VAL_25:.*]] = arith.constant 0 : index
964+
// CHECK: %[[VAL_26:.*]] = arith.constant -1 : index
965+
// CHECK: %[[VAL_27:.*]] = arith.cmpi slt, %[[VAL_23]], %[[VAL_25]] : index
966+
// CHECK: %[[VAL_28:.*]] = arith.subi %[[VAL_26]], %[[VAL_23]] : index
967+
// CHECK: %[[VAL_29:.*]] = arith.select %[[VAL_27]], %[[VAL_28]], %[[VAL_23]] : index
968+
// CHECK: %[[VAL_30:.*]] = arith.divsi %[[VAL_29]], %[[VAL_24]] : index
969+
// CHECK: %[[VAL_31:.*]] = arith.subi %[[VAL_26]], %[[VAL_30]] : index
970+
// CHECK: %[[VAL_32:.*]] = arith.select %[[VAL_27]], %[[VAL_31]], %[[VAL_30]] : index
971+
// CHECK: %[[VAL_33:.*]] = arith.constant 224 : index
972+
// CHECK: %[[VAL_34:.*]] = arith.remsi %[[VAL_0]], %[[VAL_33]] : index
973+
// CHECK: %[[VAL_35:.*]] = arith.constant 0 : index
974+
// CHECK: %[[VAL_36:.*]] = arith.cmpi slt, %[[VAL_34]], %[[VAL_35]] : index
975+
// CHECK: %[[VAL_37:.*]] = arith.addi %[[VAL_34]], %[[VAL_33]] : index
976+
// CHECK: %[[VAL_38:.*]] = arith.select %[[VAL_36]], %[[VAL_37]], %[[VAL_34]] : index
977+
// CHECK: return %[[VAL_11]], %[[VAL_32]], %[[VAL_38]] : index, index, index
983978
// CHECK: }

0 commit comments

Comments
 (0)