Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FXML-4614] Add EmitC index types, lower arith.index_cast, arith.index_castui #183

Merged
merged 27 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
f8c754c
Add EmitC types for indices
cferry-AMD May 7, 2024
8468027
TranslateToCpp emit types
cferry-AMD May 10, 2024
5803f48
Add type converter
cferry-AMD May 10, 2024
49b27f6
Draft: Type converter & tests
cferry-AMD May 10, 2024
3578257
Fix missing symbol dep
cferry-AMD May 13, 2024
1e4dbf1
Issue the new type correctly
cferry-AMD May 13, 2024
bf70671
Play around with type converter, attempting to convert value
cferry-AMD May 13, 2024
de9fff6
Don't convert value, add hack to accept diverging attr type
cferry-AMD May 14, 2024
6a04667
Rename types
cferry-AMD May 14, 2024
590611d
Incorporate trunci upstreaming changes
cferry-AMD May 14, 2024
9639d1f
Add index_cast support, add/sub/mul index ops broken
cferry-AMD May 14, 2024
dd54066
Convert types of constants, fix arith ops test
cferry-AMD May 14, 2024
fae6c49
Remove hack comment, proper way
cferry-AMD May 14, 2024
8dc639c
handle cmpi ops
cferry-AMD May 14, 2024
76d21c1
Add predicates to filter only index types
cferry-AMD May 14, 2024
85a8255
Fix error messages
cferry-AMD May 14, 2024
6bcb8f6
Remove type converter test, already tested in ArithToEmitC
cferry-AMD May 14, 2024
e86a2dc
Review comments, try to fix linker issue on CI
cferry-AMD May 14, 2024
9e7be39
Remove EmitC_SizeType
cferry-AMD May 14, 2024
378a55b
ArithToEmitC depends on EmitCTransforms
cferry-AMD May 15, 2024
9cec233
Factor in type signedness & value type adaptation
cferry-AMD May 15, 2024
59ae2c9
Remove redundant type checks, EmitCTypes includes our new types
cferry-AMD May 15, 2024
c93adb3
Comments
cferry-AMD May 15, 2024
a9348c3
Nits
cferry-AMD May 15, 2024
78f8460
Review comments
cferry-AMD May 15, 2024
ff6dcb8
Add cast op folder
cferry-AMD May 15, 2024
e284808
Handle to-bool cast conversions
cferry-AMD May 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ class EmitC_BinaryOp<string mnemonic, list<Trait> traits = []> :
def CExpression : NativeOpTrait<"emitc::CExpression">;

// Types only used in binary arithmetic operations.
def IntegerIndexOrOpaqueType : AnyTypeOf<[EmitCIntegerType, Index, EmitC_OpaqueType]>;
def IntegerIndexOrOpaqueType : AnyTypeOf<[EmitCIntegerType, Index,
EmitC_SignedSizeType, EmitC_UnsignedSizeType, EmitC_OpaqueType]>;
def FloatIntegerIndexOrOpaqueType : AnyTypeOf<[EmitCFloatType, IntegerIndexOrOpaqueType]>;

def EmitC_AddOp : EmitC_BinaryOp<"add", [CExpression]> {
Expand Down Expand Up @@ -470,7 +471,7 @@ def EmitC_ForOp : EmitC_Op<"for",
upper bound and step respectively, and defines an SSA value for its
induction variable. It has one region capturing the loop body. The induction
variable is represented as an argument of this region. This SSA value is a
signless integer or index. The step is a value of same type.
signless integer, or an index. The step is a value of same type.

This operation has no result. The body region must contain exactly one block
that terminates with `emitc.yield`. Calling ForOp::build will create such a
Expand Down Expand Up @@ -1242,7 +1243,7 @@ def EmitC_SubscriptOp : EmitC_Op<"subscript", []> {
EmitC_OpaqueType,
EmitC_PointerType]>,
"the value to subscript">:$value,
Variadic<EmitCType>:$indices);
Variadic<AnyTypeOf<[EmitCType, EmitC_SignedSizeType, EmitC_UnsignedSizeType]>>:$indices);
let results = (outs EmitCType:$result);

let builders = [
Expand Down
12 changes: 12 additions & 0 deletions mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,16 @@ def EmitC_PointerType : EmitC_Type<"Pointer", "ptr"> {
let assemblyFormat = "`<` qualified($pointee) `>`";
}

class EmitC_SizeType<string name, string typeMnemonic, list<Trait> traits = []>
mgehre-amd marked this conversation as resolved.
Show resolved Hide resolved
: EmitC_Type<name, typeMnemonic, traits> {
}

def EmitC_SignedSizeType : EmitC_SizeType<"SignedSize", "ssize_t"> {
let summary = "EmitC signed size type";
}

def EmitC_UnsignedSizeType : EmitC_SizeType<"UnsignedSize", "usize_t"> {
cferry-AMD marked this conversation as resolved.
Show resolved Hide resolved
let summary = "EmitC unsigned size type";
}

#endif // MLIR_DIALECT_EMITC_IR_EMITCTYPES
11 changes: 11 additions & 0 deletions mlir/include/mlir/Dialect/EmitC/Transforms/TypeConversions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//===- TypeConversions.h - Convert signless types into C/C++ types -------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "mlir/Transforms/DialectConversion.h"

void populateEmitCSizeTypeConversionPatterns(mlir::TypeConverter &converter);
12 changes: 9 additions & 3 deletions mlir/lib/Conversion/ArithToEmitC/ArithToEmitC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/EmitC/IR/EmitC.h"
#include "mlir/Dialect/EmitC/Transforms/TypeConversions.h"
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/Support/LogicalResult.h"
Expand Down Expand Up @@ -284,7 +285,8 @@ class CastConversion : public OpConversionPattern<ArithOp> {
ConversionPatternRewriter &rewriter) const override {

Type opReturnType = this->getTypeConverter()->convertType(op.getType());
if (!isa_and_nonnull<IntegerType>(opReturnType)) {
if (!isa_and_nonnull<IntegerType, emitc::SignedSizeType,
emitc::UnsignedSizeType>(opReturnType)) {
return rewriter.notifyMatchFailure(op, "expected integer result type");
}

Expand All @@ -294,7 +296,8 @@ class CastConversion : public OpConversionPattern<ArithOp> {
}

Type operandType = adaptor.getIn().getType();
if (!isa_and_nonnull<IntegerType>(operandType)) {
if (!isa_and_nonnull<IntegerType, emitc::SignedSizeType,
emitc::UnsignedSizeType>(operandType)) {
return rewriter.notifyMatchFailure(op, "expected integer operand type");
}

Expand All @@ -306,7 +309,8 @@ class CastConversion : public OpConversionPattern<ArithOp> {
// For int conversions: if the op is a ui variant and the type wanted as
// return type isn't unsigned, we need to issue an unsigned type to do
// the conversion.
if (castType.isUnsignedInteger() != doUnsigned) {
if ((isa<emitc::UnsignedSizeType>(castType) ||
castType.isUnsignedInteger()) != doUnsigned) {
castType = rewriter.getIntegerType(opReturnType.getIntOrFloatBitWidth(),
/*isSigned=*/!doUnsigned);
}
Expand Down Expand Up @@ -535,6 +539,8 @@ void mlir::populateArithToEmitCPatterns(TypeConverter &typeConverter,
RewritePatternSet &patterns) {
MLIRContext *ctx = patterns.getContext();

// populateEmitCSizeTypeConversionPatterns(typeConverter);

// clang-format off
patterns.add<
ArithConstantOpConversionPattern,
Expand Down
3 changes: 2 additions & 1 deletion mlir/lib/Dialect/EmitC/IR/EmitC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ bool mlir::emitc::isSupportedIntegerType(Type type) {
}

bool mlir::emitc::isIntegerIndexOrOpaqueType(Type type) {
return llvm::isa<IndexType, emitc::OpaqueType>(type) ||
return llvm::isa<IndexType, emitc::SignedSizeType, emitc::UnsignedSizeType,
emitc::OpaqueType>(type) ||
isSupportedIntegerType(type);
}

Expand Down
1 change: 1 addition & 0 deletions mlir/lib/Dialect/EmitC/Transforms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ add_mlir_dialect_library(MLIREmitCTransforms
Transforms.cpp
FormExpressions.cpp
EliminateLibm.cpp
TypeConversions.cpp

ADDITIONAL_HEADER_DIRS
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/EmitC/Transforms
Expand Down
18 changes: 18 additions & 0 deletions mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===- TypeConversions.cpp - Convert signless types into C/C++ types ------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "mlir/Dialect/EmitC/Transforms/TypeConversions.h"
#include "mlir/Dialect/EmitC/IR/EmitC.h"
#include "mlir/IR/BuiltinTypes.h"

using namespace mlir;

void populateEmitCSizeTypeConversionPatterns(TypeConverter &converter) {
converter.addConversion(
[](IndexType type) { return emitc::UnsignedSizeType(); });
}
4 changes: 4 additions & 0 deletions mlir/lib/Target/Cpp/TranslateToCpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1563,6 +1563,10 @@ LogicalResult CppEmitter::emitType(Location loc, Type type) {
}
if (auto iType = dyn_cast<IndexType>(type))
return (os << "size_t"), success();
if (auto iType = dyn_cast<emitc::UnsignedSizeType>(type))
return (os << "size_t"), success();
if (auto iType = dyn_cast<emitc::SignedSizeType>(type))
return (os << "ssize_t"), success();
if (auto tType = dyn_cast<TensorType>(type)) {
if (!tType.hasRank())
return emitError(loc, "cannot emit unranked tensor type");
Expand Down
8 changes: 4 additions & 4 deletions mlir/test/Dialect/EmitC/invalid_ops.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -170,31 +170,31 @@ func.func @add_float_pointer(%arg0: f32, %arg1: !emitc.ptr<f32>) {
// -----

func.func @div_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) {
// expected-error @+1 {{'emitc.div' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC opaque type, but got 'tensor<i32>'}}
// expected-error @+1 {{'emitc.div' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC signed size type or EmitC unsigned size type or EmitC opaque type, but got 'tensor<i32>'}}
%1 = "emitc.div" (%arg0, %arg1) : (tensor<i32>, tensor<i32>) -> tensor<i32>
return
}

// -----

func.func @mul_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) {
// expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC opaque type, but got 'tensor<i32>'}}
// expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC signed size type or EmitC unsigned size type or EmitC opaque type, but got 'tensor<i32>'}}
%1 = "emitc.mul" (%arg0, %arg1) : (tensor<i32>, tensor<i32>) -> tensor<i32>
return
}

// -----

func.func @rem_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) {
// expected-error @+1 {{'emitc.rem' op operand #0 must be integer type supported by EmitC or index or EmitC opaque type, but got 'tensor<i32>'}}
// expected-error @+1 {{'emitc.rem' op operand #0 must be integer type supported by EmitC or index or EmitC signed size type or EmitC unsigned size type or EmitC opaque type, but got 'tensor<i32>'}}
%1 = "emitc.rem" (%arg0, %arg1) : (tensor<i32>, tensor<i32>) -> tensor<i32>
return
}

// -----

func.func @rem_float(%arg0: f32, %arg1: f32) {
// expected-error @+1 {{'emitc.rem' op operand #0 must be integer type supported by EmitC or index or EmitC opaque type, but got 'f32'}}
// expected-error @+1 {{'emitc.rem' op operand #0 must be integer type supported by EmitC or index or EmitC signed size type or EmitC unsigned size type or EmitC opaque type, but got 'f32'}}
%1 = "emitc.rem" (%arg0, %arg1) : (f32, f32) -> f32
return
}
Expand Down
4 changes: 2 additions & 2 deletions mlir/test/Dialect/EmitC/invalid_types.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,15 @@ func.func @illegal_array_with_tensor_element_type(
// -----

func.func @illegal_integer_type(%arg0: i11, %arg1: i11) -> i11 {
// expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC opaque type, but got 'i11'}}
// expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC signed size type or EmitC unsigned size type or EmitC opaque type, but got 'i11'}}
%mul = "emitc.mul" (%arg0, %arg1) : (i11, i11) -> i11
return
}

// -----

func.func @illegal_float_type(%arg0: f80, %arg1: f80) {
// expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC opaque type, but got 'f80'}}
// expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC signed size type or EmitC unsigned size type or EmitC opaque type, but got 'f80'}}
%mul = "emitc.mul" (%arg0, %arg1) : (f80, f80) -> f80
return
}
Expand Down
7 changes: 7 additions & 0 deletions mlir/test/Dialect/EmitC/type-conversions.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// RUN: mlir-opt -debug -verify-diagnostics -test-emitc-type-conversions %s | FileCheck %s

// CHECK-LABEL: ssize_t
func.func @ssize_t() {
%0 = "emitc.constant"(){value = 42 : index} : () -> index
return
}
10 changes: 10 additions & 0 deletions mlir/test/Dialect/EmitC/types.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,13 @@ func.func @pointer_types() {

return
}

// CHECK-LABEL: func @index_types()
func.func @index_types() {
// CHECK-NEXT: !emitc.ssize_t
emitc.call_opaque "f"() {template_args = [!emitc.ssize_t]} : () -> ()
// CHECK-NEXT: !emitc.usize_t
emitc.call_opaque "f"() {template_args = [!emitc.usize_t]} : () -> ()

return
}
cferry-AMD marked this conversation as resolved.
Show resolved Hide resolved
10 changes: 10 additions & 0 deletions mlir/test/Target/Cpp/types.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,13 @@ func.func @ptr_types() {

return
}

// CHECK-LABEL: void size_types() {
func.func @size_types() {
// CHECK-NEXT: f<ssize_t>();
emitc.call_opaque "f"() {template_args = [!emitc.ssize_t]} : () -> ()
// CHECK-NEXT: f<size_t>();
emitc.call_opaque "f"() {template_args = [!emitc.usize_t]} : () -> ()

return
}
cferry-AMD marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions mlir/test/lib/Dialect/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ add_subdirectory(ArmSME)
add_subdirectory(Bufferization)
add_subdirectory(ControlFlow)
add_subdirectory(DLTI)
add_subdirectory(EmitC)
add_subdirectory(Func)
add_subdirectory(GPU)
add_subdirectory(Linalg)
Expand Down
9 changes: 9 additions & 0 deletions mlir/test/lib/Dialect/EmitC/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Exclude tests from libMLIR.so
add_mlir_library(MLIREmitCTransformsTest
TestTypeConversions.cpp

EXCLUDE_FROM_LIBMLIR

LINK_LIBS PUBLIC
MLIRPass
)
88 changes: 88 additions & 0 deletions mlir/test/lib/Dialect/EmitC/TestTypeConversions.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
//===- TestTypeConversions.cpp - Test EmitC type conversions --------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains a test pass to check EmitC type conversions.
//
//===----------------------------------------------------------------------===//

#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/EmitC/IR/EmitC.h"
#include "mlir/Dialect/EmitC/Transforms/TypeConversions.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/IR/Value.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Transforms/DialectConversion.h"

using namespace mlir;

namespace {
struct TestEmitCTypeConversions
: public PassWrapper<TestEmitCTypeConversions, OperationPass<>> {
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestEmitCTypeConversions)

void runOnOperation() override;
StringRef getArgument() const final { return "test-emitc-type-conversions"; }
void getDependentDialects(DialectRegistry &registry) const override {
registry.insert<emitc::EmitCDialect>();
}
StringRef getDescription() const final {
return "Test EmitC type conversions";
}
};

struct ConstantConverter : public OpConversionPattern<emitc::ConstantOp> {
public:
using OpConversionPattern<emitc::ConstantOp>::OpConversionPattern;

LogicalResult
matchAndRewrite(emitc::ConstantOp constantOp, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override {

// Get value attribute
auto valueAttr = ::cast<TypedAttr>(constantOp.getValue());
valueAttr.dump();

Type dstType = getTypeConverter()->convertType(valueAttr.getType());

if (!dstType)
return rewriter.notifyMatchFailure(constantOp, "type conversion failed");

// Invalid op since value should be an attribute but we'll get here at least
rewriter.replaceOpWithNewOp<emitc::ConstantOp>(constantOp, dstType,
adaptor.getOperands());

return success();
}
};

} // namespace

void TestEmitCTypeConversions::runOnOperation() {
MLIRContext *context = &getContext();
RewritePatternSet patterns(context);
TypeConverter typeConverter;
populateEmitCSizeTypeConversionPatterns(typeConverter);
// Add a default converter
// typeConverter.addConversion([](Type t) { t.dump(); return t; });
ConversionTarget target(getContext());
target.addLegalDialect<emitc::EmitCDialect>();
target.addDynamicallyLegalOp<emitc::ConstantOp>([](emitc::ConstantOp op) {
return isa<emitc::SignedSizeType, emitc::UnsignedSizeType>(op.getType());
});
patterns.insert<ConstantConverter>(typeConverter, context);
(void)applyPartialConversion(getOperation(), target, std::move(patterns));
}

namespace mlir {
namespace test {
void registerTestEmitCTypeConversions() {
PassRegistration<TestEmitCTypeConversions>();
}
} // namespace test
} // namespace mlir
1 change: 1 addition & 0 deletions mlir/tools/mlir-opt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ if(MLIR_INCLUDE_TESTS)
MLIRVectorTestPasses
MLIRTestVectorToSPIRV
MLIRLLVMTestPasses
MLIREmitCTransformsTest
)
set(test_libs ${test_libs}
MLIRTestPDLL
Expand Down
2 changes: 2 additions & 0 deletions mlir/tools/mlir-opt/mlir-opt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ void registerTestDecomposeCallGraphTypes();
void registerTestDiagnosticsPass();
void registerTestDominancePass();
void registerTestDynamicPipelinePass();
void registerTestEmitCTypeConversions();
void registerTestEmulateNarrowTypePass();
void registerTestExpandMathPass();
void registerTestFooAnalysisPass();
Expand Down Expand Up @@ -213,6 +214,7 @@ void registerTestPasses() {
mlir::test::registerTestDeadCodeAnalysisPass();
mlir::test::registerTestDominancePass();
mlir::test::registerTestDynamicPipelinePass();
mlir::test::registerTestEmitCTypeConversions();
mlir::test::registerTestEmulateNarrowTypePass();
mlir::test::registerTestExpandMathPass();
mlir::test::registerTestFooAnalysisPass();
Expand Down
Loading