Standardize and refactor Attribute type printing.

Remove the ability to print an attribute without a type, but allow for attributes to elide the type under certain circumstances. This fixes a bug where attributes within ArrayAttr, and other collection attributes, would never print the type.

PiperOrigin-RevId: 255306974
This commit is contained in:
River Riddle 2019-06-26 18:29:25 -07:00 committed by A. Unique TensorFlower
parent d4cf54f2c1
commit 260d3e39ad
9 changed files with 116 additions and 113 deletions

View File

@ -125,9 +125,7 @@ ParseResult linalg::SliceOp::parse(OpAsmParser *parser,
void linalg::SliceOp::print(OpAsmPrinter *p) {
*p << getOperationName() << " " << *getParentView() << "[" << *getIndexing()
<< "]";
*p << " {dim = ";
p->printAttribute(getAttr("dim"));
*p << "}";
*p << " {dim = " << getAttrOfType<IntegerAttr>("dim").getInt() << "}";
p->printOptionalAttrDict(getAttrs(), {"dim"});
*p << " : " << getParentViewType() << ", " << getIndexing()->getType();
}

View File

@ -65,7 +65,6 @@ public:
}
virtual void printType(Type type) = 0;
virtual void printAttribute(Attribute attr) = 0;
virtual void printAttributeAndType(Attribute attr) = 0;
/// Print a successor, and use list, of a terminator operation given the
/// terminator and the successor index.

View File

@ -335,12 +335,11 @@ public:
}
void print(Module *module);
void printAttributeAndType(Attribute attr) {
printAttributeOptionalType(attr, /*includeType=*/true);
}
void printAttribute(Attribute attr) {
printAttributeOptionalType(attr, /*includeType=*/false);
}
/// Print the given attribute. If 'mayElideType' is true, some attributes are
/// printed without the type when the type matches the default used in the
/// parser (for example i64 is the default for integer attributes).
void printAttribute(Attribute attr, bool mayElideType = false);
void printType(Type type);
void print(Function *fn);
@ -359,7 +358,6 @@ protected:
void printOptionalAttrDict(ArrayRef<NamedAttribute> attrs,
ArrayRef<StringRef> elidedAttrs = {});
void printAttributeOptionalType(Attribute attr, bool includeType);
void printTrailingLocation(Location loc);
void printLocationInternal(LocationAttr loc, bool pretty = false);
void printDenseElementsAttr(DenseElementsAttr attr);
@ -591,8 +589,7 @@ static void printDialectSymbol(raw_ostream &os, StringRef symPrefix,
os << "<\"" << symString << "\">";
}
void ModulePrinter::printAttributeOptionalType(Attribute attr,
bool includeType) {
void ModulePrinter::printAttribute(Attribute attr, bool mayElideType) {
if (!attr) {
os << "<<NULL ATTRIBUTE>>";
return;
@ -630,7 +627,9 @@ void ModulePrinter::printAttributeOptionalType(Attribute attr,
break;
case StandardAttributes::Bool:
os << (attr.cast<BoolAttr>().getValue() ? "true" : "false");
break;
// BoolAttr always elides the type.
return;
case StandardAttributes::Dictionary:
os << '{';
interleaveComma(attr.cast<DictionaryAttr>().getValue(),
@ -646,21 +645,19 @@ void ModulePrinter::printAttributeOptionalType(Attribute attr,
bool isSigned = intAttr.getType().isIndex() ||
intAttr.getType().getIntOrFloatBitWidth() != 1;
intAttr.getValue().print(os, isSigned);
// Print the type.
if (includeType) {
os << " : ";
printType(intAttr.getType());
}
// IntegerAttr elides the type if I64.
if (mayElideType && intAttr.getType().isInteger(64))
return;
break;
}
case StandardAttributes::Float: {
auto floatAttr = attr.cast<FloatAttr>();
printFloatValue(floatAttr.getValue(), os);
// Print the type.
if (includeType) {
os << " : ";
printType(floatAttr.getType());
}
// FloatAttr elides the type if F64.
if (mayElideType && floatAttr.getType().isF64())
return;
break;
}
case StandardAttributes::String:
@ -670,13 +667,16 @@ void ModulePrinter::printAttributeOptionalType(Attribute attr,
break;
case StandardAttributes::Array:
os << '[';
interleaveComma(attr.cast<ArrayAttr>().getValue(),
[&](Attribute attr) { printAttribute(attr); });
interleaveComma(attr.cast<ArrayAttr>().getValue(), [&](Attribute attr) {
printAttribute(attr, /*mayElideType=*/true);
});
os << ']';
break;
case StandardAttributes::AffineMap:
attr.cast<AffineMapAttr>().getValue().print(os);
break;
// AffineMap always elides the type.
return;
case StandardAttributes::IntegerSet:
attr.cast<IntegerSetAttr>().getValue().print(os);
break;
@ -690,16 +690,14 @@ void ModulePrinter::printAttributeOptionalType(Attribute attr,
case StandardAttributes::OpaqueElements: {
auto eltsAttr = attr.cast<OpaqueElementsAttr>();
os << "opaque<\"" << eltsAttr.getDialect()->getNamespace() << "\", ";
os << '"' << "0x" << llvm::toHex(eltsAttr.getValue()) << "\"> : ";
printType(eltsAttr.getType());
os << '"' << "0x" << llvm::toHex(eltsAttr.getValue()) << "\">";
break;
}
case StandardAttributes::DenseElements: {
auto eltsAttr = attr.cast<DenseElementsAttr>();
os << "dense<";
printDenseElementsAttr(eltsAttr);
os << "> : ";
printType(eltsAttr.getType());
os << '>';
break;
}
case StandardAttributes::SparseElements: {
@ -708,8 +706,7 @@ void ModulePrinter::printAttributeOptionalType(Attribute attr,
printDenseElementsAttr(elementsAttr.getIndices());
os << ", ";
printDenseElementsAttr(elementsAttr.getValues());
os << "> : ";
printType(elementsAttr.getType());
os << '>';
break;
}
@ -722,6 +719,27 @@ void ModulePrinter::printAttributeOptionalType(Attribute attr,
printLocation(attr.cast<LocationAttr>());
break;
}
// Print the type if it isn't a 'none' type.
auto attrType = attr.getType();
if (!attrType.isa<NoneType>()) {
os << " : ";
printType(attrType);
}
}
/// Print the integer element of the given DenseElementsAttr at 'index'.
static void printDenseIntElement(DenseElementsAttr attr, raw_ostream &os,
unsigned index) {
APInt value = *std::next(attr.getIntValues().begin(), index);
value.print(os, /*isSigned=*/value.getBitWidth() != 1);
}
/// Print the float element of the given DenseElementsAttr at 'index'.
static void printDenseFloatElement(DenseElementsAttr attr, raw_ostream &os,
unsigned index) {
APFloat value = *std::next(attr.getFloatValues().begin(), index);
printFloatValue(value, os);
}
void ModulePrinter::printDenseElementsAttr(DenseElementsAttr attr) {
@ -729,17 +747,20 @@ void ModulePrinter::printDenseElementsAttr(DenseElementsAttr attr) {
auto shape = type.getShape();
auto rank = type.getRank();
SmallVector<Attribute, 16> elements;
attr.getValues(elements);
// The function used to print elements of this attribute.
auto printEltFn = type.getElementType().isa<IntegerType>()
? printDenseIntElement
: printDenseFloatElement;
// Special case for 0-d and splat tensors.
if (attr.isSplat()) {
printAttribute(elements[0]);
printEltFn(attr, os, 0);
return;
}
// Special case for degenerate tensors.
if (elements.empty()) {
auto numElements = type.getNumElements();
if (numElements == 0) {
for (int i = 0; i < rank; ++i)
os << '[';
for (int i = 0; i < rank; ++i)
@ -770,13 +791,13 @@ void ModulePrinter::printDenseElementsAttr(DenseElementsAttr attr) {
}
};
for (unsigned idx = 0, e = elements.size(); idx != e; ++idx) {
for (unsigned idx = 0, e = numElements; idx != e; ++idx) {
if (idx != 0)
os << ", ";
while (openBrackets++ < rank)
os << '[';
openBrackets = rank;
printAttribute(elements[idx]);
printEltFn(attr, os, idx);
bumpCounter();
}
while (openBrackets-- > 0)
@ -1154,7 +1175,7 @@ void ModulePrinter::printOptionalAttrDict(ArrayRef<NamedAttribute> attrs,
return;
os << " = ";
printAttributeAndType(attr.second);
printAttribute(attr.second);
});
os << '}';
}
@ -1187,9 +1208,6 @@ public:
void printAttribute(Attribute attr) override {
ModulePrinter::printAttribute(attr);
}
void printAttributeAndType(Attribute attr) override {
ModulePrinter::printAttributeAndType(attr);
}
void printOperand(Value *value) override { printValueID(value); }
void printOptionalAttrDict(ArrayRef<NamedAttribute> attrs,
@ -1652,7 +1670,7 @@ void ModulePrinter::print(Function *fn) { FunctionPrinter(fn, *this).print(); }
void Attribute::print(raw_ostream &os) const {
ModuleState state(/*no context is known*/ nullptr);
ModulePrinter(os, state).printAttributeAndType(*this);
ModulePrinter(os, state).printAttribute(*this);
}
void Attribute::dump() const {

View File

@ -709,19 +709,7 @@ static ParseResult parseUndefOp(OpAsmParser *parser, OperationState *result) {
//===----------------------------------------------------------------------===//
static void printConstantOp(OpAsmPrinter *p, ConstantOp &op) {
*p << op.getOperationName() << '(' << op.value();
// Print attribute types other than i64 and f64 because attribute parsing will
// assume those in absence of explicit attribute type.
if (auto intAttr = op.value().dyn_cast<IntegerAttr>()) {
auto type = intAttr.getType();
if (!type.isInteger(64))
*p << " : " << intAttr.getType();
} else if (auto floatAttr = op.value().dyn_cast<FloatAttr>()) {
auto type = floatAttr.getType();
if (!type.isF64())
*p << " : " << type;
}
*p << ')';
*p << op.getOperationName() << '(' << op.value() << ')';
p->printOptionalAttrDict(op.getAttrs(), {"value"});
*p << " : " << op.res()->getType();
}

View File

@ -520,12 +520,12 @@ static void print(spirv::VariableOp varOp, OpAsmPrinter *printer) {
}
// Print optional descriptor binding
auto set = varOp.getAttr(kDescriptorSetAttrName);
auto binding = varOp.getAttr(kBindingAttrName);
auto set = varOp.getAttrOfType<IntegerAttr>(kDescriptorSetAttrName);
auto binding = varOp.getAttrOfType<IntegerAttr>(kBindingAttrName);
if (set && binding) {
elidedAttrs.push_back(kDescriptorSetAttrName);
elidedAttrs.push_back(kBindingAttrName);
*printer << " bind(" << set << ", " << binding << ")";
*printer << " bind(" << set.getInt() << ", " << binding.getInt() << ")";
}
printer->printOptionalAttrDict(op->getAttrs(), elidedAttrs);

View File

@ -1036,7 +1036,7 @@ static void print(OpAsmPrinter *p, ConstantOp &op) {
if (op.getAttrs().size() > 1)
*p << ' ';
p->printAttributeAndType(op.getValue());
p->printAttribute(op.getValue());
// If the value is a function, print a trailing type.
if (op.getValue().isa<FunctionAttr>()) {

View File

@ -41,16 +41,16 @@ func @mixed_alloc(%arg0: index, %arg1: index) -> memref<?x42x?xf32> {
// CHECK-NEXT: %5 = llvm.call @malloc(%4) : (!llvm.i64) -> !llvm<"i8*">
// CHECK-NEXT: %6 = llvm.bitcast %5 : !llvm<"i8*"> to !llvm<"float*">
// CHECK-NEXT: %7 = llvm.undef : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %8 = llvm.insertvalue %6, %7[0] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %9 = llvm.insertvalue %arg0, %8[1] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %10 = llvm.insertvalue %arg1, %9[2] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %8 = llvm.insertvalue %6, %7[0 : index] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %9 = llvm.insertvalue %arg0, %8[1 : index] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %10 = llvm.insertvalue %arg1, %9[2 : index] : !llvm<"{ float*, i64, i64 }">
%0 = alloc(%arg0, %arg1) : memref<?x42x?xf32>
return %0 : memref<?x42x?xf32>
}
// CHECK-LABEL: func @mixed_dealloc(%arg0: !llvm<"{ float*, i64, i64 }">) {
func @mixed_dealloc(%arg0: memref<?x42x?xf32>) {
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[0] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[0 : index] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %1 = llvm.bitcast %0 : !llvm<"float*"> to !llvm<"i8*">
// CHECK-NEXT: llvm.call @free(%1) : (!llvm<"i8*">) -> ()
dealloc %arg0 : memref<?x42x?xf32>
@ -66,16 +66,16 @@ func @dynamic_alloc(%arg0: index, %arg1: index) -> memref<?x?xf32> {
// CHECK-NEXT: %3 = llvm.call @malloc(%2) : (!llvm.i64) -> !llvm<"i8*">
// CHECK-NEXT: %4 = llvm.bitcast %3 : !llvm<"i8*"> to !llvm<"float*">
// CHECK-NEXT: %5 = llvm.undef : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %6 = llvm.insertvalue %4, %5[0] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %7 = llvm.insertvalue %arg0, %6[1] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %8 = llvm.insertvalue %arg1, %7[2] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %6 = llvm.insertvalue %4, %5[0 : index] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %7 = llvm.insertvalue %arg0, %6[1 : index] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %8 = llvm.insertvalue %arg1, %7[2 : index] : !llvm<"{ float*, i64, i64 }">
%0 = alloc(%arg0, %arg1) : memref<?x?xf32>
return %0 : memref<?x?xf32>
}
// CHECK-LABEL: func @dynamic_dealloc(%arg0: !llvm<"{ float*, i64, i64 }">) {
func @dynamic_dealloc(%arg0: memref<?x?xf32>) {
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[0] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[0 : index] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %1 = llvm.bitcast %0 : !llvm<"float*"> to !llvm<"i8*">
// CHECK-NEXT: llvm.call @free(%1) : (!llvm<"i8*">) -> ()
dealloc %arg0 : memref<?x?xf32>
@ -125,10 +125,10 @@ func @static_load(%static : memref<10x42xf32>, %i : index, %j : index) {
// CHECK-LABEL: func @mixed_load
func @mixed_load(%mixed : memref<42x?xf32>, %i : index, %j : index) {
// CHECK-NEXT: %0 = llvm.constant(42 : index) : !llvm.i64
// CHECK-NEXT: %1 = llvm.extractvalue %arg0[1] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %1 = llvm.extractvalue %arg0[1 : index] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %2 = llvm.mul %arg1, %1 : !llvm.i64
// CHECK-NEXT: %3 = llvm.add %2, %arg2 : !llvm.i64
// CHECK-NEXT: %4 = llvm.extractvalue %arg0[0] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %4 = llvm.extractvalue %arg0[0 : index] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %5 = llvm.getelementptr %4[%3] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
// CHECK-NEXT: %6 = llvm.load %5 : !llvm<"float*">
%0 = load %mixed[%i, %j] : memref<42x?xf32>
@ -137,11 +137,11 @@ func @mixed_load(%mixed : memref<42x?xf32>, %i : index, %j : index) {
// CHECK-LABEL: func @dynamic_load
func @dynamic_load(%dynamic : memref<?x?xf32>, %i : index, %j : index) {
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[1] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %1 = llvm.extractvalue %arg0[2] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[1 : index] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %1 = llvm.extractvalue %arg0[2 : index] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %2 = llvm.mul %arg1, %1 : !llvm.i64
// CHECK-NEXT: %3 = llvm.add %2, %arg2 : !llvm.i64
// CHECK-NEXT: %4 = llvm.extractvalue %arg0[0] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %4 = llvm.extractvalue %arg0[0 : index] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %5 = llvm.getelementptr %4[%3] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
// CHECK-NEXT: %6 = llvm.load %5 : !llvm<"float*">
%0 = load %dynamic[%i, %j] : memref<?x?xf32>
@ -169,11 +169,11 @@ func @static_store(%static : memref<10x42xf32>, %i : index, %j : index, %val : f
// CHECK-LABEL: func @dynamic_store
func @dynamic_store(%dynamic : memref<?x?xf32>, %i : index, %j : index, %val : f32) {
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[1] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %1 = llvm.extractvalue %arg0[2] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[1 : index] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %1 = llvm.extractvalue %arg0[2 : index] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %2 = llvm.mul %arg1, %1 : !llvm.i64
// CHECK-NEXT: %3 = llvm.add %2, %arg2 : !llvm.i64
// CHECK-NEXT: %4 = llvm.extractvalue %arg0[0] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %4 = llvm.extractvalue %arg0[0 : index] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %5 = llvm.getelementptr %4[%3] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
// CHECK-NEXT: llvm.store %arg3, %5 : !llvm<"float*">
store %val, %dynamic[%i, %j] : memref<?x?xf32>
@ -183,10 +183,10 @@ func @dynamic_store(%dynamic : memref<?x?xf32>, %i : index, %j : index, %val : f
// CHECK-LABEL: func @mixed_store
func @mixed_store(%mixed : memref<42x?xf32>, %i : index, %j : index, %val : f32) {
// CHECK-NEXT: %0 = llvm.constant(42 : index) : !llvm.i64
// CHECK-NEXT: %1 = llvm.extractvalue %arg0[1] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %1 = llvm.extractvalue %arg0[1 : index] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %2 = llvm.mul %arg1, %1 : !llvm.i64
// CHECK-NEXT: %3 = llvm.add %2, %arg2 : !llvm.i64
// CHECK-NEXT: %4 = llvm.extractvalue %arg0[0] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %4 = llvm.extractvalue %arg0[0 : index] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %5 = llvm.getelementptr %4[%3] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
// CHECK-NEXT: llvm.store %arg3, %5 : !llvm<"float*">
store %val, %mixed[%i, %j] : memref<42x?xf32>
@ -196,11 +196,11 @@ func @mixed_store(%mixed : memref<42x?xf32>, %i : index, %j : index, %val : f32)
// CHECK-LABEL: func @memref_cast_static_to_dynamic
func @memref_cast_static_to_dynamic(%static : memref<10x42xf32>) {
// CHECK-NEXT: %0 = llvm.undef : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %1 = llvm.insertvalue %arg0, %0[0] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %1 = llvm.insertvalue %arg0, %0[0 : index] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %2 = llvm.constant(10 : index) : !llvm.i64
// CHECK-NEXT: %3 = llvm.insertvalue %2, %1[1] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %3 = llvm.insertvalue %2, %1[1 : index] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %4 = llvm.constant(42 : index) : !llvm.i64
// CHECK-NEXT: %5 = llvm.insertvalue %4, %3[2] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %5 = llvm.insertvalue %4, %3[2 : index] : !llvm<"{ float*, i64, i64 }">
%0 = memref_cast %static : memref<10x42xf32> to memref<?x?xf32>
return
}
@ -208,58 +208,58 @@ func @memref_cast_static_to_dynamic(%static : memref<10x42xf32>) {
// CHECK-LABEL: func @memref_cast_static_to_mixed
func @memref_cast_static_to_mixed(%static : memref<10x42xf32>) {
// CHECK-NEXT: %0 = llvm.undef : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %1 = llvm.insertvalue %arg0, %0[0] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %1 = llvm.insertvalue %arg0, %0[0 : index] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %2 = llvm.constant(10 : index) : !llvm.i64
// CHECK-NEXT: %3 = llvm.insertvalue %2, %1[1] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %3 = llvm.insertvalue %2, %1[1 : index] : !llvm<"{ float*, i64 }">
%0 = memref_cast %static : memref<10x42xf32> to memref<?x42xf32>
return
}
// CHECK-LABEL: func @memref_cast_dynamic_to_static
func @memref_cast_dynamic_to_static(%dynamic : memref<?x?xf32>) {
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[0] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[0 : index] : !llvm<"{ float*, i64, i64 }">
%0 = memref_cast %dynamic : memref<?x?xf32> to memref<10x12xf32>
return
}
// CHECK-LABEL: func @memref_cast_dynamic_to_mixed
func @memref_cast_dynamic_to_mixed(%dynamic : memref<?x?xf32>) {
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[0] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[0 : index] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %1 = llvm.undef : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %2 = llvm.insertvalue %0, %1[0] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %3 = llvm.extractvalue %arg0[1] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %4 = llvm.insertvalue %3, %2[1] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %2 = llvm.insertvalue %0, %1[0 : index] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %3 = llvm.extractvalue %arg0[1 : index] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %4 = llvm.insertvalue %3, %2[1 : index] : !llvm<"{ float*, i64 }">
%0 = memref_cast %dynamic : memref<?x?xf32> to memref<?x12xf32>
return
}
// CHECK-LABEL: func @memref_cast_mixed_to_dynamic
func @memref_cast_mixed_to_dynamic(%mixed : memref<42x?xf32>) {
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[0] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[0 : index] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %1 = llvm.undef : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %2 = llvm.insertvalue %0, %1[0] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %2 = llvm.insertvalue %0, %1[0 : index] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %3 = llvm.constant(42 : index) : !llvm.i64
// CHECK-NEXT: %4 = llvm.insertvalue %3, %2[1] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %5 = llvm.extractvalue %arg0[1] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %6 = llvm.insertvalue %5, %4[2] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %4 = llvm.insertvalue %3, %2[1 : index] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %5 = llvm.extractvalue %arg0[1 : index] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %6 = llvm.insertvalue %5, %4[2 : index] : !llvm<"{ float*, i64, i64 }">
%0 = memref_cast %mixed : memref<42x?xf32> to memref<?x?xf32>
return
}
// CHECK-LABEL: func @memref_cast_mixed_to_static
func @memref_cast_mixed_to_static(%mixed : memref<42x?xf32>) {
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[0] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[0 : index] : !llvm<"{ float*, i64 }">
%0 = memref_cast %mixed : memref<42x?xf32> to memref<42x1xf32>
return
}
// CHECK-LABEL: func @memref_cast_mixed_to_mixed
func @memref_cast_mixed_to_mixed(%mixed : memref<42x?xf32>) {
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[0] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[0 : index] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %1 = llvm.undef : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %2 = llvm.insertvalue %0, %1[0] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %2 = llvm.insertvalue %0, %1[0 : index] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %3 = llvm.constant(42 : index) : !llvm.i64
// CHECK-NEXT: %4 = llvm.insertvalue %3, %2[1] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %4 = llvm.insertvalue %3, %2[1 : index] : !llvm<"{ float*, i64 }">
%0 = memref_cast %mixed : memref<42x?xf32> to memref<?x1xf32>
return
}
@ -268,13 +268,13 @@ func @memref_cast_mixed_to_mixed(%mixed : memref<42x?xf32>) {
func @mixed_memref_dim(%mixed : memref<42x?x?x13x?xf32>) {
// CHECK-NEXT: %0 = llvm.constant(42 : index) : !llvm.i64
%0 = dim %mixed, 0 : memref<42x?x?x13x?xf32>
// CHECK-NEXT: %1 = llvm.extractvalue %arg0[1] : !llvm<"{ float*, i64, i64, i64 }">
// CHECK-NEXT: %1 = llvm.extractvalue %arg0[1 : index] : !llvm<"{ float*, i64, i64, i64 }">
%1 = dim %mixed, 1 : memref<42x?x?x13x?xf32>
// CHECK-NEXT: %2 = llvm.extractvalue %arg0[2] : !llvm<"{ float*, i64, i64, i64 }">
// CHECK-NEXT: %2 = llvm.extractvalue %arg0[2 : index] : !llvm<"{ float*, i64, i64, i64 }">
%2 = dim %mixed, 2 : memref<42x?x?x13x?xf32>
// CHECK-NEXT: %3 = llvm.constant(13 : index) : !llvm.i64
%3 = dim %mixed, 3 : memref<42x?x?x13x?xf32>
// CHECK-NEXT: %4 = llvm.extractvalue %arg0[3] : !llvm<"{ float*, i64, i64, i64 }">
// CHECK-NEXT: %4 = llvm.extractvalue %arg0[3 : index] : !llvm<"{ float*, i64, i64, i64 }">
%4 = dim %mixed, 4 : memref<42x?x?x13x?xf32>
return
}

View File

@ -330,9 +330,9 @@ func @multireturn() -> (i64, f32, memref<42x?x10x?xf32>) {
%1 = call @get_f32() : () -> (f32)
%2 = call @get_memref() : () -> (memref<42x?x10x?xf32>)
// CHECK-NEXT: {{.*}} = llvm.undef : !llvm<"{ i64, float, { float*, i64, i64 } }">
// CHECK-NEXT: {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[0] : !llvm<"{ i64, float, { float*, i64, i64 } }">
// CHECK-NEXT: {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[1] : !llvm<"{ i64, float, { float*, i64, i64 } }">
// CHECK-NEXT: {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[2] : !llvm<"{ i64, float, { float*, i64, i64 } }">
// CHECK-NEXT: {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[0 : index] : !llvm<"{ i64, float, { float*, i64, i64 } }">
// CHECK-NEXT: {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[1 : index] : !llvm<"{ i64, float, { float*, i64, i64 } }">
// CHECK-NEXT: {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[2 : index] : !llvm<"{ i64, float, { float*, i64, i64 } }">
// CHECK-NEXT: llvm.return {{.*}} : !llvm<"{ i64, float, { float*, i64, i64 } }">
return %0, %1, %2 : i64, f32, memref<42x?x10x?xf32>
}
@ -342,9 +342,9 @@ func @multireturn() -> (i64, f32, memref<42x?x10x?xf32>) {
func @multireturn_caller() {
^bb0:
// CHECK-NEXT: {{.*}} = llvm.call @multireturn() : () -> !llvm<"{ i64, float, { float*, i64, i64 } }">
// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[0] : !llvm<"{ i64, float, { float*, i64, i64 } }">
// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[1] : !llvm<"{ i64, float, { float*, i64, i64 } }">
// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[2] : !llvm<"{ i64, float, { float*, i64, i64 } }">
// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[0 : index] : !llvm<"{ i64, float, { float*, i64, i64 } }">
// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[1 : index] : !llvm<"{ i64, float, { float*, i64, i64 } }">
// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[2 : index] : !llvm<"{ i64, float, { float*, i64, i64 } }">
%0:3 = call @multireturn() : () -> (i64, f32, memref<42x?x10x?xf32>)
%1 = constant 42 : i64
// CHECK: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64

View File

@ -72,7 +72,7 @@ func @ops(%arg0 : !llvm.i32, %arg1 : !llvm.float) {
^bb2:
// CHECK: %22 = llvm.undef : !llvm<"{ i32, double, i32 }">
// CHECK-NEXT: %23 = llvm.constant(42) : !llvm.i47
// CHECK-NEXT: %23 = llvm.constant(42 : i64) : !llvm.i47
%22 = llvm.undef : !llvm<"{ i32, double, i32 }">
%23 = llvm.constant(42) : !llvm.i47
@ -94,15 +94,15 @@ func @ops(%arg0 : !llvm.i32, %arg1 : !llvm.float) {
// An larger self-contained function.
// CHECK-LABEL:func @foo(%arg0: !llvm.i32) -> !llvm<"{ i32, double, i32 }"> {
func @foo(%arg0: !llvm.i32) -> !llvm<"{ i32, double, i32 }"> {
// CHECK-NEXT: %0 = llvm.constant(3) : !llvm.i32
// CHECK-NEXT: %1 = llvm.constant(3) : !llvm.i32
// CHECK-NEXT: %2 = llvm.constant(4.200000e+01) : !llvm.double
// CHECK-NEXT: %3 = llvm.constant(4.200000e+01) : !llvm.double
// CHECK-NEXT: %0 = llvm.constant(3 : i64) : !llvm.i32
// CHECK-NEXT: %1 = llvm.constant(3 : i64) : !llvm.i32
// CHECK-NEXT: %2 = llvm.constant(4.200000e+01 : f64) : !llvm.double
// CHECK-NEXT: %3 = llvm.constant(4.200000e+01 : f64) : !llvm.double
// CHECK-NEXT: %4 = llvm.add %0, %1 : !llvm.i32
// CHECK-NEXT: %5 = llvm.mul %4, %1 : !llvm.i32
// CHECK-NEXT: %6 = llvm.fadd %2, %3 : !llvm.double
// CHECK-NEXT: %7 = llvm.fsub %3, %6 : !llvm.double
// CHECK-NEXT: %8 = llvm.constant(1) : !llvm.i1
// CHECK-NEXT: %8 = llvm.constant(1 : i64) : !llvm.i1
// CHECK-NEXT: llvm.cond_br %8, ^bb1(%4 : !llvm.i32), ^bb2(%4 : !llvm.i32)
%0 = llvm.constant(3) : !llvm.i32
%1 = llvm.constant(3) : !llvm.i32