From 1f5f006d9d53e785296d1a8fbb0e90904a5eaf60 Mon Sep 17 00:00:00 2001 From: River Riddle Date: Thu, 10 Dec 2020 11:47:17 -0800 Subject: [PATCH] [mlir][StandardOps] Verify that the result of an integer constant is signless This was missed when supported for unsigned/signed integer types was first added, and results in crashes if a user tries to create/print a constant with the incorrect integer type. Fixes PR#46222 Differential Revision: https://reviews.llvm.org/D92981 --- mlir/lib/Dialect/StandardOps/IR/Ops.cpp | 16 ++++++++++++---- mlir/test/Dialect/Standard/invalid.mlir | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/mlir/lib/Dialect/StandardOps/IR/Ops.cpp b/mlir/lib/Dialect/StandardOps/IR/Ops.cpp index 34c3da9..0efba0d 100644 --- a/mlir/lib/Dialect/StandardOps/IR/Ops.cpp +++ b/mlir/lib/Dialect/StandardOps/IR/Ops.cpp @@ -1136,7 +1136,7 @@ static LogicalResult verify(ConstantOp &op) { if (!value) return op.emitOpError("requires a 'value' attribute"); - auto type = op.getType(); + Type type = op.getType(); if (!value.getType().isa() && type != value.getType()) return op.emitOpError() << "requires attribute's type (" << value.getType() << ") to match op's return type (" << type << ")"; @@ -1145,10 +1145,14 @@ static LogicalResult verify(ConstantOp &op) { return success(); if (auto intAttr = value.dyn_cast()) { + IntegerType intType = type.cast(); + if (!intType.isSignless()) + return op.emitOpError("requires integer result types to be signless"); + // If the type has a known bitwidth we verify that the value can be // represented with the given bitwidth. - auto bitwidth = type.cast().getWidth(); - auto intVal = intAttr.getValue(); + unsigned bitwidth = intType.getWidth(); + APInt intVal = intAttr.getValue(); if (!intVal.isSignedIntN(bitwidth) && !intVal.isIntN(bitwidth)) return op.emitOpError("requires 'value' to be an integer within the " "range of the integer result type"); @@ -1228,9 +1232,13 @@ bool ConstantOp::isBuildableWith(Attribute value, Type type) { // SymbolRefAttr can only be used with a function type. if (value.isa()) return type.isa(); - // Otherwise, the attribute must have the same type as 'type'. + // The attribute must have the same type as 'type'. if (value.getType() != type) return false; + // If the type is an integer type, it must be signless. + if (IntegerType integerTy = type.dyn_cast()) + if (!integerTy.isSignless()) + return false; // Finally, check that the attribute kind is handled. return value.isa(); } diff --git a/mlir/test/Dialect/Standard/invalid.mlir b/mlir/test/Dialect/Standard/invalid.mlir index 04ecdc6..48d2ae2 100644 --- a/mlir/test/Dialect/Standard/invalid.mlir +++ b/mlir/test/Dialect/Standard/invalid.mlir @@ -298,3 +298,18 @@ func @mismatched_types() { return } +// ----- + +func @non_signless_constant() { + // expected-error @+1 {{requires integer result types to be signless}} + %0 = constant 0 : ui32 + return +} + +// ----- + +func @non_signless_constant() { + // expected-error @+1 {{requires integer result types to be signless}} + %0 = constant 0 : si32 + return +} -- 2.7.4