mirror of https://github.com/llvm/circt.git
[FIRRTL] Add location to getResultType for better error reporting (#203)
* change getTypeSignature * Apply for bitops * Add test for bits * Modify a bit * clang-format * fit into 80
This commit is contained in:
parent
08f04b74f6
commit
4d31c29d2f
|
@ -50,7 +50,8 @@ def SubfieldOp : FIRRTLOp<"subfield", [NoSideEffect]> {
|
||||||
/// Compute the result of a Subfield operation on a value of the specified
|
/// Compute the result of a Subfield operation on a value of the specified
|
||||||
/// type and extracting the specified field name. If the request is
|
/// type and extracting the specified field name. If the request is
|
||||||
/// invalid, then a null type is returned.
|
/// invalid, then a null type is returned.
|
||||||
static FIRRTLType getResultType(FIRRTLType inType, StringRef fieldName);
|
static FIRRTLType getResultType(FIRRTLType inType, StringRef fieldName,
|
||||||
|
Location loc);
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +78,8 @@ def SubindexOp : FIRRTLOp<"subindex", [NoSideEffect]> {
|
||||||
let extraClassDeclaration = [{
|
let extraClassDeclaration = [{
|
||||||
/// Compute the result of a Subindex operation on a value of the specified
|
/// Compute the result of a Subindex operation on a value of the specified
|
||||||
/// type. If the request is invalid, then a null type is returned.
|
/// type. If the request is invalid, then a null type is returned.
|
||||||
static FIRRTLType getResultType(FIRRTLType inType, unsigned fieldIdx);
|
static FIRRTLType getResultType(FIRRTLType inType, unsigned fieldIdx,
|
||||||
|
Location loc);
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +105,8 @@ def SubaccessOp : FIRRTLOp<"subaccess", [NoSideEffect]> {
|
||||||
let extraClassDeclaration = [{
|
let extraClassDeclaration = [{
|
||||||
/// Compute the result of a Subaccess operation on a value of the specified
|
/// Compute the result of a Subaccess operation on a value of the specified
|
||||||
/// type. If the request is invalid, then a null type is returned.
|
/// type. If the request is invalid, then a null type is returned.
|
||||||
static FIRRTLType getResultType(FIRRTLType baseType, FIRRTLType indexType);
|
static FIRRTLType getResultType(FIRRTLType baseType, FIRRTLType indexType,
|
||||||
|
Location loc);
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -133,14 +136,15 @@ class BinaryPrimOp<string mnemonic, string resultTypeFunction,
|
||||||
let extraClassDeclaration = !cast<code>(!strconcat(!cast<string>([{
|
let extraClassDeclaration = !cast<code>(!strconcat(!cast<string>([{
|
||||||
/// Return the result for inputs with the specified type, returning a null
|
/// Return the result for inputs with the specified type, returning a null
|
||||||
/// type if the input types are invalid.
|
/// type if the input types are invalid.
|
||||||
static FIRRTLType getResultType(FIRRTLType lhs, FIRRTLType rhs) {
|
static FIRRTLType getResultType(FIRRTLType lhs, FIRRTLType rhs,
|
||||||
|
Location loc) {
|
||||||
return }]), resultTypeFunction, !cast<string>([{(lhs, rhs);
|
return }]), resultTypeFunction, !cast<string>([{(lhs, rhs);
|
||||||
}
|
}
|
||||||
static FIRRTLType getResultType(ArrayRef<FIRRTLType> inputs,
|
static FIRRTLType getResultType(ArrayRef<FIRRTLType> inputs,
|
||||||
ArrayRef<int32_t> integers) {
|
ArrayRef<int32_t> integers, Location loc) {
|
||||||
if (inputs.size() != 2 || !integers.empty())
|
if (inputs.size() != 2 || !integers.empty())
|
||||||
return {};
|
return {};
|
||||||
return getResultType(inputs[0], inputs[1]);
|
return getResultType(inputs[0], inputs[1], loc);
|
||||||
}
|
}
|
||||||
}])));
|
}])));
|
||||||
}
|
}
|
||||||
|
@ -197,14 +201,14 @@ class UnaryPrimOp<string mnemonic, string resultTypeFunction,
|
||||||
let extraClassDeclaration = !cast<code>(!strconcat(!cast<string>([{
|
let extraClassDeclaration = !cast<code>(!strconcat(!cast<string>([{
|
||||||
/// Return the result for inputs with the specified type, returning a null
|
/// Return the result for inputs with the specified type, returning a null
|
||||||
/// type if the input types are invalid.
|
/// type if the input types are invalid.
|
||||||
static FIRRTLType getResultType(FIRRTLType input) {
|
static FIRRTLType getResultType(FIRRTLType input, Location loc) {
|
||||||
return }]), resultTypeFunction, !cast<string>([{(input);
|
return }]), resultTypeFunction, !cast<string>([{(input);
|
||||||
}
|
}
|
||||||
static FIRRTLType getResultType(ArrayRef<FIRRTLType> inputs,
|
static FIRRTLType getResultType(ArrayRef<FIRRTLType> inputs,
|
||||||
ArrayRef<int32_t> integers) {
|
ArrayRef<int32_t> integers, Location loc) {
|
||||||
if (inputs.size() != 1 || !integers.empty())
|
if (inputs.size() != 1 || !integers.empty())
|
||||||
return {};
|
return {};
|
||||||
return getResultType(inputs[0]);
|
return getResultType(inputs[0], loc);
|
||||||
}
|
}
|
||||||
}])));
|
}])));
|
||||||
}
|
}
|
||||||
|
@ -252,12 +256,12 @@ def BitsPrimOp : PrimOp<"bits"> {
|
||||||
/// Return the result for inputs with the specified type, returning a null
|
/// Return the result for inputs with the specified type, returning a null
|
||||||
/// type if the input types are invalid.
|
/// type if the input types are invalid.
|
||||||
static FIRRTLType getResultType(FIRRTLType input, int32_t high,
|
static FIRRTLType getResultType(FIRRTLType input, int32_t high,
|
||||||
int32_t low);
|
int32_t low, Location loc);
|
||||||
static FIRRTLType getResultType(ArrayRef<FIRRTLType> inputs,
|
static FIRRTLType getResultType(ArrayRef<FIRRTLType> inputs,
|
||||||
ArrayRef<int32_t> integers) {
|
ArrayRef<int32_t> integers, Location loc) {
|
||||||
if (inputs.size() != 1 || integers.size() != 2)
|
if (inputs.size() != 1 || integers.size() != 2)
|
||||||
return {};
|
return {};
|
||||||
return getResultType(inputs[0], integers[0], integers[1]);
|
return getResultType(inputs[0], integers[0], integers[1], loc);
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
@ -277,12 +281,13 @@ def HeadPrimOp : PrimOp<"head"> {
|
||||||
let extraClassDeclaration = [{
|
let extraClassDeclaration = [{
|
||||||
/// Return the result for inputs with the specified type, returning a null
|
/// Return the result for inputs with the specified type, returning a null
|
||||||
/// type if the input types are invalid.
|
/// type if the input types are invalid.
|
||||||
static FIRRTLType getResultType(FIRRTLType input, int32_t amount);
|
static FIRRTLType getResultType(FIRRTLType input, int32_t amount,
|
||||||
|
Location loc);
|
||||||
static FIRRTLType getResultType(ArrayRef<FIRRTLType> inputs,
|
static FIRRTLType getResultType(ArrayRef<FIRRTLType> inputs,
|
||||||
ArrayRef<int32_t> integers) {
|
ArrayRef<int32_t> integers, Location loc) {
|
||||||
if (inputs.size() != 1 || integers.size() != 1)
|
if (inputs.size() != 1 || integers.size() != 1)
|
||||||
return {};
|
return {};
|
||||||
return getResultType(inputs[0], integers[0]);
|
return getResultType(inputs[0], integers[0], loc);
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
@ -301,12 +306,12 @@ def MuxPrimOp : PrimOp<"mux"> {
|
||||||
/// Return the result for inputs with the specified type, returning a null
|
/// Return the result for inputs with the specified type, returning a null
|
||||||
/// type if the input types are invalid.
|
/// type if the input types are invalid.
|
||||||
static FIRRTLType getResultType(FIRRTLType sel, FIRRTLType high,
|
static FIRRTLType getResultType(FIRRTLType sel, FIRRTLType high,
|
||||||
FIRRTLType low);
|
FIRRTLType low, Location loc);
|
||||||
static FIRRTLType getResultType(ArrayRef<FIRRTLType> inputs,
|
static FIRRTLType getResultType(ArrayRef<FIRRTLType> inputs,
|
||||||
ArrayRef<int32_t> integers) {
|
ArrayRef<int32_t> integers, Location loc) {
|
||||||
if (inputs.size() != 3 || integers.size() != 0)
|
if (inputs.size() != 3 || integers.size() != 0)
|
||||||
return {};
|
return {};
|
||||||
return getResultType(inputs[0], inputs[1], inputs[2]);
|
return getResultType(inputs[0], inputs[1], inputs[2], loc);
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
@ -330,12 +335,13 @@ def PadPrimOp : PrimOp<"pad"> {
|
||||||
let extraClassDeclaration = [{
|
let extraClassDeclaration = [{
|
||||||
/// Return the result for inputs with the specified type, returning a null
|
/// Return the result for inputs with the specified type, returning a null
|
||||||
/// type if the input types are invalid.
|
/// type if the input types are invalid.
|
||||||
static FIRRTLType getResultType(FIRRTLType input, int32_t amount);
|
static FIRRTLType getResultType(FIRRTLType input, int32_t amount,
|
||||||
|
Location loc);
|
||||||
static FIRRTLType getResultType(ArrayRef<FIRRTLType> inputs,
|
static FIRRTLType getResultType(ArrayRef<FIRRTLType> inputs,
|
||||||
ArrayRef<int32_t> integers) {
|
ArrayRef<int32_t> integers, Location loc) {
|
||||||
if (inputs.size() != 1 || integers.size() != 1)
|
if (inputs.size() != 1 || integers.size() != 1)
|
||||||
return {};
|
return {};
|
||||||
return getResultType(inputs[0], integers[0]);
|
return getResultType(inputs[0], integers[0], loc);
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
@ -351,12 +357,13 @@ class ShiftPrimOp<string mnemonic> : PrimOp<mnemonic> {
|
||||||
let extraClassDeclaration = [{
|
let extraClassDeclaration = [{
|
||||||
/// Return the result for inputs with the specified type, returning a null
|
/// Return the result for inputs with the specified type, returning a null
|
||||||
/// type if the input types are invalid.
|
/// type if the input types are invalid.
|
||||||
static FIRRTLType getResultType(FIRRTLType input, int32_t amount);
|
static FIRRTLType getResultType(FIRRTLType input, int32_t amount,
|
||||||
|
Location loc);
|
||||||
static FIRRTLType getResultType(ArrayRef<FIRRTLType> inputs,
|
static FIRRTLType getResultType(ArrayRef<FIRRTLType> inputs,
|
||||||
ArrayRef<int32_t> integers) {
|
ArrayRef<int32_t> integers, Location loc) {
|
||||||
if (inputs.size() != 1 || integers.size() != 1)
|
if (inputs.size() != 1 || integers.size() != 1)
|
||||||
return {};
|
return {};
|
||||||
return getResultType(inputs[0], integers[0]);
|
return getResultType(inputs[0], integers[0], loc);
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
@ -385,12 +392,13 @@ def TailPrimOp : PrimOp<"tail"> {
|
||||||
let extraClassDeclaration = [{
|
let extraClassDeclaration = [{
|
||||||
/// Return the result for inputs with the specified type, returning a null
|
/// Return the result for inputs with the specified type, returning a null
|
||||||
/// type if the input types are invalid.
|
/// type if the input types are invalid.
|
||||||
static FIRRTLType getResultType(FIRRTLType input, int32_t amount);
|
static FIRRTLType getResultType(FIRRTLType input, int32_t amount,
|
||||||
|
Location loc);
|
||||||
static FIRRTLType getResultType(ArrayRef<FIRRTLType> inputs,
|
static FIRRTLType getResultType(ArrayRef<FIRRTLType> inputs,
|
||||||
ArrayRef<int32_t> integers) {
|
ArrayRef<int32_t> integers, Location loc) {
|
||||||
if (inputs.size() != 1 || integers.size() != 1)
|
if (inputs.size() != 1 || integers.size() != 1)
|
||||||
return {};
|
return {};
|
||||||
return getResultType(inputs[0], integers[0]);
|
return getResultType(inputs[0], integers[0], loc);
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "circt/Dialect/FIRRTL/Ops.h"
|
#include "circt/Dialect/FIRRTL/Ops.h"
|
||||||
#include "circt/Dialect/FIRRTL/Visitors.h"
|
#include "circt/Dialect/FIRRTL/Visitors.h"
|
||||||
|
#include "mlir/IR/Diagnostics.h"
|
||||||
#include "mlir/IR/DialectImplementation.h"
|
#include "mlir/IR/DialectImplementation.h"
|
||||||
#include "mlir/IR/FunctionImplementation.h"
|
#include "mlir/IR/FunctionImplementation.h"
|
||||||
#include "mlir/IR/StandardTypes.h"
|
#include "mlir/IR/StandardTypes.h"
|
||||||
|
@ -795,7 +796,8 @@ void ConstantOp::build(OpBuilder &builder, OperationState &result, IntType type,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the result of a subfield operation.
|
// Return the result of a subfield operation.
|
||||||
FIRRTLType SubfieldOp::getResultType(FIRRTLType inType, StringRef fieldName) {
|
FIRRTLType SubfieldOp::getResultType(FIRRTLType inType, StringRef fieldName,
|
||||||
|
Location loc) {
|
||||||
if (auto bundleType = inType.dyn_cast<BundleType>()) {
|
if (auto bundleType = inType.dyn_cast<BundleType>()) {
|
||||||
for (auto &elt : bundleType.getElements()) {
|
for (auto &elt : bundleType.getElements()) {
|
||||||
if (elt.first == fieldName)
|
if (elt.first == fieldName)
|
||||||
|
@ -804,31 +806,33 @@ FIRRTLType SubfieldOp::getResultType(FIRRTLType inType, StringRef fieldName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto flipType = inType.dyn_cast<FlipType>())
|
if (auto flipType = inType.dyn_cast<FlipType>())
|
||||||
if (auto subType = getResultType(flipType.getElementType(), fieldName))
|
if (auto subType = getResultType(flipType.getElementType(), fieldName, loc))
|
||||||
return FlipType::get(subType);
|
return FlipType::get(subType);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
FIRRTLType SubindexOp::getResultType(FIRRTLType inType, unsigned fieldIdx) {
|
FIRRTLType SubindexOp::getResultType(FIRRTLType inType, unsigned fieldIdx,
|
||||||
|
Location loc) {
|
||||||
if (auto vectorType = inType.dyn_cast<FVectorType>())
|
if (auto vectorType = inType.dyn_cast<FVectorType>())
|
||||||
if (fieldIdx < vectorType.getNumElements())
|
if (fieldIdx < vectorType.getNumElements())
|
||||||
return vectorType.getElementType();
|
return vectorType.getElementType();
|
||||||
|
|
||||||
if (auto flipType = inType.dyn_cast<FlipType>())
|
if (auto flipType = inType.dyn_cast<FlipType>())
|
||||||
if (auto subType = getResultType(flipType.getElementType(), fieldIdx))
|
if (auto subType = getResultType(flipType.getElementType(), fieldIdx, loc))
|
||||||
return FlipType::get(subType);
|
return FlipType::get(subType);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
FIRRTLType SubaccessOp::getResultType(FIRRTLType inType, FIRRTLType indexType) {
|
FIRRTLType SubaccessOp::getResultType(FIRRTLType inType, FIRRTLType indexType,
|
||||||
|
Location loc) {
|
||||||
if (auto vectorType = inType.dyn_cast<FVectorType>())
|
if (auto vectorType = inType.dyn_cast<FVectorType>())
|
||||||
if (indexType.isa<UIntType>())
|
if (indexType.isa<UIntType>())
|
||||||
return vectorType.getElementType();
|
return vectorType.getElementType();
|
||||||
|
|
||||||
if (auto flipType = inType.dyn_cast<FlipType>())
|
if (auto flipType = inType.dyn_cast<FlipType>())
|
||||||
if (auto subType = getResultType(flipType.getElementType(), indexType))
|
if (auto subType = getResultType(flipType.getElementType(), indexType, loc))
|
||||||
return FlipType::get(subType);
|
return FlipType::get(subType);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
@ -1076,31 +1080,20 @@ FIRRTLType firrtl::getReductionResult(FIRRTLType input) {
|
||||||
static LogicalResult verifyBitsPrimOp(BitsPrimOp bits) {
|
static LogicalResult verifyBitsPrimOp(BitsPrimOp bits) {
|
||||||
uint32_t hi = bits.hi(), lo = bits.lo();
|
uint32_t hi = bits.hi(), lo = bits.lo();
|
||||||
|
|
||||||
// High must be >= low.
|
auto expectedType =
|
||||||
if (hi < lo) {
|
BitsPrimOp::getResultType(bits.input().getType().cast<FIRRTLType>(),
|
||||||
bits.emitError()
|
(int32_t)hi, (int32_t)lo, bits.getLoc());
|
||||||
<< "high must be equal or greater than low, but got high = " << hi
|
if (!expectedType)
|
||||||
<< ", low = " << lo;
|
|
||||||
return failure();
|
return failure();
|
||||||
}
|
|
||||||
|
|
||||||
// Input width must be > high.
|
|
||||||
int32_t width =
|
|
||||||
bits.input().getType().cast<IntType>().getBitWidthOrSentinel();
|
|
||||||
if (width != -1 && int32_t(hi) >= width) {
|
|
||||||
bits.emitError()
|
|
||||||
<< "high must be smaller than the width of input, but got high = " << hi
|
|
||||||
<< ", width = " << width;
|
|
||||||
return failure();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Result type should be int type with (high - low + 1) width.
|
|
||||||
int32_t resultWidth =
|
int32_t resultWidth =
|
||||||
bits.result().getType().cast<IntType>().getBitWidthOrSentinel();
|
bits.result().getType().cast<IntType>().getBitWidthOrSentinel();
|
||||||
if (resultWidth != -1 && int32_t(hi - lo + 1) != resultWidth) {
|
int32_t expectedWidth = expectedType.cast<IntType>().getBitWidthOrSentinel();
|
||||||
|
|
||||||
|
if (resultWidth != -1 && expectedWidth != resultWidth) {
|
||||||
bits.emitError() << "width of the result type must be equal to (high - low "
|
bits.emitError() << "width of the result type must be equal to (high - low "
|
||||||
"+ 1), expected "
|
"+ 1), expected "
|
||||||
<< hi - lo + 1 << " but got " << resultWidth;
|
<< expectedWidth << " but got " << resultWidth;
|
||||||
return failure();
|
return failure();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1108,30 +1101,51 @@ static LogicalResult verifyBitsPrimOp(BitsPrimOp bits) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FIRRTLType BitsPrimOp::getResultType(FIRRTLType input, int32_t high,
|
FIRRTLType BitsPrimOp::getResultType(FIRRTLType input, int32_t high,
|
||||||
int32_t low) {
|
int32_t low, Location loc) {
|
||||||
auto inputi = input.dyn_cast<IntType>();
|
auto inputi = input.dyn_cast<IntType>();
|
||||||
|
|
||||||
// High must be >= low and both most be non-negative.
|
if (!inputi) {
|
||||||
if (!inputi || high < low || low < 0)
|
mlir::emitError(loc) << "input type should be the int type but got "
|
||||||
|
<< input;
|
||||||
return {};
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// High must be >= low and both most be non-negative.
|
||||||
|
if (high < low) {
|
||||||
|
mlir::emitError(loc)
|
||||||
|
<< "high must be equal or greater than low, but got high = " << high
|
||||||
|
<< ", low = " << low;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (low < 0) {
|
||||||
|
mlir::emitError(loc) << "low must be non-negative but got" << low;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
// If the input has staticly known width, check it. Both and low must be
|
// If the input has staticly known width, check it. Both and low must be
|
||||||
// strictly less than width.
|
// strictly less than width.
|
||||||
int32_t width = inputi.getWidthOrSentinel();
|
int32_t width = inputi.getWidthOrSentinel();
|
||||||
if (width != -1 && high >= width)
|
if (width != -1 && high >= width) {
|
||||||
|
mlir::emitError(loc)
|
||||||
|
<< "high must be smaller than the width of input, but got high = "
|
||||||
|
<< high << ", width = " << width;
|
||||||
return {};
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
return UIntType::get(input.getContext(), high - low + 1);
|
return UIntType::get(input.getContext(), high - low + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitsPrimOp::build(OpBuilder &builder, OperationState &result, Value input,
|
void BitsPrimOp::build(OpBuilder &builder, OperationState &result, Value input,
|
||||||
unsigned high, unsigned low) {
|
unsigned high, unsigned low) {
|
||||||
auto type = getResultType(input.getType().cast<FIRRTLType>(), high, low);
|
auto type = getResultType(input.getType().cast<FIRRTLType>(), high, low,
|
||||||
|
result.location);
|
||||||
assert(type && "invalid inputs building BitsPrimOp!");
|
assert(type && "invalid inputs building BitsPrimOp!");
|
||||||
build(builder, result, type, input, high, low);
|
build(builder, result, type, input, high, low);
|
||||||
}
|
}
|
||||||
|
|
||||||
FIRRTLType HeadPrimOp::getResultType(FIRRTLType input, int32_t amount) {
|
FIRRTLType HeadPrimOp::getResultType(FIRRTLType input, int32_t amount,
|
||||||
|
Location loc) {
|
||||||
auto inputi = input.dyn_cast<IntType>();
|
auto inputi = input.dyn_cast<IntType>();
|
||||||
if (amount <= 0 || !inputi)
|
if (amount <= 0 || !inputi)
|
||||||
return {};
|
return {};
|
||||||
|
@ -1145,7 +1159,7 @@ FIRRTLType HeadPrimOp::getResultType(FIRRTLType input, int32_t amount) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FIRRTLType MuxPrimOp::getResultType(FIRRTLType sel, FIRRTLType high,
|
FIRRTLType MuxPrimOp::getResultType(FIRRTLType sel, FIRRTLType high,
|
||||||
FIRRTLType low) {
|
FIRRTLType low, Location loc) {
|
||||||
// Sel needs to be a one bit uint or an unknown width uint.
|
// Sel needs to be a one bit uint or an unknown width uint.
|
||||||
auto selui = sel.dyn_cast<UIntType>();
|
auto selui = sel.dyn_cast<UIntType>();
|
||||||
if (!selui || selui.getWidthOrSentinel() > 1)
|
if (!selui || selui.getWidthOrSentinel() > 1)
|
||||||
|
@ -1191,7 +1205,8 @@ FIRRTLType MuxPrimOp::getResultType(FIRRTLType sel, FIRRTLType high,
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
FIRRTLType PadPrimOp::getResultType(FIRRTLType input, int32_t amount) {
|
FIRRTLType PadPrimOp::getResultType(FIRRTLType input, int32_t amount,
|
||||||
|
Location loc) {
|
||||||
auto inputi = input.dyn_cast<IntType>();
|
auto inputi = input.dyn_cast<IntType>();
|
||||||
if (amount < 0 || !inputi)
|
if (amount < 0 || !inputi)
|
||||||
return {};
|
return {};
|
||||||
|
@ -1204,7 +1219,8 @@ FIRRTLType PadPrimOp::getResultType(FIRRTLType input, int32_t amount) {
|
||||||
return IntType::get(input.getContext(), inputi.isSigned(), width);
|
return IntType::get(input.getContext(), inputi.isSigned(), width);
|
||||||
}
|
}
|
||||||
|
|
||||||
FIRRTLType ShlPrimOp::getResultType(FIRRTLType input, int32_t amount) {
|
FIRRTLType ShlPrimOp::getResultType(FIRRTLType input, int32_t amount,
|
||||||
|
Location loc) {
|
||||||
auto inputi = input.dyn_cast<IntType>();
|
auto inputi = input.dyn_cast<IntType>();
|
||||||
if (amount < 0 || !inputi)
|
if (amount < 0 || !inputi)
|
||||||
return {};
|
return {};
|
||||||
|
@ -1216,7 +1232,8 @@ FIRRTLType ShlPrimOp::getResultType(FIRRTLType input, int32_t amount) {
|
||||||
return IntType::get(input.getContext(), inputi.isSigned(), width);
|
return IntType::get(input.getContext(), inputi.isSigned(), width);
|
||||||
}
|
}
|
||||||
|
|
||||||
FIRRTLType ShrPrimOp::getResultType(FIRRTLType input, int32_t amount) {
|
FIRRTLType ShrPrimOp::getResultType(FIRRTLType input, int32_t amount,
|
||||||
|
Location loc) {
|
||||||
auto inputi = input.dyn_cast<IntType>();
|
auto inputi = input.dyn_cast<IntType>();
|
||||||
if (amount < 0 || !inputi)
|
if (amount < 0 || !inputi)
|
||||||
return {};
|
return {};
|
||||||
|
@ -1228,7 +1245,8 @@ FIRRTLType ShrPrimOp::getResultType(FIRRTLType input, int32_t amount) {
|
||||||
return IntType::get(input.getContext(), inputi.isSigned(), width);
|
return IntType::get(input.getContext(), inputi.isSigned(), width);
|
||||||
}
|
}
|
||||||
|
|
||||||
FIRRTLType TailPrimOp::getResultType(FIRRTLType input, int32_t amount) {
|
FIRRTLType TailPrimOp::getResultType(FIRRTLType input, int32_t amount,
|
||||||
|
Location loc) {
|
||||||
auto inputi = input.dyn_cast<IntType>();
|
auto inputi = input.dyn_cast<IntType>();
|
||||||
if (amount < 0 || !inputi)
|
if (amount < 0 || !inputi)
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -902,7 +902,8 @@ ParseResult FIRStmtParser::parsePostFixFieldId(Value &result,
|
||||||
// Make sure the field name matches up with the input value's type and
|
// Make sure the field name matches up with the input value's type and
|
||||||
// compute the result type for the expression.
|
// compute the result type for the expression.
|
||||||
auto resultType = result.getType().cast<FIRRTLType>();
|
auto resultType = result.getType().cast<FIRRTLType>();
|
||||||
resultType = SubfieldOp::getResultType(resultType, fieldName);
|
resultType =
|
||||||
|
SubfieldOp::getResultType(resultType, fieldName, translateLocation(loc));
|
||||||
if (!resultType) {
|
if (!resultType) {
|
||||||
// TODO(QoI): This error would be nicer with a .fir pretty print of the
|
// TODO(QoI): This error would be nicer with a .fir pretty print of the
|
||||||
// type.
|
// type.
|
||||||
|
@ -938,7 +939,8 @@ ParseResult FIRStmtParser::parsePostFixIntSubscript(Value &result,
|
||||||
// Make sure the index expression is valid and compute the result type for the
|
// Make sure the index expression is valid and compute the result type for the
|
||||||
// expression.
|
// expression.
|
||||||
auto resultType = result.getType().cast<FIRRTLType>();
|
auto resultType = result.getType().cast<FIRRTLType>();
|
||||||
resultType = SubindexOp::getResultType(resultType, indexNo);
|
resultType = SubindexOp::getResultType(resultType, indexNo,
|
||||||
|
translateLocation(indexLoc));
|
||||||
if (!resultType) {
|
if (!resultType) {
|
||||||
// TODO(QoI): This error would be nicer with a .fir pretty print of the
|
// TODO(QoI): This error would be nicer with a .fir pretty print of the
|
||||||
// type.
|
// type.
|
||||||
|
@ -979,7 +981,8 @@ ParseResult FIRStmtParser::parsePostFixDynamicSubscript(Value &result,
|
||||||
// Make sure the index expression is valid and compute the result type for the
|
// Make sure the index expression is valid and compute the result type for the
|
||||||
// expression.
|
// expression.
|
||||||
auto resultType = result.getType().cast<FIRRTLType>();
|
auto resultType = result.getType().cast<FIRRTLType>();
|
||||||
resultType = SubaccessOp::getResultType(resultType, indexType);
|
resultType = SubaccessOp::getResultType(resultType, indexType,
|
||||||
|
translateLocation(indexLoc));
|
||||||
if (!resultType) {
|
if (!resultType) {
|
||||||
// TODO(QoI): This error would be nicer with a .fir pretty print of the
|
// TODO(QoI): This error would be nicer with a .fir pretty print of the
|
||||||
// type.
|
// type.
|
||||||
|
@ -1086,7 +1089,8 @@ ParseResult FIRStmtParser::parsePrimExp(Value &result, SubOpVector &subOps) {
|
||||||
|
|
||||||
#define TOK_LPKEYWORD_PRIM(SPELLING, CLASS) \
|
#define TOK_LPKEYWORD_PRIM(SPELLING, CLASS) \
|
||||||
case FIRToken::lp_##SPELLING: { \
|
case FIRToken::lp_##SPELLING: { \
|
||||||
auto resultTy = CLASS::getResultType(opTypes, integers); \
|
auto resultTy = \
|
||||||
|
CLASS::getResultType(opTypes, integers, translateLocation(loc)); \
|
||||||
if (!resultTy) \
|
if (!resultTy) \
|
||||||
return typeError(#SPELLING); \
|
return typeError(#SPELLING); \
|
||||||
result = builder.create<CLASS>(translateLocation(loc), resultTy, \
|
result = builder.create<CLASS>(translateLocation(loc), resultTy, \
|
||||||
|
|
|
@ -112,3 +112,13 @@ circuit test :
|
||||||
module invalid_name :
|
module invalid_name :
|
||||||
input bf: { flip int_1 : UInt<1>, int_out : UInt<2>}
|
input bf: { flip int_1 : UInt<1>, int_out : UInt<2>}
|
||||||
node n4 = add(bf, bf) ; expected-error {{invalid input types for 'add'}}
|
node n4 = add(bf, bf) ; expected-error {{invalid input types for 'add'}}
|
||||||
|
|
||||||
|
;// -----
|
||||||
|
|
||||||
|
circuit test :
|
||||||
|
module invalid_bits:
|
||||||
|
input a: UInt<8>
|
||||||
|
output b: UInt<4>
|
||||||
|
; expected-error@+2 {{high must be equal or greater than low, but got high = 4, low = 7}};
|
||||||
|
; expected-error@+1 {{invalid input types for 'bits': '!firrtl.uint<8>'}}
|
||||||
|
b <= bits(a, 4, 7)
|
Loading…
Reference in New Issue